Vue3中子组件改变父组件传过来的值(props)的方法小结
作者:匹马夕阳
在 Vue 3 中,子组件改变父组件传过来的值(props)的方法主要有以下几种:通过事件发射、使用 v-model、模拟 .sync 修饰符的功能(Vue 3 中已移除),以及使用 ref 或 reactive,下面我将结合代码示例和使用场景详细讲解这些方法,需要的朋友可以参考下
1. 通过事件发射
使用场景:当子组件需要显式通知父组件更新 props 的值时,事件发射是一种常见且推荐的方式。这种方法清晰地表达了数据流向,符合 Vue 的单向数据流原则。
代码示例:
// 父组件 <template> <div> <Child :message="parentMessage" @update:message="updateMessage" /> <p>父组件值:{{ parentMessage }}</p> </div> </template> <script setup> import { ref } from 'vue'; import Child from './Child.vue'; const parentMessage = ref('Hello from parent'); const updateMessage = (newMessage) => { parentMessage.value = newMessage; }; </script> // 子组件 <template> <div> <input v-model="localMessage" @input="handleInput" /> </div> </template> <script setup> import { ref, watch } from 'vue'; const props = defineProps({ message: String }); const emit = defineEmits(['update:message']); const localMessage = ref(props.message); // 监听 props 的变化,同步本地值 watch(() => props.message, (newVal) => { localMessage.value = newVal; }); const handleInput = () => { emit('update:message', localMessage.value); }; </script>
解释:
- 父组件将
parentMessage
作为 prop 传递给子组件,并监听子组件发出的update:message
事件。 - 子组件使用
localMessage
维护本地状态,并通过watch
确保与父组件的 prop 同步。 - 当输入框的值改变时,子组件通过
emit('update:message')
通知父组件更新parentMessage
。
2. 使用 v-model
使用场景:当 prop 需要双向绑定时(例如表单输入),使用 v-model
是一种简洁的方式。它本质上是对事件发射的封装,适合需要频繁更新的场景。
代码示例:
// 父组件 <template> <div> <Child v-model:message="parentMessage" /> <p>父组件值:{{ parentMessage }}</p> </div> </template> <script setup> import { ref } from 'vue'; import Child from './Child.vue'; const parentMessage = ref('Hello from parent'); </script> // 子组件 <template> <div> <input v-model="localMessage" /> </div> </template> <script setup> import { computed } from 'vue'; const props = defineProps({ message: String }); const emit = defineEmits(['update:message']); const localMessage = computed({ get() { return props.message; }, set(value) { emit('update:message', value); } }); </script>
解释:
- 父组件使用
v-model:message
将parentMessage
绑定到子组件,实际上是监听update:message
事件并传递 prop。 - 子组件通过
computed
创建一个计算属性localMessage
,其 getter 返回 prop 值,setter 触发update:message
事件。 - 输入框的值改变时,
localMessage
的 setter 会被调用,通知父组件更新parentMessage
。
3. 模拟 .sync 修饰符的功能
使用场景:在 Vue 2 中,.sync
修饰符用于双向绑定 prop,但在 Vue 3 中被移除。可以通过显式的事件发射实现类似功能,适合需要更新特定 prop 的场景。
代码示例:
// 父组件 <template> <div> <Child :message="parentMessage" @update:message="parentMessage = $event" /> <p>父组件值:{{ parentMessage }}</p> </div> </template> <script setup> import { ref } from 'vue'; import Child from './Child.vue'; const parentMessage = ref('Hello from parent'); </script> // 子组件 <template> <div> <button @click="updateMessage">更新消息</button> </div> </template> <script setup> const props = defineProps({ message: String }); const emit = defineEmits(['update:message']); const updateMessage = () => { emit('update:message', 'New message from child'); }; </script>
解释:
- 父组件监听
update:message
事件,并直接将事件参数赋值给parentMessage
。 - 子组件在按钮点击时通过
emit
发射update:message
事件,携带新值。 - 这种模式与 Vue 2 的
.sync
类似,但需要手动实现。
4. 使用 ref 或 reactive
使用场景:当 prop 是一个对象或数组时,可以将它包装在 ref
或 reactive
中传递给子组件。子组件可以直接修改这些值,因为它们是响应式的。这种方式适合复杂数据结构的场景,但可能模糊单向数据流的边界。
代码示例:
// 父组件 <template> <div> <Child :data="parentData" /> <p>父组件值:{{ parentData.message }}</p> </div> </template> <script setup> import { reactive } from 'vue'; import Child from './Child.vue'; const parentData = reactive({ message: 'Hello from parent' }); </script> // 子组件 <template> <div> <input v-model="data.message" /> </div> </template> <script setup> const props = defineProps({ data: Object }); </script>
解释:
- 父组件使用
reactive
创建一个响应式对象parentData
,并将其作为 prop 传递给子组件。 - 子组件直接操作
data.message
,由于它是响应式对象,修改会自动反映到父组件。 - 注意:这种方式绕过了显式的事件发射,建议谨慎使用,避免数据流向不清晰。
总结
以下是各种方法的适用场景和特点:
- 事件发射:最符合 Vue 单向数据流原则,适合需要显式通知父组件的场景。
v-model
:简洁优雅,适合表单输入等双向绑定场景。- 模拟
.sync
:Vue 3 中替代.sync
的手动实现,适合特定 prop 的更新。 ref
或reactive
:适合传递对象或数组,子组件可以直接修改,但需注意数据流清晰度。
根据具体需求选择合适的方法,确保代码的可维护性和数据流的一致性。
以上就是Vue3中子组件改变父组件传过来的值(props)的方法和使用场景的详细内容,更多关于Vue3子组件改变父组件传过来的值的资料请关注脚本之家其它相关文章!