欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Vue的數(shù)據(jù)響應(yīng)式

 更新時(shí)間:2021年05月15日 10:38:54   作者:lovin  
Vue.js的核心包括一套“響應(yīng)式系統(tǒng)”?!绊憫?yīng)式”,是指當(dāng)數(shù)據(jù)改變后,Vue會(huì)通知到使用該數(shù)據(jù)的代碼。例如,視圖渲染中使用了數(shù)據(jù),數(shù)據(jù)改變后,視圖也會(huì)自動(dòng)更新。

1. ES語(yǔ)法的getter和setter

在開(kāi)始了解 Vue 的數(shù)據(jù)響應(yīng)式原理前應(yīng)該先搞清楚 ES語(yǔ)法 中的 getter 和 setter 方法的具體用法。

getter和setter 方法是以 get 和 set 關(guān)鍵字來(lái)為對(duì)象添加虛擬屬性的一種方式。這種屬性其實(shí)并不真實(shí)存在,而是以取值函數(shù) getter 和存值函數(shù) setter 來(lái)模擬的一種屬性。目的是對(duì)某個(gè)屬性設(shè)置存值函數(shù)和取值函數(shù),攔截該屬性的存取行為,以便于對(duì)該屬性的存取做一些限定處理。如下所示(以下代碼來(lái)源于 mdn)

getter 方法

const obj = {
  log: ['a', 'b', 'c'],
  get latest() { //在正常方法前加 get 關(guān)鍵字
    if (this.log.length == 0) {
      return undefined;
    }
    return this.log[this.log.length - 1];
  }
}

console.log(obj.latest);// 輸出 c,獲取的是屬性名不用帶括號(hào)

setter方法

const language = {
  set current(name) {
    this.log.push(name);
  },
  log: []
}

language.current = 'EN';
language.current = 'FA';

console.log(language.log);//輸出 Array ["EN", "FA"]

2. ES語(yǔ)法的 defineProperty

defineProperty 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性, 并返回這個(gè)對(duì)象,可用于在一個(gè)對(duì)象定義好后為其修改或添加屬性。
語(yǔ)法為:

Object.defineProperty(obj, prop, descriptor)

添加常規(guī)屬性:

let data = {
  m: 0
}

Object.defineProperty(data, 'n', {
  value: 1 //添加屬性的 value 就是其值
})
console.log(`${data.n}`) //則會(huì)輸出n值為1

也可用來(lái)添加 getter 和 setter 的虛擬屬性

let data1 = {
    _n: 0
}

Object.defineProperty(data1, 'n', {
  get(){
    return this._n
  }, 
  set(value){
    if(value < 0) return
    this._n = value
  }//直接寫(xiě)明 get / set 即可
}) //由于指明了虛擬屬性為 n,即 get n(){}、set n(value){},因此在函數(shù)定義時(shí)就不用再寫(xiě)n了

3. Vue對(duì)數(shù)據(jù)的代理和監(jiān)聽(tīng)

代理,即 proxy,簡(jiǎn)單來(lái)說(shuō)我自己的一些事情我自己不親自處理,而是交給一個(gè)人讓他去幫我做,那個(gè)做事的人就是代理。這個(gè)邏輯中有兩個(gè)關(guān)鍵點(diǎn)需要搞清楚,代理是處理操作的人,而其處理操作的事情不屬于他,而是屬于委托其代理的人的。

因此類(lèi)比到 Vue數(shù)據(jù)代理 ,委托代理的是 data{} 數(shù)據(jù)對(duì)象,其找到代理就是 Vue實(shí)例vm ,data{} 數(shù)據(jù)對(duì)象要代理 vm 做的事情是管理 data{} 數(shù)據(jù)對(duì)象里數(shù)據(jù)操作。因此 data{} 數(shù)據(jù)對(duì)象只負(fù)責(zé)內(nèi)部數(shù)據(jù)的生產(chǎn)即可,對(duì)生產(chǎn)出來(lái)的數(shù)據(jù)的管理和操作全權(quán)交給 vm 處理。

那么 vm 如何對(duì) data{} 數(shù)據(jù)對(duì)象里的數(shù)據(jù)進(jìn)行控制和操作呢?換句話(huà)說(shuō),vm 如何在 data{} 數(shù)據(jù)對(duì)象里面的任意一個(gè)屬性值變化時(shí)都及時(shí)知道呢?

于是便用到了 ES 語(yǔ)法中的 getter和setter 方法,通過(guò) getter和setter 方法控制的屬性的任何操作都會(huì)被這兩個(gè)函數(shù)檢測(cè)到,而 getter和setter 方法形成的屬性是虛擬屬性,真實(shí)并不存在,因此如果用戶(hù)想私自不經(jīng)過(guò)代理 vm 直接修改 data{} 數(shù)據(jù)對(duì)象的屬性也獲取不到對(duì)應(yīng)的實(shí)體屬性,只能通過(guò) getter和setter 方法修改,那么其修改就必定被 vm 檢測(cè)到。

因此 vm 為了實(shí)現(xiàn)對(duì) data{} 數(shù)據(jù)對(duì)象里數(shù)據(jù)的全部控制,就必須在 Vue實(shí)例 創(chuàng)建的時(shí)候?qū)鬟M(jìn)來(lái)的 data{} 數(shù)據(jù)對(duì)象做一些處理,做的處理就是將 data{} 數(shù)據(jù)對(duì)象里的屬性都變成了 getter和setter 方法控制的虛擬屬性,并保存在代理數(shù)據(jù)對(duì)象 obj 并返回。

但為了不讓用戶(hù)直接修改原來(lái)的 data{} 屬性,也將原來(lái)的 data{} 對(duì)象的實(shí)體屬性全改變了,添加的虛擬屬性名字和實(shí)體屬性名一樣,就會(huì)用虛擬屬性覆蓋原來(lái)的實(shí)際屬性,用戶(hù)在修改屬性值是就是通過(guò) getter和setter 方法修改的虛擬屬性。這樣一來(lái) data{} 數(shù)據(jù)對(duì)象的全部屬性的任何變化都會(huì)被 Vue實(shí)例vm 檢測(cè)到。

let myData = {n:0}
let data = proxy({ data:myData }) // 類(lèi)似于 let vm = new Vue({data: myData})

function proxy({data}/* 解構(gòu)賦值*/){
  let _n = data.n
  Object.defineProperty(data, 'n', { //覆蓋原來(lái)的data.n屬性
    get(){
      return _n
    },
    set(newValue){
      if(newValue<0)return
      _n = newValue
    }
  })// 改變data{}數(shù)據(jù)對(duì)象本身屬性,可通過(guò)閉包形成上下文,讓原來(lái)的實(shí)際屬性值存在閉包的上下文_n中
  
  const obj = {}
  Object.defineProperty(obj, 'n', {
    get(){
      return data.n
    },
    set(value){
      data.n = value
    }
  }) //添加data{}數(shù)據(jù)對(duì)象的代理,對(duì)data{}數(shù)據(jù)對(duì)象操作
  
  return obj // obj 就是data{}的代理
}

4. Vue的數(shù)據(jù)響應(yīng)式

所謂響應(yīng)式就是當(dāng)事物發(fā)生變化時(shí)會(huì)根據(jù)變化做出相應(yīng)的反映。

Vue 中的數(shù)據(jù) data 是響應(yīng)式的,由上述 Vue 通過(guò) Object.defineProperty()函數(shù) 來(lái)用 getter和setter方法 對(duì) data 數(shù)據(jù)做了代理和監(jiān)聽(tīng),一旦數(shù)據(jù)發(fā)生變化,Vue 就會(huì)改變數(shù)據(jù)對(duì)應(yīng)的 UI 視圖,這就是 Vue的數(shù)據(jù)響應(yīng)式

但是 Vue 使用 Object.defineProperty 來(lái)設(shè)置監(jiān)聽(tīng),就只能對(duì)在 Vue實(shí)例化 時(shí) data 對(duì)象里已經(jīng)存在的屬性設(shè)置監(jiān)聽(tīng),而對(duì)不存在的或者后來(lái)添加進(jìn)去的屬性沒(méi)有進(jìn)行監(jiān)聽(tīng)。

為了解決這個(gè)問(wèn)題,有兩種方法:

1. 將所有屬性都提前聲明好

2. 使用 Vue.set 和 this.$set 添加屬性

使用 Vue.set 和 this.$set 添加屬性是會(huì)通知 Vue 對(duì)這后添加的屬性也設(shè)置監(jiān)聽(tīng)操作。

Vue.set('this.data','m','10')
this.$set('this.data','m','10')//為vm的data對(duì)象添加屬性m值為10

3.數(shù)組變異

對(duì)于數(shù)組的數(shù)據(jù)增加,無(wú)法控制其新增個(gè)數(shù)因此不能提前聲明所有數(shù)據(jù)值,而一個(gè)一個(gè) set 又太麻煩,而且數(shù)組是常用的對(duì)象數(shù)據(jù)類(lèi)型中的一種,因此 vue 的作者就對(duì)數(shù)組的增刪函數(shù)如 push 和 pop 等進(jìn)行了篡改,用戶(hù)在使用 vue 中數(shù)組增刪時(shí)仍是用 push 和 pop ,但是里面進(jìn)行了額外的處理,這幾個(gè)被篡改的 API 會(huì)對(duì)數(shù)組新增是數(shù)據(jù)代理監(jiān)聽(tīng)并根據(jù)數(shù)據(jù)響應(yīng)改變 UI 視圖。

以上就是深入理解Vue的數(shù)據(jù)響應(yīng)式的詳細(xì)內(nèi)容,更多關(guān)于Vue的數(shù)據(jù)響應(yīng)式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue中的v-cloak使用解讀

    Vue中的v-cloak使用解讀

    本篇文章主要介紹了Vue中的v-cloak使用解讀,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • Vue3中reactive函數(shù)toRef函數(shù)ref函數(shù)簡(jiǎn)介

    Vue3中reactive函數(shù)toRef函數(shù)ref函數(shù)簡(jiǎn)介

    這篇文章主要介紹了Vue3中的三種函數(shù),分別對(duì)reactive函數(shù)toRef函數(shù)以及ref函數(shù)原理及使用作了簡(jiǎn)單介紹,有需要的朋友可以借鑒參考下
    2021-09-09
  • 打通前后端構(gòu)建一個(gè)Vue+Express的開(kāi)發(fā)環(huán)境

    打通前后端構(gòu)建一個(gè)Vue+Express的開(kāi)發(fā)環(huán)境

    這篇文章主要介紹了打通前后端構(gòu)建一個(gè)Vue+Express的開(kāi)發(fā)環(huán)境,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Vue.js中v-show和v-if指令的用法介紹

    Vue.js中v-show和v-if指令的用法介紹

    這篇文章介紹了Vue.js中v-show和v-if指令的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Vue3.x項(xiàng)目開(kāi)發(fā)的一些常用知識(shí)點(diǎn)總結(jié)

    Vue3.x項(xiàng)目開(kāi)發(fā)的一些常用知識(shí)點(diǎn)總結(jié)

    目前Vue3.0是會(huì)兼容大部分2.x的語(yǔ)法,下面這篇文章主要給大家介紹了關(guān)于Vue3.x項(xiàng)目開(kāi)發(fā)的一些常用知識(shí)點(diǎn),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • vue路由--網(wǎng)站導(dǎo)航功能詳解

    vue路由--網(wǎng)站導(dǎo)航功能詳解

    這篇文章主要介紹了vue路由--網(wǎng)站導(dǎo)航功能詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • vue?css?相對(duì)路徑導(dǎo)入問(wèn)題級(jí)踩坑記錄

    vue?css?相對(duì)路徑導(dǎo)入問(wèn)題級(jí)踩坑記錄

    這篇文章主要介紹了vue?css?相對(duì)路徑導(dǎo)入問(wèn)題級(jí)踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 詳解Vue使用命令行搭建單頁(yè)面應(yīng)用

    詳解Vue使用命令行搭建單頁(yè)面應(yīng)用

    本篇文章主要介紹了詳解Vue使用命令行搭建單頁(yè)面應(yīng)用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • webStorm?debug?vue項(xiàng)目的兩種方案圖文詳解

    webStorm?debug?vue項(xiàng)目的兩種方案圖文詳解

    WebStorm作為一款功能強(qiáng)大的IDE,提供了豐富的調(diào)試功能和技巧,可以幫助你更高效地開(kāi)發(fā)和調(diào)試Vue應(yīng)用,這篇文章主要給大家介紹了關(guān)于webStorm?debug?vue項(xiàng)目的兩種方案,需要的朋友可以參考下
    2024-07-07
  • Vue.js彈出模態(tài)框組件開(kāi)發(fā)的示例代碼

    Vue.js彈出模態(tài)框組件開(kāi)發(fā)的示例代碼

    本篇文章主要介紹了Vue.js彈出模態(tài)框組件開(kāi)發(fā)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07

最新評(píng)論