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>

其实也简单

相关推荐
web加加2 小时前
vue3 +vite项目页面防f12,防打开控制台
前端·javascript·vue.js
遥遥晚风点点3 小时前
Spark导出数据文件到HDFS
前端·javascript·ajax
克里斯蒂亚诺更新4 小时前
微信小程序 点击某个marker改变其大小
开发语言·前端·javascript
KYumii4 小时前
智慧判官-分布式编程评测平台
vue.js·spring boot·分布式·spring cloud·java-rabbitmq
长空任鸟飞_阿康5 小时前
AI 多模态全栈应用项目描述
前端·vue.js·人工智能·node.js·语音识别
顾安r5 小时前
11.14 脚本网页 迷宫逃离
服务器·javascript·游戏·flask·html
顾安r6 小时前
11.14 脚本网页游戏 猜黑红
前端·javascript·游戏·flask·html
码码哈哈0.06 小时前
Vue 3 + Vite 集成 Spring Boot 完整部署指南 - 前后端一体化打包方案
前端·vue.js·spring boot
@菜菜_达6 小时前
interact.js 前端拖拽插件
开发语言·前端·javascript