在 Vue 3 中,除了改变 key 属性会触发组件重新渲染外,以下几种属性变化也会触发组件重新渲染:
1. 响应式数据变化
reactive 创建的响应式对象
当使用 reactive 函数创建的响应式对象的属性发生变化时,会触发依赖该数据的组件重新渲染。reactive 会将对象转换为响应式代理,任何对其属性的修改都会被 Vue 捕获并触发更新。
<template>
<div>
<p>{
{ user.name }}</p>
<button @click="changeName">Change Name</button>
</div>
</template>
<script setup>
import { reactive } from 'vue';
const user = reactive({
name: 'John'
});
const changeName = () => {
user.name = 'Jane';
};
</script>
在上述示例中,当点击按钮调用 changeName 方法修改 user.name 时,组件会重新渲染以反映新的数据。
ref 创建的响应式引用
使用 ref 创建的响应式引用,当修改其 .value 属性时,会触发依赖该 ref 的组件重新渲染。
<template>
<div>
<p>{
{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => {
count.value++;
};
</script>
这里点击按钮调用 increment 方法增加 count.value 的值,组件会重新渲染更新显示的计数。
2. 计算属性依赖的数据变化
计算属性是根据其他响应式数据计算得出的值,当计算属性所依赖的响应式数据发生变化时,计算属性会重新计算,并且使用该计算属性的组件会重新渲染。
<template>
<div>
<p>{
{ fullName }}</p>
<button @click="changeFirstName">Change First Name</button>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`;
});
const changeFirstName = () => {
firstName.value = 'Jane';
};
</script>
当点击按钮修改 firstName.value 时,fullName 计算属性会重新计算,组件会重新渲染以显示新的全名。
3. 传入组件的 props 变化
当父组件传递给子组件的 props 发生变化时,子组件会重新渲染以反映新的 props 值。
父组件
<template>
<div>
<ChildComponent :message="parentMessage" />
<button @click="changeMessage">Change Message</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentMessage = ref('Initial message');
const changeMessage = () => {
parentMessage.value = 'New message';
};
</script>
子组件(ChildComponent.vue)
<template>
<div>
<p>{
{ message }}</p>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
message: String
});
</script>
在父组件中点击按钮修改 parentMessage 时,传递给子组件的 message props 发生变化,子组件会重新渲染。
4. 监听的响应式数据变化
使用 watch 或 watchEffect 监听的响应式数据发生变化时,若在监听回调中涉及到组件状态的更新,也会触发组件重新渲染。
<template>
<div>
<p>{
{ data }}</p>
<button @click="updateData">Update Data</button>
</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue';
const originalData = ref('Initial data');
const data = ref('');
watchEffect(() => {
data.value = `Processed: ${originalData.value}`;
});
const updateData = () => {
originalData.value = 'New data';
};
</script>
当点击按钮更新 originalData 时,watchEffect 会重新执行,更新 data 的值,从而触发组件重新渲染。