vue3 使用v-model开发弹窗组件
我又来写这方面的东西了说实话 我用这个少 想着多记录一下
子组件
<template><el-dialog v-model="promiseVisible" title="修改起始上架章节" width="700px"><!-- 添加作品弹窗内容保持不变 --><div class="diolag-applyUp-container"><div class="item"><div class="title">分卷</div><div class="value"><el-select v-model="volumeValue" @change="volumeChange" placeholder="请选择分卷"><el-option v-for="item in volumeList" :key="item.volumeID" :label="item.volumeName" :value="item.volumeID" /></el-select></div></div><div class="item"><div class="title">章节</div><div class="value"><el-select v-model="chacaterValue" filterable :filter-method="filterMethod" :disabled="!volumeValue" placeholder="请选择章节"><el-option v-for="item in filteredOptions" :key="item.chapterID" :label="item.chapterName" :value="item.chapterID" /></el-select></div></div></div><template #footer><div class="dialog-footer"><el-button @click="onCancelDiolag">取消</el-button><el-button type="primary" @click="onConfirm"> 确定修改 </el-button></div></template></el-dialog>
</template><script setup>
import { ref, toRefs, onMounted, watch } from 'vue';
import { useChacaterApi } from '/@/api/chacater/index';
import { ElMessage } from 'element-plus';const { getVolumeList, getChacaterList } = useChacaterApi();
const volumeValue = ref('');
const chacaterValue = ref('');
const volumeList = ref([]);
const chacaterList = ref([]);// Props
const props = defineProps({// 控制弹窗显示modelValue: {type: Boolean,default: false,},novelID: {type: Number,required: true,},
});const filteredOptions = ref([]); // 过滤后显示的选项列表
// 搜索过滤方法
const filterMethod = (query) => {if (query) {// 将输入和标签都转为小写进行不区分大小写的匹配filteredOptions.value = chacaterList.value.filter((item) => item.chapterName.toLowerCase().includes(query.toLowerCase()));} else {// 输入为空时,重置为全部选项filteredOptions.value = [...chacaterList.value];}
};
const emit = defineEmits(['update:modelValue', 'submit']);const { novelID } = toRefs(props);
const promiseVisible = ref(false);// 监听外部显示状态
watch(() => props.modelValue,(newVal) => {promiseVisible.value = newVal;if (newVal) {GetvolumeList();}}
);// 监听内部弹窗状态,同步到父组件
watch(() => promiseVisible.value,(newVal) => {emit('update:modelValue', newVal);if (!newVal) {// 当弹窗关闭时,重置表单resetForm();}}
);const volumeChange = (e) => {console.log(e, 'e');chacaterListByid(e);
};const onCancelDiolag = () => {promiseVisible.value = false;
};const onConfirm = () => {// 这里添加确认逻辑if (!volumeValue.value || !chacaterValue.value) {ElMessage.warning('请选择分卷和章节');return;}// 提交数据给父组件emit('submit', {volumeID: volumeValue.value,chapterID: chacaterValue.value,});// 关闭弹窗promiseVisible.value = false;
};// 重置表单
const resetForm = () => {volumeValue.value = '';chacaterValue.value = '';volumeList.value = [];chacaterList.value = [];
};onMounted(() => {// GetvolumeList();
});//获取分卷
const GetvolumeList = async () => {try {const res = await getVolumeList({novelID: novelID.value,});if (res.code == 200) {volumeList.value = res.data.infos;console.log(res, 'res');} else {ElMessage.error(res.message);volumeList.value = [];}} catch (error) {ElMessage.error('获取书籍分卷失败~');}
};//根据分卷的id 获取对应的章节
const chacaterListByid = async (volumeID) => {try {const res = await getChacaterList({novelID: novelID.value,volumeID,type: 1,sortord: 1,pageIndex: 1,pageSize: 0,});if (res.code == 200) {chacaterList.value = res.data.infos;filteredOptions.value = [...res.data.infos];} else {chacaterList.value = [];ElMessage.error(res.message);}} catch (error) {ElMessage.error('获取图书章节失败~');}
};
</script><style scoped lang="less">
.diolag-applyUp-container {.item {display: flex;align-items: center;.title {width: 80px;}.value {flex: 1;}&:nth-child(n + 2) {margin-top: 15px;}}
}
</style>
这是一个弹窗的组件 很多地方使用的同一个组件 所以我写了一个固定的组件
这个就是v-model绑定 双向。
跟普通的传递标识说一样吧 也一样 说不一样吧 的确有不同的地方
父组件使用
<ApplyModal v-model="showApplyModal" @submit="ApplySUbmit" :novelID="userInfos.novel.novelID"></ApplyModal>
其实也简单
