应用场景:
1.使用v - model
语法实现双向绑定(传值两边都不用定义方法接数据)
1.子组件

1. @update:modelValue事件是MultiSelect组件对象自带的事件

2.:options="countries"

options是MultiSelect对象自带的可以接受自定义值的属性
countries是我们封装的接受外部自定义值的属性。。引用关系有点复杂

3.代码
<template>
<div class="card flex justify-center">
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" @update:modelValue="$emit('update:selectedCountries',selectedCountries)" filter placeholder="Select Countries" display="chip" class="w-full md:w-80">
<template #option="slotProps">
<div class="flex items-center">
<div>{{ slotProps.option.name }}</div>
</div>
</template>
<template #dropdownicon>
<i class="pi pi-map" />
</template>
<template #filtericon>
<i class="pi pi-map-marker" />
</template>
<template #header>
<div class="font-medium px-3 py-2">Available Countries</div>
</template>
<template #footer>
<div class="p-3 flex justify-between">
<Button label="Add New" severity="secondary" text size="small" icon="pi pi-plus" />
<Button label="Remove All" severity="danger" text size="small" icon="pi pi-times" />
</div>
</template>
</MultiSelect>
</div>
</template>
<script setup>
import {onMounted, ref} from "vue";
// import { MultiSelect } from 'primevue/multiselect';
// import { Button } from 'primevue/button';
const props = defineProps({
// 可以添加自定义的props,例如是否禁用组件等
disabled: {
type: Boolean,
default: false
},
countries:{
type: Array,
required: true
},
selectedCountries:{
type: Array,
},
visible:{
type: Boolean,
default: false
}
});
const selectedCountries = ref([])
// 如果需要根据父组件传入的值改变内部数据结构,可以在这里处理
// 例如:
// if (props.someValue) {
// // 对countries或者selectedCountries进行操作
// }
// 可以定义内部的方法,如果需要暴露给父组件,可以使用emits
const emit = defineEmits(['update:selectedCountries']);
const emitModelValueChange = () => {
emit('update:modelValue', selectedCountries);
};
</script>
2.父组件

1.selectedCountries这个变量我们没有在父组件里定义,这个是跟在事件之后的参数,也是我们要传的值

2.selectedUsers这个变量就是父组件所属的了
3.界面效果


2.手动实现双向绑定(不使用v - model
语法的传统方式)(传值两边都需要定义方法接数据)
1.子组件


<template>
<div class="card flex justify-center">
<MultiSelect v-model="selectedCountries" :options="countries" optionLabel="name" @update:modelValue="emitModelValueChange" filter placeholder="Select Countries" display="chip" class="w-full md:w-80">
<template #option="slotProps">
<div class="flex items-center">
<div>{{ slotProps.option.name }}</div>
</div>
</template>
<template #dropdownicon>
<i class="pi pi-map" />
</template>
<template #filtericon>
<i class="pi pi-map-marker" />
</template>
<template #header>
<div class="font-medium px-3 py-2">Available Countries</div>
</template>
<template #footer>
<div class="p-3 flex justify-between">
<Button label="Add New" severity="secondary" text size="small" icon="pi pi-plus" />
<Button label="Remove All" severity="danger" text size="small" icon="pi pi-times" />
</div>
</template>
</MultiSelect>
</div>
</template>
<script setup>
import {onMounted, ref} from "vue";
// import { MultiSelect } from 'primevue/multiselect';
// import { Button } from 'primevue/button';
const props = defineProps({
// 可以添加自定义的props,例如是否禁用组件等
disabled: {
type: Boolean,
default: false
},
countries:{
type: Array,
required: true
},
selectedCountries:{
type: Array,
},
visible:{
type: Boolean,
default: false
}
});
const selectedCountries = ref([])
// 如果需要根据父组件传入的值改变内部数据结构,可以在这里处理
// 例如:
// if (props.someValue) {
// // 对countries或者selectedCountries进行操作
// }
// 可以定义内部的方法,如果需要暴露给父组件,可以使用emits
//updateSelectedCountries名字随便,爱叫是什么叫什么,只要统一就行
const emit = defineEmits(['updateSelectedCountries']);
const emitModelValueChange = () => {
emit('updateSelectedCountries', selectedCountries);
};
</script>
2.父组件


3.界面效果

3.为啥一定要传值呢?
因为不同的vue文件要传值,
那为什么不直写在一个组件里?
因为抽出一个组件后,可以复用组件,减少代码量,代码看起来整洁不少。。。。。。。