Vue3父组件异步获取数据,子组件未接收到数据
在Vue开发过程中,特别是刚上手不久的同学,很容易遇到,父组件异步获取数据传给子组件,但子组件却没有接收到的问题,如下图所示主要原因在于,当父组件异步获取数据的同时,可能耗时较长,获取到数据再传给子组件时,子组件已经渲染完毕。
·
业务场景
在Vue开发过程中,特别是刚上手不久的同学,很容易遇到,父组件异步获取数据传给子组件,但子组件却没有接收到的问题,如下图所示
主要原因在于,当父组件异步获取数据的同时,可能耗时较长,获取到数据再传给子组件时,子组件已经渲染完毕
解决方法
父组件异步获取数据:
const data = ref<string>('')
setTimeout(() => {
data.value = '我是父组件异步获取的数据'
}, 2000)
传给子组件:
<son :data="data" />
子组件通过defineProps接收,并通过watch监听父组件传过来的值:
const props = defineProps<{
data: string
}>()
watch(
() => props.data, //监听
() => {
console.log(`子组件接收父组件传入的数据`, props.data)
}
)
子组件将值进行渲染:
<div>{{ props.data }}</div>
最后就成功啦:
Vue3 Watch进一步讲解
watch用法
在 Vue 3 的组合式 API 写法, watch 是一个可以接受 3 个参数的函数
watch(
source, // 必传,要监听的数据源
callback, // 必传,监听到变化后要执行的回调函数
options // 可选,一些监听选项
)
基础用法
watch(data, () => {
console.log('监听整个 data', data)
})
也可以监听对象里面的某个值
watch(
// 数据源,getter 形式
() => data.name,
// 回调函数 callback
(newValue, oldValue) => {
console.log('只监听 name 的变化 ', data.name)
console.log('打印变化前后的值', { oldValue, newValue })
}
)
批量监听
watch(
[message, index],
// 回调的入参也变成了数组,每个数组里面的顺序和数据源数组排序一致
([newMessage, newIndex], [oldMessage, oldIndex]) => {
console.log('message 的变化', { newMessage, oldMessage })
console.log('index 的变化', { newIndex, oldIndex })
}
)
watch监听选项
deep选项:
// 定义一个响应式数据,注意我是用的 ref 来定义
const nums = ref<number[]>([])
// 2s后给这个数组添加项目
setTimeout(() => {
nums.value.push(1)
// 可以打印一下,确保数据确实变化了
console.log('修改后', nums.value)
}, 2000)
// 但是这个 watch 不会按预期执行
watch(
nums,
// 这里的 callback 不会被触发
() => {
console.log('触发监听', nums.value)
},
// 因为关闭了 deep
{
deep: false,
}
immediate选项:
watch 默认是惰性的,也就是只有当被监听的数据源发生变化时才执行回调
// 这个时候不会触发 watch 的回调
const message = ref<string>('')
// 2s后改变数据
setTimeout(() => {
// 来到这里才会触发 watch 的回调
message.value = 'Hello World!'
}, 2000)
watch(message, () => {
console.log('触发监听', message.value)
})
watchEffect
如果一个函数里包含了多个需要监听的数据,一个一个数据去监听太麻烦了,在 Vue 3 ,你可以直接使用 watchEffect API 来简化你的操作
// 单独定义两个数据,后面用来分开改变数值
const name = ref<string>('Petter');
const age = ref<number>(18);
// 定义一个调用这两个数据的函数
const getUserInfo = (): void => {
console.log({
name: name.value,
age: age.value
});
}
// 2s后改变第一个数据
setTimeout(() => {
name.value = 'Tom';
}, 2000);
// 4s后改变第二个数据
setTimeout(() => {
age.value = 20;
}, 4000);
// 直接监听调用函数,在每个数据产生变化的时候,它都会自动执行
watchEffect(getUserInfo);
watchEffect和 watch 的区别:
- watch 可以访问侦听状态变化前后的值,而 watchEffect 没有
- watch 是在属性改变的时候才执行,而watchEffect 则默认会执行一次,然后在属性改变的时候也会执行
更多推荐
已为社区贡献7条内容
所有评论(0)