zoukankan      html  css  js  c++  java
  • vue数据不响应,可能是用法有问题

    <template>
      <div>
        <div>
          <span>用户名: {{ userInfo.name }}</span>
          <span>用户性别: {{ userInfo.sex }}</span>
          <span v-if="userInfo.officialAccount">
            公众号: {{ userInfo.officialAccount }}
          </span>
        </div>
        <button @click="handleAddOfficialAccount">添加公众号</button>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          userInfo: {
            name: '子君',
            sex: '男'
          }
        }
      },
      methods: {
        // 在这里添加用户的公众号
        handleAddOfficialAccount() {
          this.userInfo.officialAccount = '前端有的玩'
        }
      }
    }
    </script>
    
    
    但是通过this.userInfo.officialAccount = '前端有的玩' 
    添加之后,并没有生效,这是为什么呢?
    这是因为在Vue内部,
    数据响应是通过使用Object.definePrototype监听对象的每一个键的getter,然后通过setter方法来实现的,
    但通过这种方法只能监听到已有属性,新增的属性是无法监听到的,
    但我就是想监听,咋办????。下面小编提供了四种方式,如果有更多方式,欢迎下方评论区告诉我。
    

    方法一

    data() {
        return {
          userInfo: {
            name: '子君',
            sex: '男',
    
            // 我先提前定义好
            officialAccount: '',//新增
          }
        }
      }
    

    方法二

    其实上面这方法都有点取巧的嫌疑,
    其实对于新增属性,
    Vue官方专门提供了一个新的方法Vue.set用来解决【新增属性】无法触发数据响应
    
    但是每次要用到set方法的时候,还要把Vue引入进来,
    好麻烦,所以为了简便起见,
    Vue又将set方法挂载到了Vue的原型链上了,
    即Vue.prototype.$set = Vue.set,
    所以在Vue组件内部可以直接使用this.$set代替Vue.set
    
    this.$set(this.userInfo,'officialAccount', '前端有的玩')
    
    许多同学不知道什么时候应该用Vue.set,
    其实只有当你要赋值的属性还没有定义的时候需要使用Vue,set,其他时候一般不会需要使用。
    

    方法三

    我觉得$forceUpdate的存在,
    让许多前端开发者不会再去注意数据双向绑定的原理,
    因为不论什么时候,
    反正我修改了data之后,
    调用一下$forceUpdate就会让Vue组件重新渲染,bug是不会存在的。
    但是实际上这个方法并不建议使用,
    因为它会引起许多不必要的性能消耗。
    
    

    针对数组的特定方式
    其实不仅仅是对象,数组也存在数据修改之后不响应的情况,比如下面这段代码

    <template>
      <div>
        <ul>
          <li v-for="item in list" :key="item">
            {{ item }}
          </li>
        </ul>
        <button @click="handleChangeName">修改名称</button>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          list: ['张三', '李四']
        }
      },
      methods: {
        // 修改用户名称
        handleChangeName() {
          this.list[0] = '王五'
        }
      }
    }
    </script>
    
    上面的代码希望将张三的名字修改为王五,实际上这个修改并不能生效,这是因为Vue不能检测到以下变动的数组:
    
    当你利用索引直接设置一个项时,
    
    例如: this.list[index] = newValue修改数组的length属性,例如: this.list.length = 0
    所以在上例中通过this.list[0] = '王五' 是无法触发数据响应的,那应该怎么办呢?
    像上面提到的Vue.set和$forceUpdate都可以解决这个问题,比如Vue.set可以这样写
    
    Vue.set(this.list,0,'王五')
    
    在操作数组的时候,
    我们一般会用到数据提供的许多方法,
    比如push,pop,splice等等,
    在Vue中调用数组上面提供的这些方法修改数组的值是可以触发数据响应的,
    比如上面的代码改为以下代码即可触发数据响应
    
    this.list.splice(0,1,'王五')
    
    实际上,
    如果Vue仅仅依赖getter与setter,
    是无法做到在数组调用push,pop等方法时候触发数据响应的,
    因此Vue实际上是通过劫持这些方法,
    对这些方法进行包装变异来实现的。
    
    Vue对数组的以下方法进行的包装变异:
    push
    pop
    shift
    unshift
    splice
    sort
    reverse
    

    原地址:掘金:https://juejin.im/post/6854573211422572557

    作者:明月人倚楼
    出处:https://www.cnblogs.com/IwishIcould/

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!

    万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    支付宝
    微信
    本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
    如果文中有什么错误,欢迎指出。以免更多的人被误导。
  • 相关阅读:
    Coroutine 协程
    jQuery Ajax calls and the Html.AntiForgeryToken()
    CSRF in asp.net mvc and ap.net core
    What is the difference between XSS and CSRF from their execution perspective?
    cocos2d制作动态光晕效果基础——blendFunc
    很有设计感的世界杯
    cocos2d-x (Android)之-那些常见的error记
    cocos2dx libcurl
    如何在遍历中使用 iterator/reverse_iterator 删除元素
    Android ndk下用AssetManager读取assets的资源
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/13994211.html
Copyright © 2011-2022 走看看