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

Object.assign觸發(fā)watch原理示例解析

 更新時間:2022年11月04日 09:12:52   作者:字節(jié)逆旅  
這篇文章主要為大家介紹了Object.assign觸發(fā)watch原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

為什么可以用Object.assign觸發(fā)$watch

Object.assign,這個api在簡單拷貝可枚舉對象的屬性值時經(jīng)常用到。這里介紹一個在vue2中Object.assign的用法,這個用法在官網(wǎng)文檔 有詳細(xì)介紹:

watch: {
	someObject(nvalue, ovalue) {
		...
	}
}
// 為對象添加新屬性
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

而且要注意的是如果像下面這樣添加上去的新屬性無法觸發(fā)更新:

this.someObject = Object.assign(this.someObject, { a: 1, b: 2 })

問題是為什么前面那種寫法會有效?

先看vue2文檔

在vue2的文檔中有詳細(xì)說明,在組件的依賴收集過程中,所有property 在被訪問和修改時會通知變更,對于對象來說,Vue 無法檢測 property 的添加或移除。

一般情況下,在vue中,如果要對data對象中實例添加根級別property,我們可以這樣操作:

Vue.set(someObject, 'name', value)

或者這樣操作

this.$set(this.someObject,'name',2)

但是如果我們要對一個對象添加多個屬性,同時還要保持對象的響應(yīng)性,這種情況下就要用到開篇提到的方法。

mdn 上,對 Object.assign 有這一句解釋:該方法使用源對象的[[Get]]和目標(biāo)對象的[[Set]],所以它會調(diào)用相關(guān) getter 和 setter。對這句,我們用下面的例子a來理解。

var obj = {};
var c = null
Object.defineProperty(obj, 'c', {
  set:function(x){
    console.log('c被賦值:',x);
    c=x
  },
  get:function(){
    console.log('c被取出:',c)
    return c
  }
})
obj.c=3  //c被賦值: 3
obj.c  //c被取出:  3
obj = Object.assign(obj, {c: 'wer23e'}) // 觸發(fā)了set!
obj = Object.assign(obj, {a: 'wer23e'}) // 由于事先未用defineProperty定義a,所以無法監(jiān)聽
// 由于目標(biāo)對象未定義屬性,無法監(jiān)聽
obj = Object.assign({},obj, {a: 'wer23e',c: 'dfrr23e'}) 

通過這段代碼可以理解上面說的“Object.assign會使用目標(biāo)對象的[[Set]]”,同時,這段代碼也演示了vue2中響應(yīng)原理,因為vue2中所有需要響應(yīng)的屬性都是用 Object.defineProperty 進行響應(yīng)綁定,這樣所有的訪問和修改動作都會被追蹤到。

但是對于沒有事先被 Object.defineProperty定義的屬性,比如添加一個屬性就無法監(jiān)聽到了。在上面的示例中,即使我用文檔提到的用法 obj = Object.assign({},obj, {a: 'wer23e',c: 'dfrr23e'}) 仍然無法觸發(fā)c屬性的 set。走到這一步,是不是得看watch源碼了?其實不必!

用Object.assign觸發(fā)watch原理

針對這個問題,watch的源碼不必看,但是 Object.assign 的源碼必須要看,

if (typeof Object.assign !== 'function') {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, "assign", {
    value: function assign(target, varArgs) { // .length of function is 2
      'use strict';
      if (target === null || target === undefined) {
        throw new TypeError('Cannot convert undefined or null to object');
      }
      var to = Object(target);
      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];
        if (nextSource !== null && nextSource !== undefined) {
          for (var nextKey in nextSource) {
            // Avoid bugs when hasOwnProperty is shadowed
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to;
    },
    writable: true,
    configurable: true
  });
}

其實就是把 assign 方法中的參數(shù)的可枚舉屬性全部復(fù)制到此方法的第一參數(shù)上去。回頭再去理解下例子a, obj = Object.assign({},obj, {a: 'wer23e',c: 'dfrr23e'}) 無法觸發(fā)c屬性的 set 函數(shù)是因為,obj引用關(guān)系已經(jīng)被改變了,不再是原來那個對象,也就沒有了對應(yīng)的屬性監(jiān)控,但是為什么官方文檔會建議這么用呢?

接下來,我寫了個小demo,來幫你理解,你可以試下效果

<template>
 <div style="width: 100px; height: 50px; position: absolute; top: 100px" @click="clickme()"> 點我啊 {{ test.a }}</div>
</template>
<script>
export default {
	data() {
		test: { a: 3 },
	},
	watch: {
    test(n, o) {
      debugger
      console.log(n)
    }
  },
	methods: {
		clickme() {
      debugger
      this.test = Object.assign(this.test, { a: 1 })
      debugger
      this.test = Object.assign(this.test, { a: 1, b: 2 })
      debugger
      this.test = Object.assign({}, this.test, { a: 1, b: 2 })
    },	
}
}
</script>

可以看到,確實,最后一種Object.assign方法會觸發(fā)test對象監(jiān)聽。前面兩種寫法,只能觸發(fā)對象的屬性更新響應(yīng),如果給obj對象添加屬性,就無法監(jiān)測到obj的變化。到這一步,其實如果要徹底弄清楚,最好還是看下 watch 源碼。我在仔細(xì)分析了后,才發(fā)現(xiàn)其實跟watch源碼沒有什么關(guān)系,所以本文就不展開分析了,這是另一篇文章的事了。

如果看不明白 watch 源碼也沒關(guān)系,其實簡單解釋就是,用obj = Object.assign({},obj, {a: 'wer23e',c: 'dfrr23e'}) 這種方式,改變了obj的引用關(guān)系,也就是obj的值變了,所以如果你在watch函數(shù)中監(jiān)聽了obj,obj是變化了的,只不過obj的值是一個 Object 對象而已,所以會觸發(fā)obj對象的響應(yīng)。

參考資料:

cn.vuejs.org/v2/guide/re…

developer.mozilla.org/zh-CN/docs/…

http://chabaoo.cn/article/265630.htm

http://chabaoo.cn/article/266683.htm

以上就是Object.assign觸發(fā)watch原理示例解析的詳細(xì)內(nèi)容,更多關(guān)于Object.assign觸發(fā)watch的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue實現(xiàn)簡單的跑馬燈

    Vue實現(xiàn)簡單的跑馬燈

    這篇文章主要為大家詳細(xì)介紹了Vue實現(xiàn)簡單的跑馬燈,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • vue如何給element-ui中的el-tabs動態(tài)設(shè)置label屬性

    vue如何給element-ui中的el-tabs動態(tài)設(shè)置label屬性

    這篇文章主要介紹了vue如何給element-ui中的el-tabs動態(tài)設(shè)置label屬性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 詳解如何從零開始搭建Express+Vue開發(fā)環(huán)境

    詳解如何從零開始搭建Express+Vue開發(fā)環(huán)境

    這篇文章主要介紹了詳解如何從零開始搭建Express+Vue開發(fā)環(huán)境,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • vue中axios防止多次觸發(fā)終止多次請求的示例代碼(防抖)

    vue中axios防止多次觸發(fā)終止多次請求的示例代碼(防抖)

    這篇文章主要介紹了vue中axios防止多次觸發(fā)終止多次請求的實現(xiàn)方法(防抖),本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • vue+webrtc(騰訊云) 實現(xiàn)直播功能的實踐

    vue+webrtc(騰訊云) 實現(xiàn)直播功能的實踐

    本文主要介紹了vue+webrtc(騰訊云) 實現(xiàn)直播功能的實踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • vue + typescript + video.js實現(xiàn) 流媒體播放 視頻監(jiān)控功能

    vue + typescript + video.js實現(xiàn) 流媒體播放 視頻監(jiān)控功能

    視頻才用流媒體,有后臺實時返回數(shù)據(jù), 要支持flash播放, 所以需安裝對應(yīng)的flash插件。這篇文章主要介紹了vue + typescript + video.js 流媒體播放 視頻監(jiān)控,需要的朋友可以參考下
    2019-07-07
  • vue項目部署自動清除緩存方式

    vue項目部署自動清除緩存方式

    這篇文章主要介紹了vue項目部署自動清除緩存方式,包括清除文件緩存,清除瀏覽器 localStorage 緩存方式,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Vue如何給組件添加點擊事件?@click.native

    Vue如何給組件添加點擊事件?@click.native

    這篇文章主要介紹了Vue如何給組件添加點擊事件?@click.native,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 保姆級Vue3開發(fā)教程分享

    保姆級Vue3開發(fā)教程分享

    這篇Vue3開發(fā)文檔,包含了 Vue3 開發(fā)中使用的所有語法,文中的示例代碼講解詳細(xì),希望所有像他一樣還不熟的伙伴快速上手 Vue3,不會的再不看要遭老罪咯
    2023-04-04
  • 詳解基于element的區(qū)間選擇組件校驗(交易金額)

    詳解基于element的區(qū)間選擇組件校驗(交易金額)

    這篇文章主要介紹了詳解基于element的區(qū)間選擇組件校驗(交易金額),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評論