最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue面試created中兩次數(shù)據(jù)修改會(huì)觸發(fā)幾次頁面更新詳解

 更新時(shí)間:2022年12月22日 10:56:58   作者:qb  
這篇文章主要為大家介紹了vue面試created中兩次數(shù)據(jù)修改會(huì)觸發(fā)幾次頁面更新問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

面試題:

created生命周期中兩次修改數(shù)據(jù),會(huì)觸發(fā)幾次頁面更新?

一、同步的

先舉個(gè)簡(jiǎn)單的同步的例子:

new Vue({
  el: "#app",
  template: `<div>
    <div>{{count}}</div>
  </div>`,
  data() {
    return {
      count: 1,
    }
  },
  created() {
    this.count = 2;
    this.count = 3;
  },
});

created生命周期中,通過this.count = 2this.count = 3的方式將this.count重新賦值。

這里直接拋出答案:渲染一次。

為什么? 

這個(gè)與數(shù)據(jù)的響應(yīng)式處理有關(guān),先看響應(yīng)式處理的邏輯:

export function defineReactive (
  obj: Object,
  key: string,
  val: any,
  customSetter?: ?Function,
  shallow?: boolean
) {
  // 重點(diǎn):創(chuàng)建一個(gè)發(fā)布者實(shí)例
  const dep = new Dep()
  const property = Object.getOwnPropertyDescriptor(obj, key)
  if (property && property.configurable === false) {
    return
  }
  // cater for pre-defined getter/setters
  const getter = property && property.get
  const setter = property && property.set
  if ((!getter || setter) && arguments.length === 2) {
    val = obj[key]
  }
  let childOb = !shallow && observe(val)
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      const value = getter ? getter.call(obj) : val
      if (Dep.target) {
        // 重點(diǎn):進(jìn)行當(dāng)前正在計(jì)算的渲染W(wǎng)atcher的收集
        dep.depend()
        if (childOb) {
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value)
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      const value = getter ? getter.call(obj) : val
      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      /* eslint-enable no-self-compare */
      if (process.env.NODE_ENV !== 'production' && customSetter) {
        customSetter()
      }
      // #7981: for accessor properties without setter
      if (getter && !setter) return
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      childOb = !shallow && observe(newVal)
      // 重點(diǎn):當(dāng)數(shù)據(jù)發(fā)生變化時(shí),發(fā)布者實(shí)例dep會(huì)通知收集到的watcher進(jìn)行更新
      dep.notify()
    }
  })
}

在數(shù)據(jù)響應(yīng)式處理階段,會(huì)實(shí)例化一個(gè)發(fā)布者dep,并且通過Object.defineProperty的方式為當(dāng)前數(shù)據(jù)定義getset函數(shù)。在生成虛擬vNode的階段,會(huì)觸發(fā)get函數(shù)中會(huì)進(jìn)行當(dāng)前正在計(jì)算的渲染Watcher的收集,此時(shí),發(fā)布者depsubs中會(huì)多一個(gè)渲染Watcher實(shí)例。在數(shù)據(jù)發(fā)生變化的時(shí)候,會(huì)觸發(fā)set函數(shù),通知發(fā)布者depsubs中的watcher進(jìn)行更新。

至于數(shù)據(jù)修改會(huì)觸發(fā)幾次更新,就與當(dāng)前發(fā)布者depsubs中收集了幾次渲染watcher有關(guān)了,再看watcher收集和created執(zhí)行之間的順序:

Vue.prototype._init = function (options) {
    // ...
    initState(vm);
    // ...
    callHook(vm, 'created');
    // ...
    if (vm.$options.el) {
      vm.$mount(vm.$options.el);
    }
}

我們知道在initState(vm)階段對(duì)數(shù)據(jù)進(jìn)行響應(yīng)式處理,但是此時(shí)發(fā)布者depsubs還是空數(shù)組。當(dāng)執(zhí)行callHook(vm, 'created')的時(shí)候,會(huì)執(zhí)行this.count = 2this.count = 3的邏輯,也的確會(huì)觸發(fā)set函數(shù)中的dep.notify通知收集到的watcher進(jìn)行更新。但是,此時(shí)depsubs是空數(shù)組,相當(dāng)于啥也沒做。

只有在vm.$mount(vm.$options.el)執(zhí)行過程中,生成虛擬vNode的時(shí)候才會(huì)進(jìn)行渲染Watcher收集,此時(shí),depsubs才不為空。最終,通過vm.$mount(vm.$options.el)進(jìn)行了頁面的一次渲染,并未因?yàn)?code>this.count=2或者this.count=3而觸發(fā)多余的頁面更新。

簡(jiǎn)言之,就是created鉤子函數(shù)內(nèi)的邏輯的執(zhí)行是在渲染watcher收集之前執(zhí)行的,所以未引起因?yàn)閿?shù)據(jù)變化而導(dǎo)致的頁面更新。

二、異步的

同步的場(chǎng)景說完了,我們?cè)倥e個(gè)異步的例子:

new Vue({
  el: "#app",
  template: `<div>
    <div>{{count}}</div>
  </div>`,
  data() {
    return {
      count: 1,
    }
  },
  created() {
    setTimeout(() => {
      this.count = 2;
    }, 0)
    setTimeout(() => {
      this.count = 3;
    }, 0)
  },
});

created生命周期中,通過異步的方式執(zhí)行this.count = 2this.count = 3的方式將this.count重新賦值。

這里直接拋出答案:首次渲染一次,因?yàn)閿?shù)據(jù)變化導(dǎo)致的頁面更新兩次。

為什么?

這個(gè)就與eventLoop事件循環(huán)機(jī)制有關(guān)了,我們知道javascript是一個(gè)單線程執(zhí)行的語言,當(dāng)我們通過new Vue實(shí)例化的過程中,會(huì)執(zhí)行初始化方法this._init方法,開始了Vue底層的處理邏輯。當(dāng)遇到setTimeout異步操作時(shí),會(huì)將其推入到異步隊(duì)列中去,等待當(dāng)前同步任務(wù)執(zhí)行完以后再去異步隊(duì)列中取出隊(duì)首元素進(jìn)行執(zhí)行。

當(dāng)前例子中,在initState(vm)階段對(duì)數(shù)據(jù)進(jìn)行響應(yīng)式處理。當(dāng)執(zhí)行callHook(vm, 'created')的時(shí)候,會(huì)將this.count = 2this.count = 3的邏輯推入到異步隊(duì)列等待執(zhí)行。繼續(xù)執(zhí)行vm.$mount(vm.$options.el)的過程中會(huì)去生成虛擬vNode,進(jìn)而觸發(fā)get函數(shù)的渲染Watcher收集,此時(shí),depsubs中就有了一個(gè)渲染watcher

等首次頁面渲染完成以后,會(huì)去執(zhí)行this.count=2的邏輯,數(shù)據(jù)的修改會(huì)觸發(fā)set函數(shù)中的dep.notify,此時(shí)發(fā)布者depsubs不為空,會(huì)引起頁面的更新。同理,this.count=3會(huì)再次引起頁面數(shù)據(jù)的更新。也就是說,首次渲染一次,因?yàn)?code>this.count=2和this.count=3還會(huì)導(dǎo)致頁面更新兩次。

三、附加

如果我改變的值和data中定義的值一致呢?

new Vue({
  el: "#app",
  template: `<div>
    <div>{{count}}</div>
  </div>`,
  data() {
    return {
      count: 1,
    }
  },
  created() {
    setTimeout(() => {
      this.count = 1;
    }, 0)
  },
});

這個(gè)時(shí)候,在觸發(fā)set的邏輯中,會(huì)當(dāng)執(zhí)行到if (newVal === value || (newVal !== newVal && value !== value)) { return }的邏輯,不會(huì)再執(zhí)行到dep.notify,這種場(chǎng)景下數(shù)據(jù)的數(shù)據(jù)也不會(huì)引起頁面的再次更新。

總結(jié)

從生命周期created和頁面渲染的先后順序,Object.defineProperty觸發(fā)getset函數(shù)的機(jī)理,以及eventLoop事件循環(huán)機(jī)制入手,去分析created中兩次數(shù)據(jù)修改會(huì)觸發(fā)幾次頁面更新的問題就會(huì)清晰很多。

以上就是vue面試created中兩次數(shù)據(jù)修改會(huì)觸發(fā)幾次頁面更新詳解的詳細(xì)內(nèi)容,更多關(guān)于vue created數(shù)據(jù)修改頁面更新的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue實(shí)現(xiàn)的多頁面項(xiàng)目如何優(yōu)化打包的步驟詳解

    vue實(shí)現(xiàn)的多頁面項(xiàng)目如何優(yōu)化打包的步驟詳解

    這篇文章主要介紹了vue實(shí)現(xiàn)的多頁面項(xiàng)目如何優(yōu)化打包的步驟詳解,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • vue 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的全局調(diào)用彈窗案例

    vue 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的全局調(diào)用彈窗案例

    這篇文章主要介紹了vue 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的全局調(diào)用彈窗案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • vue組件入門知識(shí)全梳理

    vue組件入門知識(shí)全梳理

    這篇文章主要給大家介紹了關(guān)于vue組件入門知識(shí)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • vue+axios+mock.js環(huán)境搭建的方法步驟

    vue+axios+mock.js環(huán)境搭建的方法步驟

    本篇文章主要介紹了vue+axios+mock.js環(huán)境搭建的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • Vue如何實(shí)現(xiàn)響應(yīng)式系統(tǒng)

    Vue如何實(shí)現(xiàn)響應(yīng)式系統(tǒng)

    這篇文章給大家整理了關(guān)于Vue如何實(shí)現(xiàn)響應(yīng)式系統(tǒng)的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友可以參考學(xué)習(xí)下。
    2018-07-07
  • Vue操作DOM解決顯示位置問題

    Vue操作DOM解決顯示位置問題

    這篇文章主要介紹了Vue操作DOM解決顯示位置問題,文中通過代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-12-12
  • vue開發(fā)調(diào)試神器vue-devtools使用詳解

    vue開發(fā)調(diào)試神器vue-devtools使用詳解

    這篇文章主要為大家詳細(xì)介紹了vue開發(fā)調(diào)試神器vue-devtools的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 富文本編輯器quill.js?開發(fā)之自定義插件示例詳解

    富文本編輯器quill.js?開發(fā)之自定義插件示例詳解

    這篇文章主要為大家介紹了富文本編輯器quill.js?開發(fā)之自定義插件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • vue中的計(jì)算屬性傳參

    vue中的計(jì)算屬性傳參

    這篇文章主要介紹了vue中的計(jì)算屬性傳參,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 使用vue構(gòu)建一個(gè)上傳圖片表單

    使用vue構(gòu)建一個(gè)上傳圖片表單

    這篇文章主要為大家詳細(xì)介紹了使用vue構(gòu)建一個(gè)上傳圖片表單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07

最新評(píng)論

铁岭县| 莱西市| 井陉县| 锦屏县| 九龙城区| 蓬莱市| 安宁市| 民丰县| 宜兴市| 蚌埠市| 南陵县| 盱眙县| 瓦房店市| 鹿邑县| 琼海市| 安远县| 洮南市| 孟州市| 永昌县| 错那县| 潢川县| 来安县| 绥阳县| 德化县| 五原县| 安岳县| 三明市| 贺兰县| 揭西县| 旌德县| 和政县| 乐平市| 秭归县| 蓬莱市| 洛隆县| 连城县| 石泉县| 那坡县| 永泰县| 炉霍县| 阜新|