• Vue不能watch数组和对象变化解决方案


    Vue 能监听数组的情况

    Vue 监听数组和对象的变化(vue2.x)

    vue 实际上可以监听数组变化,比如:

    直接 = 赋值

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    data () {

      return {

        watchArr: [],

      };

    },

    watch: {

      watchArr (newVal) {

        console.log('监听:' + newVal);

      }

    },

    created () {

      setTimeout(() => {

        this.watchArr = [1, 2, 3];

      }, 1000);

    },

    再如使用 splice(0, 2, 3) 从数组下标 0 删除两个元素,并在下标 0 插入一个元素 3:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    data () {

      return {

        watchArr: [1, 2, 3],

      };

    },

    watch: {

      watchArr (newVal) {

        console.log('监听:' + newVal);

      }

    },

    created () {

      setTimeout(() => {

        this.watchArr.splice(0, 2, 3);

      }, 1000);

    },

    push、unshift、pop 数组也能够监听到

    Vue 无法监听数组变化

    但是,数组在下面两种情况无法监听:

    利用索引直接设置一个数组项时,例如:arr[indexOfItem] = newValue;

    修改数组的长度时,例如:arr.length = newLength;

    举例无法监听数组变化的情况

    利用索引直接修改数组值

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    data () {

      return {

        watchArr: [{

          name: 'krry',

        }],

      };

    },

    watch: {

      watchArr (newVal) {

        console.log('监听:' + newVal);

      }

    },

    created () {

      setTimeout(() => {

        this.watchArr[0].name = 'xiaoyue';

      }, 1000);

    },

    修改数组的长度

    长度大于原数组就将后续元素设置为 undefined

    长度小于原数组就将多余元素截掉

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    data () {

      return {

        watchArr: [{

          name: 'krry',

        }],

      };

    },

    watch: {

      watchArr (newVal) {

        console.log('监听:' + newVal);

      }

    },

    created () {

      setTimeout(() => {

        this.watchArr.length = 5;

      }, 1000);

    },

    上面的 watchArr 变成

    Vue 无法监听数组变化的解决方案

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    this.$set(arr, index, newVal);

    data () {

      return {

        watchArr: [{

          name: 'krry',

        }],

      };

    },

    watch: {

      watchArr (newVal) {

        console.log('监听:' + newVal);

      }

    },

    created () {

      setTimeout(() => {

        this.$set(this.watchArr, 0, {name: 'xiaoyue'});

      }, 1000);

    },

    使用数组 splice 方法可以监听,例子上面有

    使用临时变量直接赋值的方式,原理与直接赋值数组一样

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    data () {

      return {

        watchArr: [{

          name: 'krry',

        }],

      };

    },

    watch: {

      watchArr (newVal) {

        console.log('监听:' + newVal);

      }

    },

    created () {

      setTimeout(() => {

        let temp = [...this.watchArr];

        temp[0] = {

          name: 'xiaoyue',

        };

        this.watchArr = temp;

      }, 1000);

    },

    Vue 监听对象

    Vue 可以监听直接赋值的对象

    this.watchObj = {name: 'popo'};

    但是 Vue 不能 直接 监听对象属性的添加、修改、删除

    Vue 设置监听对象

    使用this.$set(object, key, value)、this.$delete(object, key)

    使用深度监听 deep: true,只能监听原有属性的变化,不能监听新增、删除的属性

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    mounted () {

      // 这里使用深度监听 blog 对象的属性变化,会触发 getCatalog 方法

      this.$watch('blog', this.getCatalog, {

        deep: true

        // immediate: true // 是否第一次触发

      });

    },

    watch: {

      obj: {

        // 这里深度监听变化,直接触发下面方法

        handler(curVal, oldVal) {

          // TODO

        },

        deep: true,

        immediate: true // 是否第一次触发

      }

    }

    使用this.$set(obj, key, val)来新增属性,this.$delete(object, key)来删除属性

    无法使用 this.$set 监听修改原有属性;可以使用深度监听 deep: true,可以直接以 obj.key 的方法来设置原有属性

    1

    2

    3

    4

    this.$set(this.watchObj, 'age', 124);

    this.$delete(this.watchObj, 'age')

    delete this.watchObj[‘name']//(Vue 无法监听 delete 关键字来删除对象属性)

    使用 Object.assign 方法,直接赋值的原理监听(最推荐的方法)

    1

    2

    3

    4

    this.watchObj = Object.assign({}, this.watchObj, {

      name: 'xiaoyue',

      age: 15,

    });

    直接 watch obj.key 监听某个值的变化

    1

    2

    3

    4

    5

    watch: {

      'obj.name'(curVal, oldVal) {

        // TODO

      }

    }

     

  • 相关阅读:
    努力前行,平凡的我们也能画出一条星光闪耀的轨迹——人大女王金融硕士项目
    在SpringBoot下,tomcat的运行模式:BIO、NIO、APR
    miui编译第三方卡米 对应的修改步骤位置
    一文了解DataStore(Preferences)
    OpenPose训练教程
    FPGA时序约束(七)文献时序约束实验测试
    【RealTek sdk-3.4.14b】RTL8197FH-VG+RTL8367+RTL8812F WiFi to LAN 和WiFi to WAN吞吐量
    STM32F407ZGT6|实现中断操作
    基于springboot小型车队管理系统毕业设计源码
    分布式系统的认证授权
  • 原文地址:https://blog.csdn.net/sinat_40572875/article/details/127828063