我正在使用这个响应式(Reactive)对象构建一个复杂的表单
const formData = reactive({})
provide('formData', formData)
在表单内,其中一个组件呈现如下:
<ComboZone
v-model:municipality_p="formData.registry.municipality"
v-model:province_p="formData.registry.province"
v-model:region_p="formData.registry.region"
/>
这是 ComboZone 渲染函数:
setup(props: any, { emit }) {
const { t } = useI18n()
const { getters } = useStore()
const municipalities = getters['registry/municipalities']
const _provinces = getters['registry/provinces']
const _regions = getters['registry/regions']
const municipality = useModelWrapper(props, emit, 'municipality_p')
const province = useModelWrapper(props, emit, 'province_p')
const region = useModelWrapper(props, emit, 'region_p')
const updateConnectedField = (key: string, collection: ComputedRef<any>) => {
if (collection.value && collection.value.length === 1) {
console.log(`update:${key} => ${collection.value[0].id}`)
emit(`update:${key}`, collection.value[0].id)
} else {
console.log(`update:${key} =>undefined`)
emit(`update:${key}`, undefined)
}
}
const provinces = computed(() => (municipality.value ? _provinces[municipality.value] : []))
const regions = computed(() => (province.value ? _regions[province.value] : []))
watch(municipality, () => updateConnectedField('province_p', provinces))
watch(province, () => updateConnectedField('region_p', regions))
return { t, municipality, province, region, municipalities, provinces, regions }
}
使用模型包装器:
import { computed, WritableComputedRef } from 'vue'
export default function useModelWrapper(props: any, emit: any, name = 'modelValue'): WritableComputedRef<any> {
return computed({
get: () => props[name],
set: (value) => {
console.log(`useModelWrapper update:${name} => ${value}`)
emit(`update:${name}`, value)
}
})
}
问题是从 useModelWrapper 发出的事件正确更新父模板中的 formData,从 watch 函数内部发出的事件延迟了一次渲染......
最佳答案
TL;DR;
使用watchEffect
而不是watch
...需要注意的是,我没有尝试重现,我的猜测是您遇到此问题是因为您使用的是延迟运行的 watch
嗯>。
惰性本质是延迟执行的结果,这可能就是您看到它在下一个周期触发的原因。
watchEffect
Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed.
watch
Compared to watchEffect, watch allows us to:
- Perform the side effect lazily;
- Be more specific about what state should trigger the watcher to re-run;
- Access both the previous and current value of the watched state.
关于vue.js - 响应式(Reactive)对象未更新 watch 发出的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65796891/