父子组件传递双向绑定对象

父组件向子组件传递子组件需要双向绑定对象

问题场景

子组件表单素绑定了一个v-model对象,这个对象需要从父组件传入,父组件在传入这个参数后,页面上操作表单元素报错。比如说一个单选按钮的子组件,双向绑定的对象由父组件传入,页面上点击单选按钮选择状态不能保持且控制台报错:
img

子组件ButtonGroup:

<template>
    <div>
        <Card :label="label" icon>
            <RRadioGroup class="flex-wrap grid" v-model:modelValue="bindModel" button size="middle">
                <div class="grid-column" v-for="item in products" :key="item.type">
                    <RRadio block :label="item.type" name="radarRadioGroup">{{ item.name }}
                    </RRadio>
                </div>
            </RRadioGroup>

        </Card>
    </div>
</template>

<script lang="ts">
import {
    computed,
    defineComponent,
    PropType,
    watch,
    ref,
    onMounted,
    reactive,
    toRef,
    toRefs,
} from 'vue';
import RCheckbox from '@/components/common/Checkbox/checkbox.vue';



export default defineComponent({
    name: 'ButtonGroup',
    components: { RCheckbox },
    props: {
        products: {
            type: Array as PropType<any>,
            default: [],
        },
        bindModel: {
            type: String,
            default: '',
        },
        label: {
            type: String,
            default: '',
        },
    },
    setup(props) {
       
        return {};
    },
});
</script>

<style lang="scss" scoped>
@import '@/styles/modules/index.scss';

</style>

<template>
    <div>
        <Card label="多源观测设备" icon>
            <ButtonGroup :bind-model="rainModel" :products="rain_data.options"></ButtonGroup>

        </Card>
    </div>
</template>

<script lang="ts">
import {
    computed,
    defineComponent,
    PropType,
    watch,
    ref,
    onMounted,
} from 'vue';


export default defineComponent({
    name: 'Echo',
    components: { RCheckbox, ButtonGroup },
    computed: {
        ...mapState(useProductStore, {
            // testRadars: (store) => store.products.filter((item) => item.band === 'X'),
            XCRProfiles: (store) => {
                const menus = store.products.filter(
                    (item) => item.menuGroup === 'XCRProfile',
                );
                return menus;
            },
        }),
    },
    props: {
        // label: {
        //     type: String,
        //     default: '',
        // },
        // products: {
        //     type: Array as PropType<any>,
        //     default: [],
        // },
        // type: {
        //     type: String,
        //     default: '',
        // },
        // step: {
        //     type: Number,
        //     default: 1,
        // },
        // model: {
        //     type: String,
        //     default: '',
        // },
        // bilinear: {
        //     type: Boolean,
        //     default: false,
        // },
    },
    setup(props) {
        const model = ref('')
        
        return {
            model
        };
    },
});
</script>

<style lang="scss" scoped>
@import '@/styles/modules/index.scss';

</style>

问题分析:由于子组件的v-model双向绑定的响应式变量是父组件传入的,子组件不能直接使用,需要把这个双向绑定的响应式变量转换成子组件的双向绑定的响应式变量。把父组件传入的变量在子组件中用reactive套一层(用toRef套不行!),修改后子组件代码如下:

<template>
    <div>
        <Card :label="label" icon>
            <RRadioGroup class="flex-wrap grid" v-model:modelValue="model" button size="middle">
                <div class="grid-column" v-for="item in products" :key="item.type">
                    <RRadio block :label="item.type" name="radarRadioGroup">{{ item.name }}
                    </RRadio>
                </div>
            </RRadioGroup>

        </Card>
    </div>
</template>

<script lang="ts">
import {
    computed,
    defineComponent,
    PropType,
    watch,
    ref,
    onMounted,
    reactive,
    toRef,
    toRefs,
} from 'vue';
import RCheckbox from '@/components/common/Checkbox/checkbox.vue';



export default defineComponent({
    name: 'ButtonGroup',
    components: { RCheckbox },
    props: {
        products: {
            type: Array as PropType<any>,
            default: [],
        },
        bindModel: {
            type: String,
            default: '',
        },
        label: {
            type: String,
            default: '',
        },
    },
    setup(props) {
        const  v = reactive({
            model:props.bindModel
        })
        // const model = toRef(props,"bindModel")



        return {
            ...toRefs(v)
        };
    },
});
</script>

<style lang="scss" scoped>
@import '@/styles/modules/index.scss';
</style>
posted @ 2025-08-29 11:01  南宫影  阅读(2)  评论(0)    收藏  举报