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

Vue?data中隨意改一個(gè)屬性,視圖都會(huì)更新嗎?

 更新時(shí)間:2021年12月15日 11:42:43   作者:Rudy24  
這篇文章主要討論Vue?data中隨意改一個(gè)屬性,視圖都會(huì)更新嗎?下面來自面試官的問題然后做i出的一個(gè)問題總結(jié),具有一定的參考價(jià)值,需要的小伙伴可以參考一下
  • 面試官:看過 Vue 的源碼沒?
  • 候選者:看過。
  • 面試官:那你說下 Vue data 中隨意更改一個(gè)屬性,視圖都會(huì)被更新嗎?
  • 候選者:不會(huì)。
  • 面試官:why?
  • 候選者:如果該屬性沒有被用到 template 中,就沒有必要去更新視圖,頻繁這樣性能不好。
  • 面試官:那 Vue 中是如何去實(shí)現(xiàn)該方案的?
  • 候選者:在實(shí)例初始化過程中,利用Object.defineProperty對(duì) data 中的屬性進(jìn)行數(shù)據(jù)監(jiān)聽,如果在 template 中被使用到的屬性,就被 Dep 類收集起來,等到屬性被更改時(shí)會(huì)調(diào)用notify更新視圖。
  • 面試官:那你怎么知道那些屬性是在 template 被用到的呢?
  • 候選者:WTF。。。這個(gè)倒不是很清楚,您能解釋下嗎?
  • 面試官:OK,那我就簡(jiǎn)單解釋下:

先寫個(gè)簡(jiǎn)單的 demo,其中 data 中有 4 個(gè)屬性a,b,c,d,在模板中被利用到的屬性只有a,b??纯词遣皇侵挥衋,b才會(huì)調(diào)用Dep收集起來呢?

new Vue({
  el: '#app',
  data() {
    return {
      a: 1,
      b: 2,
      c: 3,
      d: 4,
    };
  },
  created() {
    console.log(this.b);
    this.b = 'aaa';
  },
  template: '<div>Hello World{{a}}{}</div>',
});


在Vueinstance/state.js里面,會(huì)利用proxy把每個(gè)屬性都 代理一遍

const keys = Object.keys(data)
  const props = vm.$options.props
  const methods = vm.$options.methods
  let i = keys.length
  while (i--) {
    const key = keys[i]
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== 'production' && warn(
        `The data property "${key}" is already declared as a prop. ` +
        `Use prop default value instead.`,
        vm
      )
    } else if (!isReserved(key)) {
      // 代理對(duì)象的屬性
      proxy(vm, `_data`, key)
    }
  }
  // observe data
  observe(data, true /* asRootData */)


利用defineReactive對(duì)data中的每個(gè)屬性進(jìn)行劫持

observe(data, true /* asRootData */);

// observe
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
  defineReactive(obj, keys[i]);
}

// defineReactive
Object.defineProperty(obj, key, {
  enumerable: true,
  configurable: true,
  get: function reactiveGetter() {
    const value = getter ? getter.call(obj) : val;
    // 重點(diǎn)在這里,后續(xù)如果在模板中使用到的屬性,都會(huì)被執(zhí)行reactiveGetter函數(shù)
    // 被Dep類 收集起來
    if (Dep.target) {
      console.log(`${key} 屬性 被Dep類收集了`)
      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;
    }
    if (setter) {
      // 這里是處理computed set 函數(shù)
      setter.call(obj, newVal);
    } else {
      val = newVal;
    }
    childOb = !shallow && observe(newVal);
    // 如果我們?cè)诟膶傩詴r(shí),就會(huì)調(diào)用notify 異步更新視圖
    dep.notify();
  },
});

執(zhí)行$mount進(jìn)行視圖掛載

if (vm.$options.el) {
  vm.$mount(vm.$options.el);
}


$mount 是調(diào)用 Vue 原型上的方法, 重點(diǎn)是最后一句 mount.call(this, el, hydrating)

Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && query(el);

  const options = this.$options;
  // resolve template/el and convert to render function
  /**
   * 查看render 函數(shù)是否存在?如果不存在就解析template模板
   * Vue渲染頁面時(shí),有兩個(gè)方式 1. template,2. render,最終所有的模板類的都需要使用render去渲染
   */
  if (!options.render) {
    let template = options.template;
    if (template) {
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template);
          /* istanbul ignore if */
          if (process.env.NODE_ENV !== 'production' && !template) {
            warn(
              `Template element not found or is empty: ${options.template}`,
              this
            );
          }
        }
      } else if (template.nodeType) {
        template = template.innerHTML;
      } else {
        if (process.env.NODE_ENV !== 'production') {
          warn('invalid template option:' + template, this);
        }
        return this;
      }
    } else if (el) {
      // 如果模板不存在,就創(chuàng)建一個(gè)默認(rèn)的html模板
      template = getOuterHTML(el);
    }
  }
  // 重寫了Vue.prototype.$mount ,最終調(diào)用緩存的mount方法完成對(duì)$mount的掛載
  return mount.call(this, el, hydrating);
};

這里mount調(diào)用了 mountComponent(this, el, hydrating) 方法,而 mountComponent是執(zhí)行了 _render函數(shù),最終_render是調(diào)用render 生成一個(gè)vnode。

const { render, _parentVnode } = vm.$options;
vnode = render.call(vm._renderProxy, vm.$createElement);


最后一張圖可以看到是render函數(shù)在渲染我們demo里面的template模板,最終只有a, b兩個(gè)屬性才會(huì)被Dep類收集起來。

如果文中有錯(cuò)誤的地方,麻煩各位指出,我會(huì)持續(xù)改進(jìn)的。謝謝, 需要調(diào)試源碼的,這里點(diǎn)擊這里,按照 readme操作即可。希望star下

到此這篇關(guān)于Vue data中隨意改一個(gè)屬性,視圖都會(huì)更新?的文章就介紹到這了,更多相關(guān)Vue data 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解vue.js+UEditor集成 [前后端分離項(xiàng)目]

    詳解vue.js+UEditor集成 [前后端分離項(xiàng)目]

    本篇文章主要介紹了詳解vue.js+UEditor集成 [前后端分離項(xiàng)目] ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • Vue項(xiàng)目總結(jié)之webpack常規(guī)打包優(yōu)化方案

    Vue項(xiàng)目總結(jié)之webpack常規(guī)打包優(yōu)化方案

    這篇文章主要介紹了vue項(xiàng)目總結(jié)之webpack常規(guī)打包優(yōu)化方案,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • vue中watch和computed的區(qū)別詳解

    vue中watch和computed的區(qū)別詳解

    這篇文章主要給大家介紹了關(guān)于vue中watch和computed區(qū)別的相關(guān)資料,computed和watch都是vue框架中的用于監(jiān)聽數(shù)據(jù)變化的屬性,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • vue2中l(wèi)ess的安裝以及使用教程

    vue2中l(wèi)ess的安裝以及使用教程

    less是css預(yù)處理器,對(duì)原先css進(jìn)行了擴(kuò)展和補(bǔ)充,下面這篇文章主要給大家介紹了關(guān)于vue2中l(wèi)ess的安裝以及使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Vue+Vant 圖片上傳加顯示的案例

    Vue+Vant 圖片上傳加顯示的案例

    這篇文章主要介紹了Vue+Vant 圖片上傳加顯示的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Vue實(shí)現(xiàn)下拉表格組件

    Vue實(shí)現(xiàn)下拉表格組件

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)下拉表格組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue單頁應(yīng)用加百度統(tǒng)計(jì)代碼(親測(cè)有效)

    vue單頁應(yīng)用加百度統(tǒng)計(jì)代碼(親測(cè)有效)

    這篇文章主要介紹了vue單頁應(yīng)用加百度統(tǒng)計(jì)代碼的解決方法,需要的朋友參考下吧
    2018-01-01
  • vue虛擬滾動(dòng)性能優(yōu)化方式詳解

    vue虛擬滾動(dòng)性能優(yōu)化方式詳解

    這篇文章主要為大家介紹了vue虛擬滾動(dòng)性能優(yōu)化方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 在vue中使用Echarts畫曲線圖的示例

    在vue中使用Echarts畫曲線圖的示例

    這篇文章主要介紹了在vue中使用Echarts畫曲線圖的示例,幫助大家在vue中繪制圖表,感興趣的朋友可以了解下
    2020-10-10
  • 解決ant design vue 表格a-table二次封裝,slots渲染的問題

    解決ant design vue 表格a-table二次封裝,slots渲染的問題

    這篇文章主要介紹了解決ant design vue 表格a-table二次封裝,slots渲染的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10

最新評(píng)論