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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM