背景
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中的问题一样了,接口响应慢就正常,接口响应快表单就是空白的。
1398

被折叠的 条评论
为什么被折叠?



