Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 412|回复: 0

Vue不能检测数组或对象变动问题的解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-25 06:52:54 | 显示全部楼层 |阅读模式
    <!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' })

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-23 09:16 , Processed in 0.055831 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表