VUE中的proxy和defineproperty有何区别?
Admin 2021-10-18 群英技术资讯 1077 次浏览
VUE中的proxy和defineproperty有何区别?proxy和defineproperty的区别有:Proxy可以劫持的数组的改变,defineProperty 需要变异、Proxy代理可以劫持对象的改变,defineProperty需要遍历、Proxy代理可以劫持对象属性的添加,defineProperty用this.$set来实现等等,下面我们详细的了解看看。
Proxy的出现,给vue响应式带来了极大的便利,比如可以直接劫持数组、对象的改变,可以直接添加对象属性,但是兼容性可能会有些问题
Proxy可以劫持的数组的改变,defineProperty 需要变异
defineProperty 中劫持数组变化的变异的方法
可以理解为在数组实例和原型之间,插入了一个新的原型的对象,这个原型方法实现了变异的方法,也就真正地拦截了数组原型上的方法
我们来看下vue2.x的源码
// vue 2.5.0 var arrayProto = Array.prototype; var arrayMethods = Object.create(arrayProto); // Array {} function def(obj, key, val, enumerable) { Object.defineProperty(obj, key, { value: val, enumerable: !!enumerable, writable: true, configurable: true }); } var methodsToPatch = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ]; /** * Intercept mutating methods and emit events */ methodsToPatch.forEach(function(method) { // cache original method var original = arrayProto[method]; // 比如 method是push,则结果为 // ƒ push() { [native code] } def(arrayMethods, method, function mutator() { var args = [], len = arguments.length; while (len--) args[len] = arguments[len]; var result = original.apply(this, args); var ob = this.__ob__; var inserted; switch (method) { case 'push': case 'unshift': inserted = args; break case 'splice': inserted = args.slice(2); break } if (inserted) { ob.observeArray(inserted); } // notify change ob.dep.notify(); return result }); }); /** * Observe a list of Array items. */ Observer.prototype.observeArray = function observeArray(items) { for (var i = 0, l = items.length; i < l; i++) { observe(items[i]); // 后续的逻辑 } };
Proxy可以直接劫持数组的改变
let proxy = new Proxy(fruit, { get: function (obj, prop) { return prop in obj ? obj[prop] : undefined }, set: function (obj, prop, newVal) { obj[prop] = newVal console.log("newVal", newVal) // 输出{ name: "lemon", num: 999 } return true; } }) proxy.push({ name: "lemon", num: 999 }) console.log(fruit)
Proxy代理可以劫持对象的改变,defineProperty需要遍历
defineProperty
let fruit = { "apple": 2, "pear": 22, "peach": 222 } Object.keys(fruit).forEach(function (key) { Object.defineProperty(fruit[i], key, { enumerable: true, configurable: true, get: function () { return val; }, set: function (newVal) { val = newVal; // 输出 newVal 888 console.log("newVal", newVal) } }) }) fruit.apple = 888
Proxy
let fruit = { "apple": 2, "pear": 22, "peach": 222 } let proxy = new Proxy(fruit, { get: function (obj, prop) { return prop in obj ? obj[prop] : undefined }, set: function (obj, prop, newVal) { obj[prop] = newVal console.log("newVal", newVal) // 输出 newVal 888 return true; } }) proxy.apple = 888
Proxy代理可以劫持对象属性的添加,defineProperty用this.$set来实现
defineProperty,如果属性不存在,则需要借助this.$set
<div id="app"> <span v-for="(value,name) in fruit">{{name}}:{{value}}个 </span> <button @click="add()">添加柠檬</button> </div> <script src="https://unpkg.com/vue"></script> <script> new Vue({ el: '#app', data() { return { fruit: { apple: 1, banana: 4, orange: 5 } } }, methods: { add() { this.fruit.lemon = 5; // 不会让视图发生变化 // this.$set(this.fruit,"lemon",5) // this.$set可以 } } }) </script>
Object.keys(fruit).forEach(function (key) { Object.defineProperty(fruit, key, { enumerable: true, configurable: true, get: function () { return val; }, set: function (newVal) { val = newVal; console.log("newVal", newVal) // 根本没有进去这里 } }) })
Proxy 直接可以添加属性
// vue 3 <div id="app"> <span v-for="(value,name) in fruit">{{name}}:{{value}}个 </span> <button @click="add()">添加柠檬</button> </div> <script src="https://unpkg.com/vue@next"></script> <script> Vue.createApp({ data() { return { fruit: { apple: 1, banana: 4, orange: 5 } } }, methods: { add() { this.fruit.lemon = 5; // 这样子是可以的 } } }).mount('#app') // vue 3 不再是使用el属性,而是使用mount </script>
let proxy = new Proxy(fruit, { get: function (obj, prop) { return prop in obj ? obj[prop] : undefined }, set: function (obj, prop, newVal) { obj[prop] = newVal console.log("newVal", newVal) // lemon, 888 return true; } }) proxy.lemon = 888
Proxy
其他属性
应用场景 promisify化
用Proxy写一个场景,请求都是通过回调,如果我们需要用promise包一层的话,则可以
// server.js // 假设这里都是回调 export const searchResultList = function (data, callback, errorCallback) { axios.post(url, data, callback, errorCallback) }
// promisify.js import * as server from './server.js' const promisify = (name,obj) => (option) => { return new Promise((resolve, reject) => { return obj[name]( option, resolve, reject, ) }) } const serverPromisify = new Proxy(server, { get (target,prop) { return promisify(prop, server) } }) export default serverPromisify
使用
// index.js import serverPromisify from './serverPromisify' serverPromisify.searchResultList(data).then(res=>{ })
如有不正确,望请指出
以上就是关于VUE中的proxy和defineproperty的区别介绍啦,上述示例具有一定的借鉴价值,有需要的朋友可以参考学习,希望对大家对大家学习proxy和defineproperty的使用有帮助,想要了解更多可以继续浏览群英网络其他相关的文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
Vue众所周知是一个轻量级的框架,源码仅仅为72.9KB,但是也有它自己的缺点,就是首屏加载会比较慢,这篇文章主要给大家介绍了关于Vue项目首屏性能优化组件的相关资料,需要的朋友可以参考下
这篇文章我们来了解jQuery删除兄弟节点的相关内容,下文分享的示例是如何删除指定元素后的兄弟节点的方法,文中有很详细的介绍,有需要的朋友可以参考,接下来就跟随小编来一起学习一下吧!
在react中的三大属性有state、props、refs,这篇文章给大家分享的是有关react的refs属性的内容,小编觉得挺实用的,因此分享给大家做个参考,接下来一起跟随小编看看吧。
这篇文章主要给大家分享vue实现点击切换图片效果的内容,切换图片的效果在很多网站上都是比较常见的,小编觉得比较实用,因此分享给大家做个参考,感兴趣的朋友可以看看,希望大家阅读完这篇文章能有所收获,下面我们一起来学习一下吧。
这篇文章给大家分享的是怎样用js实现生成验证码并校验的内容。小编觉得挺实用的,在很多注册登录页面都能使用到,因此分享给大家做个参考,感兴趣的朋友就继续往下看吧。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008