前言
在做黑马的vue大事件项目的时候,遇到了vue3当中的父子通信使用双向绑定,以此记录总结一下
场景
因为文章分类这个选择器的内容,是可以自定义添加的,不固定的,所以需要像后端动态请求渲染option,为了便于维护,直接拆分成一个小组件 ChannelSelect.vue
源码
这是封装的ChannelSelect.vue的源码
<script setup>
import { artGetChannelsService } from '@/api/article'
import { ref } from 'vue'
defineProps({
modelValue: {
type: [Number, String]
}
})
const emit = defineEmits(['update:modelValue'])
const channelList = ref([])
const getChannelList = async () => {
const res = await artGetChannelsService()
channelList.value = res.data.data
}
getChannelList()
</script>
<template>
<el-select
:modelValue="modelValue"
@update:modelValue="emit('update:modelValue', $event)"
style="width: 180px"
>
<el-option
v-for="channel in channelList"
:key="channel.id"
:label="channel.cate_name"
:value="channel.id"
></el-option>
</el-select>
</template>
这是父组件中提到的用法
<el-form-item label="文章分类:">
<channel-select v-model="params.cate_id"></channel-select>
</el-form-item>
分析
首先vue2当中要实现父子组件的双向绑定
正常来说父子通信的双向绑定
父组件中
<Son :list="list" @del="handerDel"></Son >
// 在methods中
handerDel(id) {
}
子组件中
// 接收父组件的值 渲染到页面上
prop: { list }
<span> list </span>
// 自定义事件
< button @click="del(id)">
// 在methods中定义
del(id) {
this.$emit("del", id);
}
但是如果是对于input输入框的父子通信,由于input中的v-model就包含了 :value和@input,相当于已经自定义事件,所以就不需要声明
例如父组件中
<Son :list="list"></Son >
在子组件中的input输入框中就需要
接收父组件中的数据:
prop: { list }
<input v-model="todoName"/>
所以说
Vue2 =>v-model:value和 @input 的简写
但是在vue3中
Vue3 =>v-model :modelValue 和 @update:modelValue 的简写
父组件中
v-model是v-model :modelValue的简写 相当于往子组件传入一个modelValue的简写的值
自定义接收的事件就叫做@update:modelValue
<channel-select v-model="params.cate_id"></channel-select>
子组件中
// 接收父组件的值
defineProps({
modelValue: {
type: [Number, String]
}
})
// 自定义事件update:modelValue
const emit = defineEmits(['update:modelValue'])
// 在页面中
<el-select
// 绑定父组件传过来的数据
:modelValue="modelValue"
// 自定义数据传回去
@update:modelValue="emit('update:modelValue', $event)"
style="width: 180px"
>
一点小小总结,如有错误,希望大佬可以指正纠错