例子代码
本篇将要讲解dom diff,那么咱们结合下面的例子来进行讲解,这个例子是在上一篇文章的基础上,加了一个数据变更,也就是list的值发生了改变。html中增加了一个按钮change,通过点击change按钮来调用change函数,来改变list的值。例子位于源代码/packages/vue/examples/classic/
目录下,下面是例子的代码:
const app = Vue.createApp({
data() {
return {
list: ['a', 'b', 'c', 'd']
}
},
methods: {
change() {
this.list = ['a', 'd', 'e', 'b']
}
}
});
app.mount('#demo')
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"
content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,target-densitydpi=medium-dpi,viewport-fit=cover"
/>
<title>Vue3.js hello example</title>
<script src="../../dist/vue.global.js"></script>
</head>
<body>
<div id="demo">
<ul>
<li v-for="item in list" :key="item">
{
{item}}
</li>
</ul>
<button @click="change">change</button>
</div>
<script src="./hello.js"></script>
</body>
</html>
Vue3源码视频讲解:进入学习
源码解读
关于Vue3中数据发生变更,最终影响到页面发生变化的过程,我们本篇文章只对componentEffect以及以后的代码进行讲解,对于数据变更后,是如何执行到componentEffect函数,以及为何会执行componentEffect,后面的文章再进行讲解。
componentEffect
来看下componentEffect更新部分的代码:
// @file packages/runtime-core/src/renderer.ts
function componentEffect() {
if (!instance.isMounted) {
// first render
} else {
let {
next, bu, u, parent, vnode} = instance
let originNext = next
let vnodeHook: VNodeHook | null | undefined
if (next) {
updateComponentPreRender(instance, next, optimized)
} else {
next = vnode
}
next.el = vnode.el
// beforeUpdate hook
if (bu) {
invokeArrayFns(bu)
}
// onVnodeBeforeUpdate
if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
invokeVNodeHook(vnodeHook, parent, next, vnode)
}
const nextTree = renderComponentRoot(instance)
const prevTree = instance.subTree
instance.subTree = nextTree
if (instance.refs !== EMPTY_OBJ) {
instance.refs = {
}
}
patch(
prevTree,
nextTree,
hostParentNode(prevTree.el!)!,
getNextHostNode(prevTree),
instance,
parentSuspense,
isSVG
)
next.el