zoukankan      html  css  js  c++  java
  • Vue不能检测数组或对象变动问题的解决

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>vue</title>
      <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
      <style>
        li:hover {
          cursor: pointer;
        }
      </style>
    </head>
    <body>
      <div class="wrap">
        <ul>
          <li v-for="item,index in items" v-on:click="handle(index)">
            <span>{{item.name}}</span>
            <span>{{numbers[index]}}</span>
          </li>
        </ul>
      </div>
      <script>
        var vm = new Vue({
          el: ".wrap",
          data: {
            numbers: [],
            items: [
              {name: 'jjj'},
              {name: 'kkk'},
              {name: 'lll'},
            ]
          },
          methods: {
            handle: function (index) {
              // WHY: 更新数据,view层未渲染,但通过console这个数组可以发现数据确实更新了
               if (typeof(this.numbers[index]) === "undefined" ) {
              // 注:下面这么设置是可以的。例如 
              // var arr = [];
              // arr[3]=3;
              // console.log(arr)   //[empty × 3, 3]
                  this.numbers[index] = 1;  
                //  this.numbers.splice(index,0,1)   //用splice方法能同步显示,但得不到想要的效果
               } else {
                  this.numbers[index]++;
                //  this.numbers.splice(index,1,this.numbers[index]++)
               }
            //    console.log(this.numbers)
            }
          }
        });
       
      </script>
    </body>
    </html>

    想实现的效果是点击 li 看 vm.nymbers[index] 是否存在,不存在设置为1,存在的话加1。

    点击之后数字并没有在view层更新,而通过console打印发现数据更新了,只是view层没有及时的检测到。

    再看一个栗子的:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>vue</title>
      <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
      <style>
        li:hover {
          cursor: pointer;
        }
      </style>
    </head>
    <body>
      <div class="wrap">
        <ul>
          <li v-for="item,index in items" v-on:click="handle(index)">
            <span>{{item.name}}</span>
            <!--<span>{{numbers[index]}}</span>-->
          </li>
        </ul>
      </div>
      <script>
        var vm = new Vue({
          el: ".wrap",
          data: {
            // numbers: [],
            items: [
              {name: 'jjj'},
              {name: 'kkk'},
              {name: 'lll'},
            ]
          },
          methods: {
            handle: function (index) {
              // 不是数组,这里更新数据就可以直接在view层渲染
              this.items[index].name += " success";
            //   console.log(this.numbers)
            }
          }
        });
      </script>
    </body>
    </html>

    可以看到这里的view层能及时得到更新,但是到了数组哪里为什么就不可以了呢?


    来看Vue2.0官方的文档说明:

    由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

    当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
    当你修改数组的长度时,例如:vm.items.length = newLength
    为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

    // Vue.set
    Vue.set(example1.items, indexOfItem, newValue)
    
    
    // Array.prototype.splice
    example1.items.splice(indexOfItem, 1, newValue)

    你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名。

    还有由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:

    var vm = new Vue({
      data: {
        a: 1
      }
    })
    // `vm.a` 现在是响应式的
     
    vm.b = 2
    // `vm.b` 不是响应式的

    对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。例如,对于:

    var vm = new Vue({
      data: {
        userProfile: {
          name: 'Anika'
        }
      }
    })


    //如果你想添加新的响应式属性应该这样做:
    this
    .userProfile = Object.assign({}, this.userProfile, { age: 27, favoriteColor: 'Vue Green' })
  • 相关阅读:
    21 viewPager--- hzScrollView ----llContainer
    21 ViewPager RadioGroup
    CLEAR REFRESH FEEE的区别
    在ALV中更新数据库表
    cl_gui_cfw=>flush
    cl_gui_cfw=>dispatch
    数据库表-DD01L DD02L DD03L-保存数据表和域的消息
    SAP 锁机制
    ABAP 搜索帮助
    SAP Basis常用事务代码
  • 原文地址:https://www.cnblogs.com/gavinjay/p/10678406.html
Copyright © 2011-2022 走看看