-
2022-03-04 13:14:12
vue如何监听数组变化
先看这一段代码
// 拿到数组的原型 const oldArrayProperty = Array.prototype // 创建一个新的对象,原型指向oldArrayProperty,这么做为的是不污染全局的Array原型 // Object.create 和 new Objcet() 的区别在知识库 前端知识点中有 const arrProto = Object.create(oldArrayProperty) // 给arrProto增加方法,例如push arrProto.push = function() { updateView() //这里触发更新视图 Array.prototype.push.call(this, ..arguments) // 这里才是真正执行push方法 }
然后修改1-4中的代码
/* 模拟更新视图 -- 这个不变 */ function updateView() { console.log('视图更新') }
const oldArrayPrototype = Array.prototyoe const arrProto = Object.create(oldArrayPrototype) // 这里没写全所有的数组方法 !!['push', 'pop', 'shift', 'unshift', 'splice', 'slice'].forEach(methodName => { arrProto[methodName] = function() { updateView() // 更新视图 oldArrayPrototype[methodName].call(this, ...arguments) } })
/* 监听对象属性 */ function observer(target) { // 只监听对象和数组 if (typeof target !== 'object' || target == null) { return target } // 对数组进行特殊处理 // 这样,操作target是数组的时候,就是使用的是我们自定义的方法了 if(Array.isArray(target)) { target.__proto__ = arrProto } // 重新定义各个属性 for (let key in target) { defineReactive(target, key, target[key]) } }
/* 对属性重新定义,并且监听 -- 这个也不变 */ function defineReactive(target, key, val) { // 深度监听 observer(val) // 因为val不一定是值,也可能是一个对象或数组 Object.defineProperty(target, key, { get() { return val }, set(newVal) { if (newVal !== val) { // 深度监听 新增加的如果是对象和数组也要加入监听 observer(newVal) // 设置新值 val = newVal } // 更新视图 updateView() } }) }
更多相关内容 -
Vue监听数组变化源码解析
2020-08-31 04:14:43主要为大家详细解析了Vue监听数组变化的源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
vue中是怎样监听数组变化的
2021-01-18 18:36:01但实际用vue开发时,对于响应式数组,使用push、splice、pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢? 通过vue源码可以看出,vue重写了数组的push、splice、pop等方法。 // src/core/... -
详解Vue 如何监听Array的变化
2020-10-16 20:57:52主要介绍了详解Vue 如何监听Array的变化,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
Vue如何监听数组的变化?
2021-02-21 09:43:27文章目录Vue如何监听数组的变化?Vue为什么不能检测数组变动$set为啥能检测数组变动 Vue如何监听数组的变化? 理解: 使用函数劫持的方式,重写了数组的方法 Vue 将 data 中的数组,进行了原型链重写。指向了自己...故心故心故心故心小故冲啊
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
Vue如何监听数组的变化?
理解:
使用函数劫持的方式,重写了数组的方法 Vue 将 data 中的数组,进行了原型链重写。指向了自己定义的数组原型方法,这样当调用数组 api 时,可以通知依赖更新.如果数组中包含着引用类型。会对数组中的引用类型再次进行监控重写了数组中的原型的方法
1.获取数组中的原型方法,因为拦截后还需要这些原生的方法帮助我们实现数组的变化
2.对这些原型的方法使用object.deinePropetry进行拦截操作(def方法)
3.把拦截的数组的原型指向改造后的原型原理:
Vue为什么不能检测数组变动
性能问题而没有采用这种方式监听数组。
性能代价和获得的用户收益不成正比
通过源码我们可以知道,Vue 没有对数组每个键设置响应式的过程,而是直接对值进行递归设置响应式。
$set为啥能检测数组变动
这就是vue重写数组方法的原因,利用数组这些方法触发使得每一项的value都是响应式的
-
Vue如何监听数组的变化的
2022-03-28 16:36:13修改了数组对象的原型,在原本的原型链上插入了一个新的原型对象,在新的原型对象上重写了7个变异方法(push/pop/unshift/shift/splice/sort/reverse) ... // 监听到调用了数组的push方法,执行视图渲染的代码 con.修改了数组对象的原型,在原本的原型链上插入了一个新的原型对象,在新的原型对象上重写了7个变异方法(push/pop/unshift/shift/splice/sort/reverse)
var arrayProto = Array.prototype var newArrayProto = Object.create(arrayProto) newArrayProto.push = function (...rest) { // 监听到调用了数组的push方法,执行视图渲染的代码 console.log('监听到调用了数组的push方法,执行视图渲染的代码,添加之前的逻辑。。。。') // 为了保留原来的数组push方法的逻辑 arrayProto.push.call(this, ...rest) console.log('数组push方法添加之后的逻辑,。。。。。') } // 在递归遍历数据的时候,只要找到数组数据,就将其原型指向为newArrayProto // arr.__proto__ = newArrayProto var arr = [1,2,3] arr.__proto__ = newArrayProto
为什么没有像对象一样用Object.defineProperty监听数组中所有的元素变化呢?
因为数组中的元素有可能有很多个,如果循环遍历,开销太大!不能这样。。。Vue给我们提供了支持驱动视图的API(this.$set,
Vue.set),还有重写了7个变异方法 -
vue如何监听数组变化?
2020-05-09 23:54:22Vue.js观察数组变化主要通过以下7个方法(push、pop、shift、unshift、splice、sort、reverse) 怎么实现? 通过对data数据中数组的这7个方法进行重新包装(注意只是data数据中的数组) 为什么不直接对Array....Vue.js观察数组变化主要通过以下7个方法(push、pop、shift、unshift、splice、sort、reverse)
怎么实现?
通过对data数据中数组的这7个方法进行重新包装(注意只是data数据中的数组)
为什么不直接对Array.prototype的原型方法进行重新包装?
因为不应该过多地去影响全局
案例:
const patchArray = (function () { const methodsToPatch = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort' ]; //设置对象属性的工具方法 function def (obj, key, val) { Object.defineProperty(obj, key, { value: val, enumerable: true, writable: true, configurable: true }); } const arrayProto = Array.prototype, //缓存Array的原型 arrayMethods = Object.create(arrayProto); //继承Array的原型 methodsToPatch.forEach(function (method, index) { def(arrayMethods, method, function (...args) { //首先调用Array原型的方法 const res = arrayProto[method].apply(this, args); //data中每个数组都有一个__ob__的私有属性指向创建的Observer实例(有兴趣看看源码中的observe方法,这里不详述) const ob = this.__ob__; let inserted = null; //记录插入的值 switch(method) { case 'push': case 'unshift': inserted = args; break; case 'splice': inserted = args.slice(2); break; } if (inserted) { //如果是调用了push、unshift、splice,则尝试对新插入的值进行响应式绑定,因为插入的值有可能是对象(Object)或者数组(Array) ob && ob.observeArray(inserted); } console.log('数组发生改变了'); //向所有依赖发送通知,告诉它们数组的值发生变化了 ob && ob.dep.notify(); return res; }); }); return function (target) { //看看浏览器支不支持__proto__这个属性,通过改变__proto__的值,可以设置对象的原型 if ('__proto__' in {}) { //将数组的原型指向arrayMethods,这样当数组调用上述的7个方法时,其实是调用arrayMethods中的方法而不是调用Array.prototype中的方法 target.__proto__ = arrayMethods; } else { //如果浏览器不支持__proto__,则设置数组对应的属性,这样当数组调用上述的7个方法时,其实是调用数组对应属性指向的方法 for (let i = 0, l = methodsToPatch.length; i < l; i++) { let key = methodsToPatch[i]; def(target, key, arrayMethods[key]); } } } })(); //测试 let arr = [1, 2, 3]; patchArray(arr); arr.push(4);
-
解决vue无法侦听数组及对象属性的变化问题
2021-01-19 07:48:55一、数组 1、可以监听到的情况 如push、splice、=赋值(array=[1,2,3]) 2、无法监听到的情况 使用下标修改某个元素(这种比较常见) array[index] = 1 object.a = 3 直接修改数组length array.length = 5 3、... -
vue原理:vue中是如何监听数组变化?
2021-05-05 14:00:04我们知道通过Object.defineProperty()劫持数组为...但实际用vue开发时,对于响应式数组,使用push、splice、pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢? 答案是 vue 重写了数组的push、s -
vue是如何监听数组变化的
2021-08-06 10:47:27vue的数据绑定用Object.defineProperty的getter和setter对一个对象属性的变化进行监听,并且通过依赖关系作出相应的视图更新。但由于js的限制,vue无法检测到以下数组的变动:...如何监听数组变化? vue中是如何监听数. -
vue3 使用watch监听数组问题
2021-09-15 10:49:18监听数组时,用splice这种改变数组是正常的,但是如果数组直接置空,则监听失效 const array = ref([1,2,3]); const changeArr = ()=>{ array.value = []; } watch(array.value,(now,old)=>{ console.log... -
vue中是如何监听数组变化(vue图解03)
2020-02-27 16:02:28起源:在 Vue 的数据绑定中会对一个对象属性的变化进行监听,并且通过依赖收集做出相应的视图更新等等。 问题:一个对象所有类型的属性变化都能被监听到吗? 之前用 Object.defineProperty通过对象的 getter/setter... -
vue怎么监听数组和对象的变化
2020-06-16 17:22:24但是数组和对象的变化很多小白可能不太会,接下来我就为大家展示怎么监听数组和对象 废话不多说。上代码 data() { return { arr: ["sss", "scsdr", 22], obj: { a: "bai", b: 2 } }; }, data中有一个数组... -
在vue中对数组值变化的监听与重新响应渲染操作
2020-10-15 03:03:22主要介绍了在vue中对数组值变化的监听与重新响应渲染操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
vue 2.x 监听数组变化
2021-10-30 21:01:31vue 2.x 子组件props 数组内容发生变化时,页面不刷新。 可以通过 watch 监听,注意需要在监听数据下添加 deep: true 字段。 props: { dataValue: { type: Array, default: function () { return []; } } } ... -
vue监听数组,新数据和旧数据一样问题解决
2021-11-09 12:55:23// 计算属性,解决直接监听数组新旧值一样的情况 tableData() { return JSON.parse(JSON.stringify(this.maStockList)) } }, watch: { tableData: { deep: true, handler(array, oldArray) { } } } 使用... -
vuex state中的数组变化监听实例
2020-12-13 04:14:46vuex的state用来放数据,我就把数组放在了vuex中,然后设置了修改的函数。最终store.js中的代码如下: import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { messArray:[] } const ... -
vue中是如何监听数组变化?
2019-08-22 11:26:21vue中是如何监听数组变化? 参考于Vue源码解析五——数据响应系统 参考文献: [1] 如何监听数组变化? -
Vue中对数组变化监听
2021-04-03 17:56:40我们在实际开发中,经常要对数组进行操作,最为常见的方法就是直接对数组中的某个元素进行赋值,比如下面这样的: <script> export default { data() { return { comments: [], isReply: [0, 0, 0, 0, 0]... -
Vue不能观察到数组length的变化
2020-11-30 17:43:57由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当你利用索引直接...为什么Vue不能观察到数组length的变化 如下代码,虽然看起来数组的length是10,但是for in的时候只能遍历出0, 1, 2,导致了只有前三个索引被 -
vue监听数组对象
2022-01-14 16:41:362、watch要写在computed后面,不然监听不到 3、要加deep:true const tag_list = ref([]); // 这是个数组对象 const tagList = computed(()=>{ JSON.parse(JSON.stringify(tag_list.value)) }) watch(tagList,... -
Vue 如何监听数组的变化
2021-04-21 19:16:45Vue 如何监听数组的变化 我们知道通过Object.defineProperty()劫持数组为其设置getter和setter后,调用的数组的push、splice、pop等方法改变数组元素时并不会触发数组的setter,这就会造成使用上述方法改变数组后,... -
Vue监听数组 watch监听
2020-10-05 15:48:53Vue中监听数组解析 1,简单监听一个参数,demo如下 data() { return { msg: "test---test", } }, watch: { msg(newVal, oldVal) { console.log(newVal) console.log(oldVal) }, }, created() { thi -
vue源码阅读解析(超详细、监听数组变化、Watch监听的实现、computed实现、nextTick原理)
2021-10-09 15:09:34监听数组变化4. Watch监听的实现5. computed实现6. nextTick原理7. Vue.extend原理 前言:使用 vue 也有一段时间了,前段时间看了看 vue 的源码,很多小伙伴看到vue几万行的源码都是望而止步了,当时看源码看得也很... -
Vue 监听对象数组某一项某个属性值的变化
2022-03-08 19:35:43示例: 监听tempArr数组的第0项的age值变化 监听formData对象的likes数组第1项吉他项的值的变化 export default { data(){ return { tempArr: [ { name: '小明', age: 18 }, { -
Vue监听数组长度变化
2019-02-20 15:36:32Vue监听数组长度变化: 最近APP项目需要监听数组长度的变化,界面上做出相应变化;百度了很多,未果,请教了同事,了解到一个方法,特来分享一下。 watch: { 'list.length': { handler(newValue, oldValue) { ... -
vue监听数组、对象变化
2020-03-27 22:20:381.vue单独监听一个数组或者一个对象变化 watch:{ 'payList' : { handler : function(newVal,oldVal){ console.log(newVal,'变化后的值',oldVal,‘变化前的值’) } } } 2.如果你想监听一个数组中多个对象是否...
收藏数
23,704
精华内容
9,481