面试题答案
一键面试可能原因
- 数据不是响应式的:如果在父组件中传递的数据本身不是响应式的,例如直接定义的普通JavaScript对象或数组,而非Vue的响应式数据(通过
reactive
或ref
创建),那么即使数据发生变化,子组件通过inject
接收时也不会触发更新。 - Provide 没有更新:父组件中
provide
的值没有正确更新。如果在provide
时传递的是一个非响应式的引用,即使内部数据改变,provide
的值引用并未改变,导致子组件感知不到变化。
解决方法
- 使用响应式数据:在父组件中使用
reactive
或ref
创建响应式数据,并通过provide
传递。
<template>
<div>
<button @click="updateData">更新数据</button>
<ChildComponent />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import ChildComponent from './ChildComponent.vue';
const reactiveData = ref({ message: '初始值' });
provide('sharedData', reactiveData);
const updateData = () => {
reactiveData.value.message = '更新后的值';
};
</script>
- 确保 Provide 更新:如果传递的是复杂对象或数组,确保
provide
的引用会随着数据变化而更新。例如,使用计算属性来提供数据,这样当依赖的响应式数据变化时,计算属性会重新计算,provide
的值也会更新。
<template>
<div>
<button @click="updateData">更新数据</button>
<ChildComponent />
</div>
</template>
<script setup>
import { ref, provide, computed } from 'vue';
import ChildComponent from './ChildComponent.vue';
const internalData = ref({ message: '初始值' });
const sharedData = computed(() => internalData.value);
provide('sharedData', sharedData);
const updateData = () => {
internalData.value.message = '更新后的值';
};
</script>
子组件接收
子组件通过inject
接收数据,确保在模板中正确使用。
<template>
<div>
<p>{{ sharedData.message }}</p>
</div>
</template>
<script setup>
import { inject } from 'vue';
const sharedData = inject('sharedData');
</script>