sfsoul / issueslistofvue Goto Github PK
View Code? Open in Web Editor NEWVue的知识清单
Vue的知识清单
异步渲染:异步更新队列指的是当状态发生变化时,Vue 异步执行DOM的更新。
在日常项目开发中会遇到一种场景:当我们修改某个属性值后,往往想获得更新后的DOM值,但此时通过 $refs
获取到的DOM的值时更新前旧DOM的值,此时需要使用 vm.$nextTick
方法来异步获取DOM。
Vue.component('update-message', {
template: `
<button ref="message" @click="updateMessage">{{message}}</button>
`,
data () {
return {
message: 'Hello world'
}
},
methods: {
updateMessage () {
this.message = '哈哈哈';
console.log(this.$refs.message.textContent); // 打印message值为:Hello world
this.$nextTick(() => {
console.log('$nextTick', this.$refs.message.textContent); // 打印message值为:哈哈哈
})
}
}
})
从上面的 demo 可以看到,如果想要在属性值被改变后立刻获取到DOM中的新值,是需要在 vm.$nextTick
的回调中去获取的。
<template>
<div>
<div>{{test}}</div>
</div>
</template>
export default {
data () {
return {
test: 0
};
},
mounted () {
for(let i = 0; i < 1000; i++) {
this.test++;
}
}
}
如上情况:mounted
的时候属性 test
的值会被 ++ 循环执行1000次。每次++时,都会根据响应式触发 setter => Dep => Watcher => update => patch。 如果此时没有异步更新视图,那么每次++都会直接操作DOM更新视图,这是非常消耗性能的。所以Vue实现了一个 queue 队列,在下一个tick的时候会统一执行queue中Watcher的run。同时拥有相同id的Watcher不会被重复加入到该queue中去,所以不会执行1000次Watcher的run。最终更新视图只会直接将test对应的DOM的0变成1000。保证更新视图操作DOM的动作是在当前栈执行完以后下一个tick的时候调用,大大优化了性能。
假设 Vue 是同步执行DOM更新,来看看会存在什么问题?
this.message = '第一个更新';
this.message = '第二个更新';
this.message = '第三个更新';
this.message = '第四个更新';
上面代码修改了4次 message
的值,所以DOM也会更新4次,DOM的更新是十分消耗性能的。 但其实我们真正需要的也就是最后一次更新的结果(即DOM只需要更新一次),前三次的DOM更新是可以省略的。只需要等所有状态都修改好了之后再进行渲染就可以减少一些无用功。
Vue2.0 开始引入 Virtualdom
,每一次状态发生变化后,状态变化的信号会发送给组件,组件内部使用 VirtualDOM
进行计算得出需要更新的具体的DOM节点,然后对DOM进行更新操作,每次更新状态后的渲染过程需要更多的计算,而这种无用功也将浪费更多的性能,所以异步渲染变得更加至关重要。
组件内部使用 VirtualDOM
进行渲染,即组件内部其实不关心哪个状态发生了变化,它只需要计算一次就可以得知哪些节点需要更新。比如说:更改了N个状态,其实只需要发送一个信号就可以将DOM更新到最新啦。
updateStatus () {
this.name = 'zhangjing';
this.age = 27;
}
执行 updateStatus
方法,修改了2种状态,但其实Vue只渲染一次。因为 VirtualDOM
只需要一次就可以将整个组件的DOM更新到最新,它根本不会关心这个更新的信号到底是哪个具体的状态发出来的。
将渲染操作推迟到所有状态都修改完毕后进行。
只需要将渲染操作推迟到本轮事件循环的最后或者下一轮事件循环。即只需要在本轮事件循环的最后,等前面更新状态的语句都执行完之后,执行一次渲染操作,它就可以无视前面各种更新状态的语法,无论前面写了多少条更新状态的语句,只在最后渲染一次即可。将渲染推迟到本轮事件循环的最后,执行渲染的时机会比推迟到下一轮快很多,所以Vue优先将渲染操作推迟到本轮事件循环的最后,如果执行环境不支持会降级到下一轮。
所谓重复渲染指的是:一个组件属性(以
message
为例)的值被改变多次,那么会有多个对应的任务被添加到任务队列中,应该避免这样。
Vue 的变化侦测机制决定了它必然会在每次状态发生变化时都会发出渲染的信号,但Vue会在收到信号之后检查队列中是否已经存在这个任务,保证队列中不会有重复。如果队列中不存在则将渲染操作添加到队列中。 之后通过异步的方式延迟执行队列中的所有渲染的操作并清空队列,当同一轮事件循环中反复修改状态时,并不会反复向队列中添加相同的渲染操作。所以在使用Vue时,修改状态后更新DOM都是异步的。
可以理解为是在 observer(data)
方法之后执行的钩子,此时 vm.$data
下的属性都能够被访问到且都已经被数据劫持了。(被添加了 get
与 set
)
可以调用 ajax
进行一些数据资源的请求,但由于当前生命周期无法通过 $ref
去操作 DOM,
所以有关于请求后需要更新DOM值的操作都放到 mounted
生命周期中。
实例已经挂载完成,适合去做需要根据获取的数据并去初始化DOM的操作。
此时DOM中的值并未发生改变,原因在于:虚拟DOM还未重新渲染,且未开始应用更新。 适合在此生命周期中进一步地更改
状态,这不会触发附加的重渲染过程。
可以执行依赖于 DOM 的操作。多数情况下应避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务端渲染
期间不被调用。
从下方截图可以很明显的看出来,beforeUpdate
与 updated
钩子函数的区别在于:DOM节点的值有没有更新。
原因就在于:虚拟DOM的重新渲染以及更新应用的时机是在 beforeUpdate
钩子之后才进行的。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.