You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Vuetify创建是/否单选按钮组件遇props修改报错求解

解决Vue3+Vuetify单选按钮组件的props修改报错问题

你遇到的Unexpected mutation of "selectedValue" prop报错,核心原因是Vue的单向数据流规则:子组件不能直接修改父组件传递过来的props,而你直接把selectedValue这个props绑定给了v-radio-group的v-model,v-model在用户选择时会尝试修改绑定值,这就违反了规则。

下面是两种正确的实现方式,都遵循Vue的数据流规范:

方法一:用计算属性实现自定义v-model(推荐)

这种方式利用Vue的计算属性get/set方法,把v-model的读写操作转成props读取和事件触发,是Vue3官方推荐的自定义组件v-model的写法。

子组件 YesNoRadioButton.vue

<template>
    <v-radio-group inline :label="title" v-model="localValue">
        <v-radio label="Yes" :value="true"></v-radio>
        <v-radio label="No" :value="false"></v-radio>
    </v-radio-group>
</template>

<script setup>
import { defineProps, defineEmits, computed } from 'vue'

// 定义接收的props
const props = defineProps({
    title: String,
    selectedValue: Boolean
})

// 定义要触发的事件,遵循Vue的v-model命名规范:update:xxx
const emit = defineEmits(['update:selectedValue'])

// 计算属性作为中间层,连接props和组件内部的v-model
const localValue = computed({
    // 读取时返回props的值
    get() {
        return props.selectedValue
    },
    // 修改时触发事件,通知父组件更新数据
    set(newVal) {
        emit('update:selectedValue', newVal)
    }
})
</script>

父组件 Parent.vue

直接用v-model:selectedValue语法糖绑定,它等价于:selectedValue="userAnswer"加上@update:selectedValue="userAnswer = $event":

<template>
    <YesNoRadioButton title="Are You Sure?" v-model:selectedValue="userAnswer" />
</template>

<script setup>
import YesNoRadioButton from './YesNoRadioButton.vue'
import { ref } from 'vue'

const userAnswer = ref(true);
</script>

方法二:维护本地状态+监听props同步

如果需要在子组件中对选中值做额外处理,可以用本地响应式变量,同时监听props变化保持同步,值改变时通知父组件。

子组件 YesNoRadioButton.vue

<template>
    <v-radio-group inline :label="title" v-model="localValue">
        <v-radio label="Yes" :value="true"></v-radio>
        <v-radio label="No" :value="false"></v-radio>
    </v-radio-group>
</template>

<script setup>
import { defineProps, defineEmits, ref, watch } from 'vue'

const props = defineProps({
    title: String,
    selectedValue: Boolean
})

const emit = defineEmits(['update:selectedValue'])

// 初始化本地变量为props的值
const localValue = ref(props.selectedValue)

// 监听props的变化,同步到本地变量(防止父组件修改值时子组件不同步)
watch(() => props.selectedValue, (newVal) => {
    localValue.value = newVal
})

// 监听本地变量变化,触发事件通知父组件
watch(localValue, (newVal) => {
    emit('update:selectedValue', newVal)
})
</script>

父组件写法和方法一完全一致

同样用v-model:selectedValue="userAnswer"绑定即可。

这两种方式都能避免直接修改props的问题,保证数据流单向,同时实现单选按钮的双向绑定效果。

内容的提问来源于stack exchange,提问作者user3953989

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 21:12:36