vue3.0实现自定义手风琴

1、html部分

    <div class="lesson" v-if="list.length > 0">
			<div v-for="(item, index) in list" :key="index">
                <---面板部分---->
				<div class="collapse-item web-flex" style="border-bottom: 1px solid #e8e8e8;position:relative;">
					<el-row class="collapse-item-header" @click="collapseClick(index)">
						<el-col :span="4" style="position: relative;">
							<img src="../assets/img/tip_icon.svg" alt="" style="position:absolute;left:-5px;top:10px;"
								v-if="item.stayNum > 0 && item.courseType == 2">
							<div class="first-collapse-item">
								{{item.courseName}}
							</div>
						</el-col>
						<el-col :span="1">
							<div>{{item.courseType == 0 ? '团课' : item.courseType == 1 ? '私教' : '培训'}}</div>
						</el-col>
						<el-col :span="3">
							<div>课时数:{{item.courseNum || '-'}}</div>
						</el-col>
						<el-col :span="4">
							<div>课时时长:{{item.courseTime}}分钟</div>
						</el-col>
						<el-col :span="4">
							<div>有效期:<span v-if="item.courseType != 0">{{item.termDay}}</span><span
									v-else>{{item.timeDay}}</span>天</div>
						</el-col>
						<el-col :span="5">
							<div>报名截止时间:{{item.deadTime}}</div>
						</el-col>
						<el-col :span="3">
							<div v-if="item.coursePrice">价格¥{{item.coursePrice}}</div>
						</el-col>
					</el-row>
                    <---面板操作按钮,使用element-ui会导致点击操作按钮手风琴打开---->
					<div class="btn-content web-flex">
						<div>
								<el-button type="text">修改</el-button>
								<el-button type="text">分班</el-button>
								<el-button type="text">报名</el-button>
						</div>
						<div @click="collapseClick(index)" style="flex:1;">
							<el-button type="text" class="float-right" style="margin-top:12px;">
								<img src="../assets/img/you.svg" alt="" :id="'img' + index"
									style="width:20px;height:20px;transition: 0.3s;">
							</el-button>
						</div>
					</div>
				</div>
                <---显隐部分---->
				<div class="collapse-item-body" :id="index">
					<div class="web-flex" v-for="(cell, index1) in item.reCoursePeriodList" :key="index1">
						<el-row class="collapse-item-content">
							<template v-if="cell.periodType == 1">
								<el-col :span="4" :offset="4">
									<div class="collapse-line">{{cell.date}}</div>
								</el-col>
								<el-col :span="4">
									<div class="collapse-line">{{cell.string}}</div>
								</el-col>
							</template>
							<el-col :span="8" :offset="4" v-if="cell.periodType != 1">
								<div class="collapse-line">{{cell.string}}</div>
							</el-col>
							<el-col :span="4">
								<div>报名总人数:{{cell.signNum}}</div>
							</el-col>
							<el-col :span="5" v-if="status == 1 && item.courseType == 2">
								<div class="orange">待分班人数:{{cell.stayNum}}</div>
							</el-col>
						</el-row>
						<div class="btn-content btn-context" v-if="status == 1">
							<el-button @click="openClass(cell, item)" v-if="item.courseType == 0" type="text"
								style="margin-right:20px;">开课时间
							</el-button>
							<router-link v-if="item.courseType == 2"
								:to="{path:'/apply',query:{code: cell.periodCode,id: item.courseCode}}">
								<el-button type="text">报名</el-button>
							</router-link>
						</div>
					</div>
                    <---内容部分的底部边框---->
					<div v-show="activeIndex == index" style="width:100%;border-bottom:1px solid #e8e8e8;"></div>
				</div>
			</div>

2、vue.js部分

    const list = ref([])
	const activeIndex = ref(null)
	const height = ref(0)
    //通过控制高度控制显隐
	const collapseClick = (index) => {
		if (activeIndex.value != null) {
			var al = document.getElementById(activeIndex.value)
			al.style.setProperty('height', '0px')
			var img1 = document.getElementById('img' + activeIndex.value)
			img1.style.setProperty('transform', 'rotateZ(0)')
		}
		var el = document.getElementById(index)
		var img = document.getElementById('img' + index)
		var height = el.scrollHeight;
		if (activeIndex.value == index) {
			activeIndex.value = null
			el.style.setProperty('height', '0px')
			img.style.setProperty('transform', 'rotateZ(0)')
		} else {
			activeIndex.value = index
			el.style.setProperty('height', height + 1 + 'px');
			img.style.setProperty('transform', 'rotateZ(90deg)')
		}
	}

3、样式

.collapse-item {
		width: 100%;
		height: 54px;
		line-height: 54px;
		background: #fafafa;
		padding: 0 20px;
		box-sizing: border-box;
		cursor: pointer;
	}


	.collapse-item-header {
		width: calc(100% - 160px);
	}

	.collapse-item-body {
		transition: 0.3s;
		height: 0;
		overflow: hidden;
		margin-bottom: 5px;
	}

	.collapse-item-body>div {
		padding: 0 20px;
		box-sizing: border-box;
	}

	.collapse-item-content {
		height: 32px;
		line-height: 32px;
		margin: 5px 0;
		width: calc(100% - 160px);
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 ant-design-vue3.0 中,我们可以通过自定义表单校验错误显示来实现我们想要的效果。首先,我们需要在表单项中定义校验规则,并给每个表单项添加一个唯一的 `name` 属性。例如: ```html <a-form-item label="用户名" name="username" rules={[{ required: true, message: '请输入用户名' }]}> <a-input v-model:value="formData.username"></a-input> </a-form-item> ``` 接下来,我们可以在表单的 `validateTrigger` 属性中指定触发校验的时机。默认情况下,它的值为 `change` 和 `blur`,即在表单项失去焦点或值改变时触发校验。我们可以将它修改为 `submit`,表示只有在提交表单的时候才触发校验。 ```html <a-form ref="formRef" :model="formData" :validateTrigger="'submit'"> <!-- 表单项 --> </a-form> ``` 当表单校验失败时,默认情况下会在表单项下方显示错误信息。我们可以通过 `validateStatus` 和 `help` 属性来自定义错误显示。`validateStatus` 可以接受三种值:`'success'` 表示校验通过,`'error'` 表示校验失败,`'validating'` 表示校验中。我们可以根据需要设置不同的显示效果。 ```html <a-form-item label="用户名" name="username" :validateStatus="validateStatus('username')" :help="errorMessages['username']"> <a-input v-model:value="formData.username"></a-input> </a-form-item> ``` 其中,`validateStatus` 是一个方法,用于根据校验结果返回对应的状态值。`errorMessages` 是一个对象,保存所有的错误信息。 ```javascript data() { return { formData: { username: '' }, errorMessages: {} // 错误信息 } }, methods: { validateStatus(name) { if (this.errorMessages[name]) { return 'error'; } return ''; } } ``` 最后,我们需要在提交表单时手动触发校验,并捕获校验结果,并将错误信息保存到 `errorMessages` 中。 ```javascript methods: { submitForm() { this.$refs.formRef.validate((valid) => { if (valid) { // 校验通过,提交表单 } else { // 校验失败,显示错误信息 this.errorMessages = this.$refs.formRef.getFieldsError().reduce((acc, {name, errors}) => { if (errors.length > 0) { acc[name] = errors[0].message; } return acc; }, {}); } }); } } ``` 通过以上步骤,我们就可以实现自定义表单校验错误显示。在校验失败时,表单项下方会显示我们设置的错误信息,而不是默认的错误提示。 ### 回答2: 在 ant-design-vue 3.0 中,可以通过使用自定义校验规则和错误信息来自定义表单校验错误显示。 首先,创建一个自定义的校验规则函数。校验规则函数需要接受两个参数:rule 和 value。rule 代表当前校验规则的配置,而 value 代表当前表单字段的值。在校验函数中,可以根据具体的校验逻辑进行判断并返回一个校验结果。校验结果可以返回一个布尔值或一个 Promise 对象。 接着,在需要进行校验的表单控件中,可以使用 rules 属性来指定校验规则函数或校验规则数组。如果是多个校验规则,可以将它们放入数组中。可以通过 message 属性来设置错误提示信息。 例如,我们需要自定义一个校验规则,判断输入的字符串是否包含特定字符。可以创建一个函数 validateSpecialChar,接受 rule 和 value 作为参数,根据具体需求进行判断,并返回一个校验结果。 ```javascript const validateSpecialChar = (rule, value) => { if (/[@#$%^&*]/.test(value)) { return Promise.reject(new Error('不能包含特殊字符')); } return Promise.resolve(); }; ``` 然后,在表单控件中,可以指定 rules 属性来使用这个校验规则,并设置错误提示信息。 ```html <a-form-item label="用户名" required> <a-input v-decorator="['username', { rules: [{ validator: validateSpecialChar, message: '不能包含特殊字符' }] }]"></a-input> </a-form-item> ``` 当用户输入的字符串中包含特殊字符时,会显示错误提示信息"不能包含特殊字符"。如果输入合法,则不显示错误提示信息。 通过这种方式,我们可以方便地自定义表单校验错误的显示方式。根据具体需求,可以自定义不同的校验规则函数和错误提示信息来满足不同的校验需求。 ### 回答3: 在Ant Design Vue 3.0中,默认的表单校验错误显示是使用Tooltip组件,在表单控件的右上方显示错误提示信息。如果需要自定义表单校验错误显示,可以通过以下步骤实现: 1. 创建自定义的错误提示组件:可以使用Message组件或者其他任意组件作为错误提示的样式,根据具体需求进行定制。 ```vue <template> <div class="custom-error"> <span class="error-message">{{ errorMessage }}</span> </div> </template> <script> export default { name: 'CustomError', props: { errorMessage: { type: String, required: true } } } </script> <style> .custom-error { /* 自定义样式 */ } .error-message { /* 自定义样式 */ } </style> ``` 2. 在表单组件中使用自定义的错误提示组件。在需要进行校验的表单控件外部包裹一层`FormItem`组件,并通过`rules`属性设置校验规则,在`validateStatus`属性中根据校验结果设置表单控件的状态,如果校验失败,将错误信息通过`error-message`属性传给自定义错误提示组件。 ```vue <template> <a-form :form="form"> <a-form-item label="用户名" :validateStatus="validateStatus('username')" :help="helpMessage('username')"> <a-input v-model="username" /> </a-form-item> </a-form> </template> <script> import CustomError from '@/components/CustomError.vue'; export default { name: 'MyForm', components: { CustomError }, data() { return { form: this.$form.createForm(this), username: '' }; }, methods: { validateStatus(fieldName) { const { isFieldTouched, getFieldError } = this.form; return isFieldTouched(fieldName) && getFieldError(fieldName) ? 'error' : ''; }, helpMessage(fieldName) { const { isFieldTouched, getFieldError } = this.form; return isFieldTouched(fieldName) && getFieldError(fieldName) ? getFieldError(fieldName)[0] : ''; } } } </script> ``` 3. 构建校验规则:根据具体需求,使用`rules`属性定义校验规则,可以使用Ant Design Vue提供的校验规则或者自定义校验规则。 ```vue <script> export default { // ... methods: { validateStatus(fieldName) { // ... }, helpMessage(fieldName) { // ... } }, created() { this.form.setFields({ username: { rules: [ { required: true, message: '请输入用户名' }, { pattern: /^[a-zA-Z0-9_]{5,16}$/, message: '用户名由字母、数字或下划线组成,长度为5-16位' } ] } }); } } </script> ``` 通过以上步骤,我们可以实现自定义表单校验错误显示。可以根据自己的需求,使用不同的组件和样式来进行自定义
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值