亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

vue中Vue.set()的使用以及對(duì)其進(jìn)行深入解析

 更新時(shí)間:2023年01月04日 09:31:46   作者:天命愛心職責(zé)~  
vue不允許在已經(jīng)創(chuàng)建的實(shí)例上動(dòng)態(tài)添加新的根級(jí)響應(yīng)式屬性,不過(guò)可以使用Vue.set()方法將響應(yīng)式屬性添加到嵌套的對(duì)象上,下面這篇文章主要給大家介紹了關(guān)于vue中Vue.set()的使用以及對(duì)其進(jìn)行深入解析的相關(guān)資料,需要的朋友可以參考下

Vue.set()使用

vue 在實(shí)例上添加新的屬性的時(shí)候,該屬性,并不是響應(yīng)式的。同樣刪除某一屬性的時(shí)候,也不會(huì)實(shí)時(shí)渲染到頁(yè)面上。

比如:

 <p> 年齡:{{obj.age? obj.age: "無(wú)"}}</p>

        ···········      

 data() {

            return {        

                obj:{ name:"Lena", id:1 },

            }

          }

頁(yè)面上 顯示的是  年齡:無(wú)   現(xiàn)在需要添加一個(gè)響應(yīng)式的屬性 age 。

<template>
<div class="app">
      <ul>
        <li> 年齡:{{obj.age? obj.age: "無(wú)"}}</li>
      </ul>
      <button @click="add()">添加年齡屬性</button>
      <button @click="show()">打印</button>
</div>
</template>
 
<script>
import Vue from 'vue'
export default {
  component:{},
  data() {
    return {
        obj:{ name:"Lena", id:1 },
    }
  },
  methods: {
    add(){
      this.obj.age= 20
    },
    show(){
      console.log('obj',this.obj)
    }
  }
}
</script>

效果:

通過(guò) this.obj.age= 20 ,控制臺(tái)打印已經(jīng)有了該屬性,并沒(méi)有渲染到頁(yè)面上。 可見,這種方式添加的屬性 age 并不是響應(yīng)式的。

使用Vue.set() ,更改add()方法:

add(){
      Vue.set(this.obj,'age', '20')
    },

效果:

因?yàn)関ue不能檢測(cè)到對(duì)象屬性的添加或者刪除,只有在data對(duì)象上存在的屬性是響應(yīng)式的,所以要使用Vue.set()方法將響應(yīng)式屬性添加到對(duì)象上。同樣的道理,刪除對(duì)象 Vue.delete也是如此。

Vue.delete()的使用

<template>
<div class="app">
      <ul>
        <li> 年齡:{{obj.age? obj.age: "無(wú)"}}</li>
      </ul>
      <button @click="add()">添加年齡屬性</button>
      <button @click="del()">刪除年齡屬性</button>
      <button @click="show()">打印</button>
</div>
</template>
<script>
import Vue from 'vue'
export default {
  component:{
 
  },
  data() {
    return {
        obj:{ name:"Lena", id:1 },
    }
  },
  methods: {
    add(){
      Vue.set(this.obj,'age', '20')
    },
    del(){
      Vue.delete(this.obj,'age')
    },
    show(){
      console.log('obj',this.obj)
    }
  }
}
</script>

效果:

del() 方法如果是下面兩種,同樣不是響應(yīng)式的。

del(){

      delete this.obj.age

    },

或者:

del(){

      this.obj = { name:"Lena", id:1 }

    },

Vue.set()方法原理解析

我們找到封裝set方法的地方:.........\node_modules\vue\src\core\observer\index.js

 找到封裝的set方法:

export function set (target: Array<any> | Object, key: any, val: any): any {
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, val)
    return val
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val
    return val
  }
  const ob = (target: any).__ob__
  if (target._isVue || (ob && ob.vmCount)) {
    process.env.NODE_ENV !== 'production' && warn(
      'Avoid adding reactive properties to a Vue instance or its root $data ' +
      'at runtime - declare it upfront in the data option.'
    )
    return val
  }
  if (!ob) {
    target[key] = val
    return val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

對(duì)象調(diào)用:Vue.set( target ,'age', 20 ) 

數(shù)組調(diào)用Vue.set( array , 0,  20 )  //數(shù)組對(duì)象,索引,值

首先是判斷是否是開發(fā)環(huán)境并且 對(duì)象是否被定義isUndef(target)或者是否是基礎(chǔ)類型isPrimitive(target),否則會(huì)報(bào)錯(cuò):

`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`

if (process.env.NODE_ENV !== 'production' &&

    (isUndef(target) || isPrimitive(target))

  )

如果是數(shù)組的話,調(diào)用重寫的splice()方法,可以更新視圖。

isValidArrayIndex(key)方法用來(lái)驗(yàn)證是否是一個(gè)有效的數(shù)組索引, 其實(shí)就是驗(yàn)證是否是一個(gè)非無(wú)窮大的正整數(shù)。

if (Array.isArray(target) && isValidArrayIndex(key)) {
? ? target.length = Math.max(target.length, key)
? ? target.splice(key, 1, val)
? ? return val
? }

如果對(duì)象本身就有所要添加的屬性,那只需要直接賦值就可以。

if (key in target && !(key in Object.prototype)) {
? ? target[key] = val
? ? return val
? }

 如果是Vue實(shí)例,或者是根數(shù)據(jù)data的時(shí)候,就會(huì)報(bào)錯(cuò)。

如果本身就不是響應(yīng)式的,只需要直接賦值即可。

const ob = (target: any).__ob__
  //如果是Vue實(shí)例,或者是根數(shù)據(jù)data的時(shí)候,就會(huì)報(bào)錯(cuò)。
  if (target._isVue || (ob && ob.vmCount)) {
    process.env.NODE_ENV !== 'production' && warn(
      'Avoid adding reactive properties to a Vue instance or its root $data '+
      'at runtime - declare it upfront in the data option.'
    )
    return val
  }
 
  //如果本身就不是響應(yīng)式的,只需要直接賦值即可。
  if (!ob) {
    target[key] = val
    return val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val

排除各種不合適的,最后給當(dāng)前對(duì)象定義一個(gè)屬性:defineReactive(ob.value, key, val) 相當(dāng)于用了 Object.defineProperty 重新定義了一下。

最后,手動(dòng)通知視圖更新:ob.dep.notify()

總結(jié)

這個(gè) set方法,對(duì)于數(shù)組來(lái)說(shuō),調(diào)用的就是splice,對(duì)于對(duì)象來(lái)說(shuō),使用的就是defineReactive,再添加了一個(gè)手動(dòng)的視圖更新。這就是set的原理。

到此這篇關(guān)于vue中Vue.set()的使用以及對(duì)其進(jìn)行深入解析的文章就介紹到這了,更多相關(guān)vue Vue.set()的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論