您好,登錄后才能下訂單哦!
這篇文章主要講解了“Vue data中隨意改一個屬性視圖就會更新嗎”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Vue data中隨意改一個屬性視圖就會更新嗎”吧!
先寫個簡單的 demo
,其中 data 中有 4 個屬性a,b,c,d,在模板中被利用到的屬性只有a,b。看看是不是只有a,b才會調用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}}{{b}}</div>', });
在Vueinstance/state.js里面,會利用proxy把每個屬性都 代理一遍
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)) { // 代理對象的屬性 proxy(vm, `_data`, key) } } // observe data observe(data, true /* asRootData */)
利用defineReactive對data中的每個屬性進行劫持
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; // 重點在這里,后續如果在模板中使用到的屬性,都會被執行reactiveGetter函數 // 被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 函數 setter.call(obj, newVal); } else { val = newVal; } childOb = !shallow && observe(newVal); // 如果我們在更改屬性時,就會調用notify 異步更新視圖 dep.notify(); }, });
執行$mount進行視圖掛載
if (vm.$options.el) { vm.$mount(vm.$options.el); }
$mount 是調用 Vue 原型上的方法, 重點是最后一句 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 函數是否存在?如果不存在就解析template模板 * Vue渲染頁面時,有兩個方式 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) { // 如果模板不存在,就創建一個默認的html模板 template = getOuterHTML(el); } } // 重寫了Vue.prototype.$mount ,最終調用緩存的mount方法完成對$mount的掛載 return mount.call(this, el, hydrating); };
這里mount調用了 mountComponent(this, el, hydrating) 方法,而 mountComponent是執行了 _render函數,最終_render是調用render 生成一個vnode。
const { render, _parentVnode } = vm.$options; vnode = render.call(vm._renderProxy, vm.$createElement);
最后一張圖可以看到是render
函數在渲染我們demo
里面的template
模板,最終只有a, b兩個屬性才會被Dep類收集起來。
感謝各位的閱讀,以上就是“Vue data中隨意改一個屬性視圖就會更新嗎”的內容了,經過本文的學習后,相信大家對Vue data中隨意改一個屬性視圖就會更新嗎這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。