zoukankan      html  css  js  c++  java
  • 惊!VUE居然数据不能驱动视图?

    Vue 不能检测到对象属性的添加或删除

    1、划重点了:Vue 不能检测到对象属性的添加或删除

    官网——深入响应式原理(https://cn.vuejs.org/v2/guide...)中介绍到:受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

    上面的a是响应式的,所以a的改变后会自动渲染页面;
    但是b是在vm实例创建之后添加的属性,所以他不是响应式的,当我们改变b的值的时候,通过DevTool看到的数据并不会改变,除非我们在DevTool中刷新数据,而且页面也不会刷新。

    有三种解决方案:

    var vm = new Vue{
        el: "#app",
        data:{
            obj:{
                name: "aaa"            
            }
        }
    }
    

    1、方案一:利用Vue.set(object,key,value)

    Vue.set(vm.obj,"sex","man")

    2、方案二:利用this.$set(this.object,key,value)

    this.$set(this.obj,"sex","man")

    3、方案三:利用Object.assign({},this.obj)

    this.obj.sex = "man";
    this.obj = Object.assign({},this.obj)
    
    //或者下面方式
    this.obj = Object.assign({},this.obj,{"sex","man"})
    

    2、划重点了:删除vue实例的属性

    注意:Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上。

    对于上述Demo实例中通过this.$set添加的属性,通过以下方式删除即可:

    //以下这种方式可以删除属性,同时会触发数据响应式的更新
    this.$delete(this.mainData.test, "boolean");
    //而通过delete this.mainData.test.boolean这种方法不能响应式更新视图层。
    
    

    数组的问题

     changeArr() {
          // this.arr[0] = 112233;
          delete this.arr[0];
          console.log("这是修改之后的数组", this.arr);
          // $set(arr, 0, 112233);
        },
        changeObj() {
          // this.haha.content = "我是一个小和尚";
          delete this.haha.age;
          console.log("这是修改之后的对象", this.haha);
        }
    

    删除数组或者对象也是不能被VUE监听到的。那就搬出了一个方法set。

    利用vue中的set让修改内容的数组或者对象渲染到页面上。

    对于数组:
    this.$set(this.arr, 0, 112233);

    对于对象:
    this.$set(this.haha, "content", "我是一个小和尚");

    对于set这个方法的解释。
    this.$set(数组或者对象,修改的下标或者对象属性名,修改的值)

    原理

    首先,Vue.js是基于Object.defineProperty对对象实现“响应式化”,而对于数组,Vue.js提供的方法是重写push、pop、shift、unshift、splice、sort、reverse这七个数组方法。修改数组原型方法的代码可以参考observer/array.js以及observer/index.js。

    参考Vue官网。

    如果需要用数组下标修改数组并实现响应式数据变化,Vue.js提供了$set()及$remove()方法。

    扩展部分:
    当数组里的值是对象时,
    当对象里还有一个对象时,
    添加或者删除还会需要set吗~~~

    代码

     data() {
        return {
          arr: [{ key: "name" }, { 12: "hhah" }, 2, 3, 4, 5, 6],
          haha: {
            name: {
              name: "lili"
                 }
               }
        };
      },
      methods: {
        changeArr() {
          this.arr[0].key = 112233;
          console.log("这是修改之后的数组", this.arr);
        },
        changeObj() {
          this.haha.name.name = "我是一个小和尚";  
          console.log("这是修改之后的对象", this.haha); 
        }
      }
    

    注意到了吗。我没有用$set哦~

    这么看来,修改数组中的对象,和对象中的对象是不需要用set的!

  • 相关阅读:
    mysql中使用row_number()函数
    Android开发环境的搭建之(二)Android Studio的安装
    Android开发环境的搭建之(一)Java开发环境的安装
    进程与线程
    工作起始之博客搬家
    MapReduce的自制Writable分组输出及组内排序
    map端join和reduce端join的区别
    String.StartsWith 方法
    RPC和心跳机制
    MAPREDUCE中的序列化
  • 原文地址:https://www.cnblogs.com/liliuyu/p/13646101.html
Copyright © 2011-2022 走看看