vue2+elementui,动态生成的表单校验

news2024/11/24 19:07:03

话不多,先上一段视频,看看是不是你们需要的效果 

elementui动态生成表单校验

附上代码

<template>
	<div class="home">
		<div class="home-box">
			<!-- <menuHtml></menuHtml> -->
			<div class="home-div">
				<div style="margin-top: 20px;display:flex;justify-content: space-between;">
					<div>
						<span class="blueBlock">&nbsp;</span>
						<span class="title">问卷编辑</span>
					</div>
					<div>
						<span style="color:#F56C6C;">问卷编辑完成,千万不要忘记点击保存哦<i class="el-icon-thumb"
								style="transform: rotate(90deg);"></i></span>
						<el-button type="primary" plain size="mini" icon="el-icon-s-claim"
							@click="save('form')">保存</el-button>
					</div>
				</div>
				<el-form abel-position='top' :model="form" ref="form">
					<div class="content">
						<div class="content-top">
							<el-form-item prop="title" :rules="{required: true, message: '  ', trigger: 'blur' }">
								<el-input size="small" v-model="form.title" placeholder="请输入问卷标题">
									<el-button slot="append" @click="addQuestion()" icon="el-icon-circle-plus-outline">
										添加问题
									</el-button>
								</el-input>
							</el-form-item>
						</div>
						<div class="content-box">
							<div class="content-center" v-for="(question,index) in form.questionList">
								<el-form-item>
									<el-radio v-model="question.type" :label="1">单选</el-radio>
									<el-radio v-model="question.type" :label="2">多选</el-radio>
									<el-radio v-model="question.type" :label="3">开放式问题</el-radio>
								</el-form-item>
								<el-form-item class="question" :prop="'questionList.'+index+'.name'"
									:rules="{required: true, message: '', trigger: 'blur' }">
									<el-input placeholder="请输入问题" size="small" v-model="question.name">
										<template slot="prepend">Q{{index+1}}.</template>
									</el-input>
									<div @click="delQuestion(index)">
										<i class="el-icon-delete-solid"></i>
										<span>删除</span>
									</div>
								</el-form-item>
								<el-form-item v-if="question.type==3" :prop="'questionList.'+index+'.answer2'"
									:rules="{required: true, message: '  ', trigger: 'blur' }">
									<el-input type="textarea" :rows="4" placeholder="请输入答案" v-model="question.answer2"
										resize="none"></el-input>
								</el-form-item>
								<el-form-item v-else>
									<div class="answer" v-for="(answer,index1) in question.answerList">
										<el-form-item :prop="'questionList.'+index+'.answerList.'+index1+'.name'" :rules="{required: true, message: '  ', trigger: 'blur' }">
											<el-input size="small" placeholder="请输入答案" v-model="answer.name">
												<template slot="prepend">{{chars[index1]}}.</template>
											</el-input>
										</el-form-item>
										<div class="answer-right">
											<el-button @click="delAnswer(index,index1,question)" size="mini"
												icon="el-icon-minus" circle type="danger" plain></el-button>
											<el-button v-if="question.answerList.length==index1+1"
												@click="addAnswer(index,index1)" size="mini" icon="el-icon-plus" circle
												type="primary" plain></el-button>
										</div>
									</div>

								</el-form-item>
								<el-form-item label="正确答案" v-if="question.type==1" 
								 :prop="'questionList.'+index+'.answer'" :rules="{required: true, message: '  ', trigger: 'blur' }">
									<el-select size="mini" v-model="question.answer" placeholder="请选择答案">
										<el-option v-for="(item,index2) in question.answerList" :key="index2"
											:label="chars[index2]" :value="index2">
										</el-option>
									</el-select>

								</el-form-item>
								<el-form-item label="正确答案" v-if="question.type==2"
								:prop="'questionList.'+index+'.answer1'" :rules="{required: true, message: '  ', trigger: 'blur' }">
									<el-select size="mini" multiple v-model="question.answer1" placeholder="请选择答案">
										<el-option v-for="(item,index2) in question.answerList" :key="index2"
											:label="chars[index2]" :value="index2">
										</el-option>
									</el-select>
								</el-form-item>


							</div>
						</div>
					</div>
				</el-form>
			</div>

		</div>
	</div>
</template>

<script>
	// import menuHtml from '../../../view/leaf-content/menuHtml.vue'
	export default {
		name: 'addWjByTeacher',
		components: {
			// menuHtml,
		},
		props: [],
		data() {
			return {
				chars: ['A', 'B', 'C', 'D'],
				form: {
					title: '',
					// questionList: [],
					questionList: [{
						type: 1, //1.单选,2:多选,3开放式问题
						questionTitle: '',
						answerList: [{}],
						answer: '', //单选答案
						answer1: [], //多选答案
						answer2: '', //开放式问题答案
					}, {
						type: 2, //1.单选,2:多选,3开放式问题
						questionTitle: '',
						answerList: [{}],
						answer: '',
						answer1: [],
						answer2: '',
					}, {
						type: 3, //1.单选,2:多选,3开放式问题
						questionTitle: '',
						answerList: [{}],
						answer: '',
						answer1: [],
						answer2: '',
					}],
				}
			}

		},
		methods: {
			addQuestion() { //添加问题
				this.form.questionList.push({
					type: 1, //1.单选,2:多选,3开放式问题
					questionTitle: '',
					answerList: [{}],
					answer: '',
				});
			},
			delQuestion(index) { //删除问题
				this.form.questionList.splice(index, 1);
			},
			addAnswer(questionIndex, answerIndex) { //添加答案
				console.log(answerIndex);
				if (answerIndex < 3) {
					this.form.questionList[questionIndex].answerList.push({});
				}
			},
			delAnswer(questionIndex, answerIndex, question) { //删除答案
				if (answerIndex >= 1) {
					this.form.questionList[questionIndex].answerList.splice(answerIndex, 1);
				}
				//判断单选还是多选,要一同清空掉答案
				if (question.type == 1) {
					// this.form.questionList[questionIndex].answerList
					question.answer = "";
				} else if (question.type == 2) {
					question.answer1 = "";
				}
			},
			save(formName) { //保存问题
				this.$refs[formName].validate((valid) => {
					if (valid) {
						alert('submit!');
					} else {
						console.log('error submit!!');
						return false;
					}
				});
			},
		},
		mounted() {

		},
		destroyed() {

		},
		created() {

		}

	}
</script>

<style scoped>
	@import '../../../../assets/css/screenBase.css';

	.home {
		margin-top: 100px;
	}

	.home-box {
		margin: 0 auto;
		display: flex;
		align-items: flex-start;
		width: 1000px;
		justify-content: center
	}

	.home-div {
		width: 1000px;
		height: 650px;
		background-color: #fff;
		border-radius: 10px;
		/* 	padding-top: 20px; */
		padding-right: 40px;
		padding-left: 40px;

		/* padding-bottom: 20px; */
	}

	.blueBlock {
		height: 8px;
		width: 2px;
		background-color: #226cd3;
		margin-right: 10px;
	}

	.title {
		font-weight: 600;
		font-size: 24px;
	}

	.content {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		width: 900px;

	}

	.el-form-item {
		margin-bottom: 0px;
	}

	.content-top {

		margin-top: 20px;
		display: flex;
	}

	.content-top /deep/ input {
		width: 800px;
	}

	.content-center {
		width: 880px;
		background-color: #e9f5f136;
		border-radius: 10px;
		margin-top: 5px;
		padding: 10px;
		box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
	}

	.content-box {
		/* margin-top: 20px; */
		padding: 5px;
		height: 500px;
		overflow: hidden;
		overflow-y: auto;

	}

	/deep/.el-form--label-top .el-form-item__label {
		padding: 0px;
	}

	.btn {
		margin-top: 40px;
		text-align: center;
	}

	.question {}

	.question /deep/.el-form-item__content {
		display: flex;
		align-items: flex-start;
		justify-content: flex-start;
	}

	/* .answer /deep/.el-form-item__content {
		display: flex;
		align-items: flex-start;
		justify-content: flex-start;
		width: 750px;
	} */

	.question /deep/ input {
		width: 550px;
	}

	.question div {
		width: 100px;
		text-align: center;
	}

	.question i {
		color: #F56C6C;
		margin-right: 5px;
	}

	.answer /deep/ .el-input-group--prepend {
		width: 500px;
	}

	.answer /deep/ .el-input__inner {
		width: 500px;
	}

	.answer-right {
		width: 100px;
		display: flex;
		align-items: flex-start;
		/* text-align: center; */
	}

	.answer-right span {
		width: 25px;
		height: 25px;
		line-height: 25px;
		text-align: center;
		display: inline-block;
		background: #FFFFFF;
		border-radius: 8px;
		border: 1px solid #CCD3E7;

	}

	.answer-right i {
		color: #000;
		font-weight: 600;
	}

	.answer {
		display: flex;
		align-items: center;
	}
</style>

最主要的地方,因为我是双层的循环遍历,先看第一层的注意地方

最最最最最最最主要的地方,这是第二层的地方

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1797628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用2个手机文件恢复工具,轻松找回文件

在这个智能手机横行的时代&#xff0c;手机已经成为我们生活中不可或缺的一部分。然而&#xff0c;就像生活中的一切事物一样&#xff0c;手机也有可能出现意外&#xff0c;比如文件丢失。这就像是你在超市购物&#xff0c;结果发现钱包不见了&#xff0c;那种感觉真是让人抓狂…

CTFHUB-技能树-web-web前置技能-HTTP协议全

目录 1.请求方式 2.302跳转 3.Cookie 4.基础认证 5.响应包源码 1.请求方式 curl -v -X http://challenge-3022c877a8dcedeb.sandbox.ctfhub.com:10800/index.php 2.302跳转 参考链接&#xff1a;http://t.csdnimg.cn/aqdNG 301——永久性重定向。该状态码表示请求的资源已…

攻防世界---misc---津门杯2021-m1

1、题目描述&#xff0c;下载附件是一张bmp格式的图片 2、直觉告诉我这和图片的颜色通道有关 3、于是我就尝试用stegslove打开图片 4、将颜色通道都改为0&#xff0c;点击preview 5、然后发现一串base64编码 6、解码得flag flag{l5DGqF1pPzOb2LU919LMaBYS5B1G01FD}

MyEclipse新手使用介绍

目录 1.MyEclipse诞生背景 2.作用 3.版本历史 4.优缺点 5.应用场景 6.如何使用 6.1.下载与安装 6.2.MyEclipse 菜单及其菜单项 7.创建和发布一个 Java 程序 7.1.创建 Java 程序 7.2.发布 Java 程序 8.示例 8.1. Hello World 示例 8.2. 简单Spring Boot 应用 8.3…

行心科技中禄松波携手,开启智能健康新时代

在2024年第34届健博会暨中国大健康产业文化节的盛大舞台上&#xff0c;广州市行心信息科技有限公司&#xff08;以下简称“行心科技”&#xff09;与浙江中禄松波生物工程有限公司&#xff08;以下简称“中禄松波”&#xff09;宣布达成战略合作&#xff0c;共同推动医康养产业…

【JavaEE精炼宝库】多线程(4)深度理解死锁、内存可见性、volatile关键字、wait、notify

目录 一、死锁 1.1 出现死锁的常见场景&#xff1a; 1.2 产生死锁的后果&#xff1a; 1.3 如何避免死锁&#xff1a; 二、内存可见性 2.1 由内存可见性产生的经典案例&#xff1a; 2.2 volatile 关键字&#xff1a; 2.2.1 volatile 用法&#xff1a; 2.2.2 volatile 不…

2024 年最新商家转账到零钱功能申请问题集中解答

鉴于诸多商户在申请商家转账到零钱时受到过时、错误经验文章的误导&#xff0c;基于我们数千次成功开通商家转账到零钱功能的丰富经验&#xff0c;特整理此篇文章&#xff0c;以期对新商户开通微信支付的商家转账到零钱功能提供有益帮助。以下将针对商家转账到零钱功能申请前、…

阿里云sls 采集日志安装记录

参考阿里云给的安装文档 阿里云安装Logtail组件 注意这里&#xff0c;选择地域&#xff0c;是中国地域选中国&#xff0c;海外选海外即可 按照文档继续下去 修改配置文件./alibaba-cloud-log-all/values.yaml 所有的操作完成后&#xff0c;去控制台配置 以上操作的前提是…

多目标应用:MOHHO多目标哈里斯鹰优化算法求解无人机三维路径规划(MATLAB代码)

详细介绍 多目标应用&#xff1a;MOHHO多目标哈里斯鹰优化算法求解无人机三维路径规划&#xff08;MATLAB代码&#xff09;-CSDN博客 一次运行结果 完整MATLAB代码

工会考试基础知识题库分享(附答案解析)

单选题 1、国家机关在组织起草或者修改直接涉及职工切身利益的法律、法规、规章时&#xff0c;( )工会意见。 A、可以听取 B、应当听取 C、必须听取 D、应当吸收 [答案]B 【解析】国家机关在组织起草或者修改直接涉及职工自身利益的法律、法规、规章时&#xff0c;应当听取工…

正宇软件助力青岛打造智慧政协平台,引领新时代政协工作创新

在当前数字化、智能化浪潮的推动下&#xff0c;青岛市政协紧跟时代步伐&#xff0c;以“百舸争流奋楫先”的精神&#xff0c;不断开拓创新&#xff0c;推动政协工作高质量发展。5月30日&#xff0c;人民政协报报道了青岛市政协在推动高质量发展、加强思想政治引领、凝聚合作共识…

电赛报告书写

一、总体要求 &#xff08;1&#xff09;摘要&#xff1a;一页&#xff0c;小于300字 &#xff08;2&#xff09;正文&#xff1a;不超过8页 &#xff08;3&#xff09;附录&#xff1a;可以没有&#xff0c;但是不能超过2页 二、摘要书写 摘要要小于等于300字&#xff0c…

ARM公司发展历程

Arm从1990年成立前开始&#xff0c;历经漫长岁月树立各项公司里程碑及产品成就&#xff0c;一步步成为全球最普及的运算平台。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; Acorn 时期 1978年&#xff0c;Chris Curry和Hermann Hauser共同创立了Acorn…

如何使用SeaFile文件共享服务器结合内网穿透将家中电脑变成个人云盘

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 Cpolar下载安装3.2 Cpolar的注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 本文主要为大家介绍&#xff0c;如何使用两个…

普通人如何找到合适的创业方向

作为普通人创业&#xff0c;试错的成本是很高的&#xff0c;哪怕是低成本创业&#xff0c;你起码也得花费大量的时间&#xff0c;所以&#xff0c;在方向的选择上&#xff0c;我们需要谨慎&#xff0c;避免因为方向的选择错误&#xff0c;导致陷入进退两难的地步。 创业方向如何…

h5接入企业微信登录以及本地开发调试

首先管理员登录企业微信&#xff0c;创建第三方应用 把appID(企业微信ID) &#xff0c; AgentId&#xff08;应用id&#xff09;和Secret&#xff08;密钥&#xff09;记下来给后端同事 在应用中配置可信域名&#xff0c;例如&#xff1a; 我配置好的如下&#xff1a; 配置…

【C语言】学生管理系统:完整模拟与实现

&#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;C笔记专栏&#xff1a; C笔记 &#x1f308;喜欢的诗句:无人扶我青云志 我自踏雪至山巅 &#x1f525;引言 本篇文章为修改了在校期间实训报告&#xff0c;使用C…

基于python flask的旅游景点评论数据可视化大屏实现,包括数据采集

背景 在旅游行业中&#xff0c;了解游客对旅游景点的评论和评价对于景点管理和市场营销至关重要。通过采集旅游景点评论数据并进行可视化分析&#xff0c;可以帮助景点管理者更好地了解游客对景点的看法和体验&#xff0c;发现优劣势&#xff0c;优化服务和提升用户满意度。基…

【全开源】CMS内容管理系统(ThinkPHP+FastAdmin)

基于ThinkPHPFastAdmin的CMS内容管理系统&#xff0c;自定义内容模型、自定义单页、自定义表单、专题、统计报表、会员发布等 提供全部前后台无加密源代码和数据库私有化部署&#xff0c;UniAPP版本提供全部无加密UniAPP源码​ &#x1f50d; 解锁内容管理新境界&#xff1a;C…

ai智能全自动批量剪辑软件神器,让视频创作变得简单!

随着科技的飞速发展&#xff0c;人工智能技术在各个领域都取得了突破。在视频制作领域&#xff0c;AI智能全自动批量剪辑软件神器的出现&#xff0c;为视频创作者带来了前所未有的便利。接下来咱们详细介绍这款软件的特点和优势&#xff0c;以及它如何让视频创作变得更加简单。…