Vue生命周期
图示:
结合代码理解:
Vue.component('Test',{
template:`
<div>
<p>{{msg}},我是test组件</p>
<button @click='msg+=" Danli"'>更新数据</button>
</div>
`,
data(){
return{
msg:'hello'
}
},
// 数据挂载: 执行data()函数,初始化变量。这个过程会触发数据挂载事件,会依次调用2个钩子函数
// 组件创建前,数据尚未挂载
beforeCreate(){
console.log('组件创建前',this.msg); //this.msg是undefined
},
// 组件创建后,数据已挂载
created(){
console.log('组件创建后',this.msg); //this.msg的值是"hello"
},
// dom挂载:把模板作为innerHTML挂载到容器元素中。会触发dom挂载事件,依次调用2个钩子函数
// dom挂载前
beforeMount() {
console.log('dom挂载前',document.getElementById("app").innerHTML); //此时组件的dom尚未挂载,此时是个虚拟dom,innerHTML为空
},
// dom挂载后
mounted() {
console.log('dom挂载后',document.getElementById("app").innerHTML); //此时组件的dom已挂载,innerHTML有值
},
// 挂载完毕后,修改data中的变量时会触发数据更新事件,依次调用2个钩子函数
// 数据更新前,数据指的是内存中的变量,
beforeUpdate() {
console.log('数据更新前',document.body.innerHTML);
},
// 数据更新后
updated() {
console.log('数据更新后',document.body.innerHTML); //如果打印的是this.msg,数据要已发生更新才能界定更新前后,此时数据已变了,更新前后打印出来的this.msg是一样的
},
// 触发组件销毁事件时,会依次调用2个钩子函数
// 组件销毁前
beforeDestroy() {
console.log('组件销毁前');
},
// 组件销毁后
destroyed() {
console.log('组件销毁后');
},
});
Vue获取节点在哪个生命周期?
由上面是图示结合代码,不难看出created阶段和mouted阶段的区别是,两个阶段数据都可获取到,但在created阶段,数据还未挂载在dom树上(即dom节点上还不能获取到数据),但在mouted阶段,数据已经完成挂载在dom树上了。
所以,Vue获取节点是在mouted完成挂载的生命周期阶段上进行的。
Vue请求异步数据是在哪个生命周期?
一般来说,在created和mouted都可以请求数据,但created阶段请求数据会更佳。原因是:created能更快获取到服务端数据,减少页面 loading 时间;因为mouted挂载阶段也是渲染dom阶段,此时若数据庞大,那么页面loading的时间会较长,用户使用受影响。
Vue获取不到异步数据dom的原因及解决方案
我们都知道在created钩子函数获取异步数据,mounted钩子函数里面获取dom节点,但是如果你获取的异步数据比mounted钩子函数还要滞后,导致异步数据的dom渲染不出来,该如何解决?
先分析一下原因:
因为created和mounted执行时,有时候会遇到异步初始化还没执行(还没执行完)。或者说当我在created/mounted里打印我想要访问的data值的时候,这个异步请求可能还没发起,还没获取到data的值。所有的钩子都只是钩子,调用一次,没有参数,不关心返回值,可以是异步函数但不等待。
那么解决方法有哪些呢?
(1)$nextTick
Vue中的nextTick涉及到Vue中DOM的异步更新,其运用的场景:
1.在vue的生命周期created()钩子函数中进行dom操作,一定要放在$nextTick()函数中执行。在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中,再在mouted阶段进行DOM操作。
2.在数据变化后要执行某个操作,而这个操作需要随着数据改变而改变DOM结构时,这个操作都是需要放在vue.$nextTick()的回调函数中。
// 以下为伪代码
methods: {
async getList() {
await getList() // 这里成功获取异步数据
this.$nextTick(() => {
// 这里面写获取异步数据dom的操作逻辑
})
}
}
(2)watch监听
在watch当中监听数据,然后在watch函数中,通过nextTick获取Dom节点
wacth: {
data () {
this.$nextTick(() => {
// 此时, 这里就可以获取到data了
}
}
(3)延时器【不推荐】
mounted() {
setTimeout(() => {
// 这里面写获取异步数据dom的操作逻辑
}, 2000);
}