这篇文章主要讲解了"武田中随意改一个属性视图就会更新吗",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"武田中随意改一个属性视图就会更新吗"吧!
先写个简单的演示,其中数据中有四个属性a,b,c,d,在模板中被利用到的属性只有a,b。看看是不是只有a,b才会调用Dep收集起来呢?
newVue({ 0
el:'#app ',
数据(){ 0
返回{
a:1,
b:2,
c:3,
d:4,
};
},
已创建(){ 0
控制台。日志(这个。b);
this.b=' aaa '
},
模板:“Divhelloworld { { a } } { { b } }/div”,
});在Vueinstance/state.js里面,会利用proxy把每个属性都 代理一遍
常量键=对象键(数据)
constprops=vm .$选项。道具
constmethods=vm .$options.methods
leti=keys.length
而(我-){ 0
常量键=键[I]
if(propshasow(道具,钥匙)){ 0
process.env.NODE_ENV!=="生产"警告(
` dataproperty'${key} '是一个isalreadydeclaredasaprop。'
" Usepropdefaultvalueinstead改为",
伏特计
)
}elseif(!以色列(密钥)){ 0
//代理对象的属性
代理(虚拟机,` _数据`,密钥)
}
}
//观察者数据
观察(数据,真/*作为跟踪数据*/)利用defineReactive对data中的每个属性进行劫持
观察(数据,真/*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中随意改一个属性视图就会更新吗这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/148248.html