开发过程中有时会需要给父子组件数据双向绑定。在这里记录一下,废话不多说 ,上代码
<template>
<el-select v-model="currentValue" @change="change">
<el-option v-for="opt in options" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</template>
<script setup lang="ts">
import { onMounted, ref, toRefs } from 'vue';
import { knowledgeDict } from '/@/api/knowledgeBase/common';
import { STATUS_CODE } from '/@/enum/global';
interface Props {
dataCategoryId: number;
modelValue: any; // 父组件传过来的值
}
const props = defineProps<Props>();
const emits = defineEmits(['update:modelValue']);
const { dataCategoryId } = toRefs(props);
const currentValue = ref<any>(); // 子组件中设置一个变量,否则select的v-model不生效。之所以不用modelValue,是因为在vue中父组件传过来的是一个只读的,不允许修改
const options = ref<SelectOptionType[]>();
const change = (value: any) => {
emits('update:modelValue', value); // 通过 update:modelValue 触发父组件的事件,将修改后的值传递给父组件,在父组件中进行修改。
};
const getOptions = async () => {
const { code, data } = await knowledgeDict({ category: dataCategoryId.value });
if (code === STATUS_CODE.SUCCESS && data[dataCategoryId.value]) {
options.value = data[dataCategoryId.value].map((item: { value: any; code: any }) => ({
label: item.value,
value: item.code,
}));
}
};
onMounted(() => {
getOptions();
});
</script>
<style lang="scss" scoped></style>
在父组件中调用
<template v-for="(item, index) in label" >
<SelectCom
:key="index"
:modelValue="data[item.prop]"
:dataCategoryId="item.dataCategoryId"
@update:modelValue="(value) => (data[item.prop] = value)"
></SelectCom>
</template>
代码中出现的 STATUS_CODE 等是系统定义的一些常量,大家根据自己系统的代码进行修改即可。
注:vue官网中对这部分内容也做了详细介绍,除了我使用的这种方法外,还可以使用vue提供的defineModel这个便利宏来实现。