【面试】涉及Vue生命周期的常见面试题:Vue获取节点、请求异步数据在哪个生命周期、获取不到异步数据dom如何解决


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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值