
1. vue 子组件修改 props 值
在 Vue 中,props 应被视为只读的,这是为了确保组件之间的数据独立性和可预测性。
直接修改 props 会导致难以追踪的 bug,并且违反了单向数据流的原则。
然而,有时候确实需要在子组件中基于 props 的值进行一些操作。
以下是几种常见的处理方式:
1.1. 使用局部状态
在子组件中创建一个局部状态来存储 prop 的值,并在需要时更新这个局部状态。
<template>
<div>
<p>{{ localTitle }}</p>
<button @click="updateLocalTitle">Update Title</button>
</div>
</template>
<script setup>
import { ref, watch } from "vue";
const props = defineProps({
title: String,
});
const localTitle = ref(props.title);
watch(
() => props.title,
(newVal) => {
localTitle.value = newVal;
}
);
const updateLocalTitle = () => {
localTitle.value = "New Title";
};
</script>1.2. 使用 $emit 发送事件
如果需要将子组件中的更改通知给父组件,可以使用 $emit 发送事件,让父组件来更新数据。
1.2.1. 子组件
<template>
<div>
<p>{{ title }}</p>
<button @click="updateTitle">Update Title</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from "vue";
const props = defineProps({
title: String,
});
const emit = defineEmits(["update:title"]);
const updateTitle = () => {
emit("update:title", "New Title");
};
</script>1.2.2. 父组件
<template>
<ChildComponent :title="title" @update:title="updateTitle" />
</template>
<script setup>
import { ref } from "vue";
import ChildComponent from "./ChildComponent.vue";
const title = ref("Initial Title");
const updateTitle = (newTitle) => {
title.value = newTitle;
};
</script>1.3. 使用计算属性
如果需要基于 props 的值进行一些计算,可以使用计算属性来实现。
<template>
<div>
<p>{{ computedTitle }}</p>
</div>
</template>
<script setup>
import { defineProps, computed } from "vue";
const props = defineProps({
title: String,
});
const computedTitle = computed(() => {
return `Modified: ${props.title}`;
});
</script>1.4. 使用 v-model 或自定义模型
Vue 3 支持 v-model 的自定义修饰符,可以更方便地实现双向绑定。
1.4.1. 子组件
<template>
<div>
<p>{{ title }}</p>
<input v-model="localTitle" @input="onInput" />
</div>
</template>
<script setup>
import { defineProps, defineEmits, computed } from "vue";
const props = defineProps({
modelValue: String,
});
const emit = defineEmits(["update:modelValue"]);
const localTitle = computed({
get: () => props.modelValue,
set: (value) => emit("update:modelValue", value),
});
const onInput = (event) => {
emit("update:modelValue", event.target.value);
};
</script>1.4.2. 父组件
<template>
<ChildComponent v-model:title="title" />
</template>
<script setup>
import { ref } from "vue";
import ChildComponent from "./ChildComponent.vue";
const title = ref("Initial Title");
</script>1.5. 总结
局部状态:在子组件中创建一个局部状态来存储
prop的值,并在需要时更新这个局部状态。发送事件:使用
$emit发送事件,让父组件来更新数据。计算属性:基于
props的值进行计算,使用计算属性来实现。自定义模型:使用
v-model或自定义模型实现双向绑定。
通过这些方法,可以在不直接修改 props 的情况下,实现所需的功能,同时保持组件的可维护性和可预测性。










