精华内容
下载资源
问答
  • vue如何监听数组变化
    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监听数组变化的源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 但实际用vue开发时,对于响应式数组,使用push、splice、pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢? 通过vue源码可以看出,vue重写了数组的push、splice、pop等方法。 // src/core/...
  • 主要介绍了详解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:22
    Vue.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);
    
    展开全文
  • 一、数组 1、可以监听到的情况 如push、splice、=赋值(array=[1,2,3]) 2、无法监听到的情况 使用下标修改某个元素(这种比较常见) array[index] = 1 object.a = 3 直接修改数组length array.length = 5 3、...
  • 我们知道通过Object.defineProperty()劫持数组为...但实际用vue开发时,对于响应式数组,使用push、splice、pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢? 答案是 vue 重写了数组的push、s
  • vue的数据绑定用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 的数据绑定中会对一个对象属性的变化进行监听,并且通过依赖收集做出相应的视图更新等等。 问题:一个对象所有类型的属性变化都能被监听到吗? 之前用 Object.defineProperty通过对象的 getter/setter...
  • vue怎么监听数组和对象的变化

    千次阅读 2020-06-16 17:22:24
    但是数组和对象的变化很多小白可能不太会,接下来我就为大家展示怎么监听数组和对象 废话不多说。上代码 data() { return { arr: ["sss", "scsdr", 22], obj: { a: "bai", b: 2 } }; }, data中有一个数组...
  • 主要介绍了在vue中对数组值变化监听与重新响应渲染操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • vue 2.x 监听数组变化

    2021-10-30 21:01:31
    vue 2.x 子组件props 数组内容发生变化时,页面不刷新。 可以通过 watch 监听,注意需要在监听数据下添加 deep: true 字段。 props: { dataValue: { type: Array, default: function () { return []; } } } ...
  • // 计算属性,解决直接监听数组新旧值一样的情况 tableData() { return JSON.parse(JSON.stringify(this.maStockList)) } }, watch: { tableData: { deep: true, handler(array, oldArray) { } } } 使用...
  • vuex的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:21
    vue中是如何监听数组变化? 参考于Vue源码解析五——数据响应系统 参考文献: [1] 如何监听数组变化?
  • Vue中对数组变化监听

    千次阅读 2021-04-03 17:56:40
    我们在实际开发中,经常要对数组进行操作,最为常见的方法就是直接对数组中的某个元素进行赋值,比如下面这样的: <script> export default { data() { return { comments: [], isReply: [0, 0, 0, 0, 0]...
  • 由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当你利用索引直接...为什么Vue不能观察到数组length的变化 如下代码,虽然看起来数组的length是10,但是for in的时候只能遍历出0, 1, 2,导致了只有前三个索引被
  • vue监听数组对象

    2022-01-14 16:41:36
    2、watch要写在computed后面,不然监听不到 3、要加deep:true const tag_list = ref([]); // 这是个数组对象 const tagList = computed(()=>{ JSON.parse(JSON.stringify(tag_list.value)) }) watch(tagList,...
  • Vue 如何监听数组变化 我们知道通过Object.defineProperty()劫持数组为其设置getter和setter后,调用的数组的push、splice、pop等方法改变数组元素时并不会触发数组的setter,这就会造成使用上述方法改变数组后,...
  • Vue监听数组 watch监听

    万次阅读 多人点赞 2020-10-05 15:48:53
    Vue监听数组解析 1,简单监听一个参数,demo如下 data() { return { msg: "test---test", } }, watch: { msg(newVal, oldVal) { console.log(newVal) console.log(oldVal) }, }, created() { thi
  • 监听数组变化4. Watch监听的实现5. computed实现6. nextTick原理7. Vue.extend原理 前言:使用 vue 也有一段时间了,前段时间看了看 vue 的源码,很多小伙伴看到vue几万行的源码都是望而止步了,当时看源码看得也很...
  • 示例: 监听tempArr数组的第0项的age值变化 监听formData对象的likes数组第1项吉他项的值的变化 export default { data(){ return { tempArr: [ { name: '小明', age: 18 }, {
  • Vue监听数组长度变化

    万次阅读 2019-02-20 15:36:32
    Vue监听数组长度变化: 最近APP项目需要监听数组长度的变化,界面上做出相应变化;百度了很多,未果,请教了同事,了解到一个方法,特来分享一下。 watch: { 'list.length': { handler(newValue, oldValue) { ...
  • vue监听数组、对象变化

    千次阅读 2020-03-27 22:20:38
    1.vue单独监听一个数组或者一个对象变化 watch:{ 'payList' : { handler : function(newVal,oldVal){ console.log(newVal,'变化后的值',oldVal,‘变化前的值’) } } } 2.如果你想监听一个数组中多个对象是否...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,704
精华内容 9,481
关键字:

vue3监听数组变化