vue 组件响应式更新原理 All In One
vue 组件响应式更新原理 All In One
vue 组件更新原理 / vue 组件响应式原理
- 依赖收集
- 监听,通知
- 重绘
https://cn.vuejs.org/v2/guide/reactivity.html#如何追踪变化
对象
https://cn.vuejs.org/v2/guide/reactivity.html#对于对象
var vm = new Vue({
data: {
a: 1
}
});
// `vm.a` 是响应式的
vm.b = 2;
// `vm.b` 是非响应式的
// Vue.set(vm.someObject, 'b', 2)
this.$set(this.someObject, "b", 2);
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 });
数组
https://cn.vuejs.org/v2/guide/reactivity.html#对于数组
var vm = new Vue({
data: {
items: ["a", "b", "c"]
}
});
vm.items[1] = "x"; // 不是响应性的
vm.items.length = 2; // 不是响应性的
// Vue.set
Vue.set(vm.items, indexOfItem, newValue);
vm.$set(vm.items, indexOfItem, newValue);
// Array.prototype.splice 就地复用
vm.items.splice(indexOfItem, 1, newValue);
vm.items.splice(newLength);
$nextTick
Vue Diff 算法 / virtual DOM
虚拟 DOM / VNode 树
https://cn.vuejs.org/v2/guide/render-function.html#节点、树以及虚拟-DOM
https://cn.vuejs.org/v2/guide/syntax.html#
虚拟 DOM Diff 算法 / 就地复用
key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。
如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。
而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
https://cn.vuejs.org/v2/api/#key
注意,updated 不会保证所有的子组件也都被重新渲染完毕。如果你希望等到整个视图都渲染完毕,可以在 updated 里使用 vm.$nextTick:
updated: function () {
this.$nextTick(function () {
// 仅在整个视图都被重新渲染之后才会运行的代码
})
}
https://cn.vuejs.org/v2/api/#updated
生命周期图示
https://cn.vuejs.org/v2/guide/instance.html#生命周期图示
DOM tree
https://javascript.info/dom-nodes
render function & $slots
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)
},
props: {
level: {
type: Number,
required: true
}
}
})
https://cn.vuejs.org/v2/api/#vm-slots
demo
methods: {
// 1. 通过调用父组件的方法,更改 props ✅
updateForm(obj = {}, index = 0) {
// this.formData.creativeList[index] = obj;
// console.log("update data", obj, index);
if (!this.formData.creativeList[index]) {
this.formData.creativeList[index] = {};
} else {
// ✅对象属性合并
obj = Object.assign({}, this.formData.creativeList[index], obj);
// obj = {
// ...this.formData.creativeList[index],
// ...obj,
// };
}
// ❌ 非响应式,数组
// Object.assign(this.formData.creativeList[index], obj);
// ✅ 响应式,数组, this.$set
// this.$set(this.formData.creativeList, index, obj);
// ✅ 响应式,数组,Array.splice 就地复用
this.formData.creativeList.splice(
this.formData.creativeList[index],
1,
obj
);
},
// 2. 通过 Array[0].Object 对象引用,直接修改 props 的 formData 属性? 不推荐 ❌
},
refs
https://cn.vuejs.org/v2/guide/reactivity.html
https://codesandbox.io/s/shit-vue-docs-4xwiu?file=/readme.md:19-29
in-place 就地复用
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
https://www.cnblogs.com/xgqfrms/p/10711789.html
https://stackoverflow.com/questions/958908/how-do-you-reverse-a-string-in-place-in-javascript
©xgqfrms 2012-2020
www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/14817132.html
未经授权禁止转载,违者必究!