【vue2中watch与created执行时机导致的问题】

背景

vue2项目,子组件watch设置immediate监听父组件传递的props,当有值的时候更新form信息,created会对这个form有一个初始化的操作。

created() {
	this.form = createForm() // 非常复杂的表单,这里就简单伪代码表示一下
}
watch: {
	formData: {
		immediate: true,
		handler(newValue) {
			if (newValue) {
				this.form = dealForm(newValue)
			}
		}
	}
}

我在优化的时候发现接口数据已经返回了,但是表单信息回显的都是空的。

vue2中created与watch的执行时机

function initMixin (Vue) {
	Vue.prototype._init = function(options) {
		// 其它逻辑
		callHook(vm, 'beforeCreate')
		initInjections(vm)
    	initState(vm) // watch开始处理的入口点
    	initProvide(vm)
    	callHook(vm, 'created') // created生命周期开始之前的点
    	// 其它逻辑
	}
}

watch最终处理的逻辑

Vue.prototype.$watch = function (expOrFn, cb, options) {
	// 其它逻辑
	if (options.immediate) {
		cb.call(vm, watcher.value)
	}
	// 其它逻辑
}

从上面两端代码可以看出,如果设置了immediate的watch从执行时机上来看,确实是早于created的。

为什么之前没有问题呢?

首先,接口请求的触发来自另一个immediate:true的watch事件(简单理解的话也可以当作是在父组件中的created触发的)。
其次,父子组件的生命周期顺序是created(父) -> watch(子immediated:true) -> created(子)
最后,就是接口响应的速度导致了上述问题的产生

接口响应慢

watch(immediate:true) -> created -> watch(接口响应触发)

接口响应快

watch(immediate:true, 接口响应) -> created

那vue3中会出现上述的问题吗!

首先vue3中并不存在显示的created生命周期的调用

<script setup lang="ts">
const form = ref()
form.value = createForm() // 初始化的操作
watch(() => props.formData, (newValue) => {
	if (newValue) {
		form.value = dealForm(newValue) // 监听赋值的操作
	}
}, {immediate: true})
</script>

函数式写法自上而下执行,所以不会存在vue2中created于immediate:true的执行先后的问题。

那如果我就是要像下面这样子来写呢

<script setup lang="ts">
const form = ref()
watch(() => props.formData, (newValue) => {
	if (newValue) {
		form.value = dealForm(newValue) // 监听赋值的操作
	}
}, {immediate: true})
form.value = createForm() // 初始化的操作
</script>

那就与vue2中的问题一样了,接口响应慢就正常,接口响应快表单就是空白的。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值