vue3+Element Plus功能组件封装——条件搜索(输入框(可新增删除),下拉选择框,日期选择)

目录

1.html部分

2.js部分

3.使用

4.附加


后台管理做多了,会发现无非就是一些,表单和表格,没什么新东西,直接套模板即可,下次遇到直接用,别再重复造轮子了,多花点时间推升自己!

1.html部分

选择性使用,可根据v-if else区分

javascript 复制代码
<el-form ref="fromRef"  style="display:flex;">
	<template style="display:flex;flex-wrap:wrap;">
		<el-form-item v-for="item in FormData.formItems" :label="item.label">
			<!-- 判断是输入框还是选择框 选择框给出 是否多选属性  (附加表单验证) -->
			<el-input v-if="item.type=='input'" v-model="item.inputValue" :placeholder="item.placeholder"
				@change="inputChange(item.key,$event)" />
			<el-select v-else v-model="item.selectValue" :disabled="item.disabled" :multiple="item.multiple"
				:collapse-tags="item.collapsetags" :placeholder="item.placeholder"
				@change="selectChange(item.key,$event)" style="width: 200px;">
				<el-option v-for="option in item.selectOptions" :key="option.value" :label="option.label"
					:value="option.value" />
			</el-select>
            <template v-else-if="item.type=='multipleInput'">
				<template v-for="(time,index) in item.inputValue" :key="index">
					<div class="" style="width: 100%;">
						<el-input v-model="item.inputValue[index]" style="margin:0 5px 10px 0"
							@change="multipleInputChange(item.key,item.inputValue)"
							:placeholder="item.placeholder" />
						<el-icon v-if="index==0" style="font-size:20px" @click="addInput(item.key)">
							<CirclePlus />
						</el-icon>
						<el-icon v-else style="font-size:20px" @click="delInput(item.key,index)">
							<Remove />
						</el-icon>
					</div>
			
				</template>
			</template>
		</el-form-item>
		<!-- 判断有没有时间 -->
		<el-form-item :label="$t('CMP.time')" v-if="FormData.isTimePicker">
			<date-time-picker ref="childRef" @selectedDate="getSelectedDate"
				:toclear="false"></date-time-picker>
		</el-form-item>
	</template>
</el-form>

2.js部分

接收父组件数据,渲染页面;将搜索条件数据通过emit方法返回给父组件

javascript 复制代码
import dateTimePicker from '@/components/dateTimePicker.vue'

let props = defineProps({
	FormData: Object
})

const emit = defineEmits()

const selectChange = (key, value) => {
	emit('selectFromChange', {
		key,
		value
	})
	console.log(key, value);
}
const inputChange = (key, value) => {
	emit('inputChange', {
		key,
		value
	})
	console.log(key, value);
}
const getSelectedDate = (date) => {
	emit('dateChange', date)
	console.log(date);
}
//输入框的新增和删除
    const multipleInputChange = (key, inputValue) => {
		emit('multipleInputChange', {
			key,
			inputValue
		})
		console.log(key, inputValue);
	}
	
	const addInput = (key) => {
		emit('addInput', key)
	}
	
	const delInput = (key, index) => {
		emit('delInput', {
			key,
			index
		})
	}

3.使用

javascript 复制代码
<template>
	<div class="common_style">
		<select-module 
            :FormData="formData"
            @inputChange="inputChange" 
            @selectFromChange="selectFromChange"
            @dateChange="dateChange"
            @addInput="addInput"
            @multipleInputChange="multipleInputChange" 
            @delInput="delInput">
        </select-module>
	</div>
</template>
<script setup>
	import selectModule from '@/components/selectModule.vue'
	
	const inputChange = (data) => {
		searchFormData[data.key] = data.value
	}
	
	const selectFromChange = (data) => {
		searchFormData[data.key] = data.value
	}

    // 增加一个日期时间
	const addInput = (key) => {
		formData.formItems.map(item => {
			if (item.key == key) {
				item.inputValue.push('')
			}
		})
	}

    const delInput = (data) => {
		formData.formItems.map((item) => {
			if (item.key == data.key) {
				item.inputValue.splice(data.index, 1)
				updateInfo[data.key] = item.inputValue
			}
		})
		updateInfo[data.key] = updateInfo[data.key].filter(item => item)
	}

    const multipleInputChange = (data) => {
		data.inputValue = data.inputValue.filter(item => item)
		updateInfo[data.key] = data.inputValue
	}
	
    let updateInfo = {}//用于接收子组件数据

	const formData = reactive({
		formItems: [{
				type: 'input',
				key: 'ID',
				inputValue: "",
				label: i18n.global.t('DQ.deviceID'),
				placeholder: i18n.global.t('DQ.pleaseInputID')
			},
			{
				type: 'select',
				key: 'Type',
				selectValue: "",
				label: i18n.global.t('DQ.Type'),
				multiple: true,
				collapsetags: true,
				placeholder: i18n.global.t('DQ.pleaseSelectType'),
				selectOptions
			},
            {
				type: 'multipleInput',
				key: 'phones',
				inputValue: [],
				label: i18n.global.t('DM.phoneNumbers'),
				placeholder: i18n.global.t('DM.phoneNumbersPlaceholder')
			},
		]
		isTimePicker: true
	})
</script>

其中,multiple: truecollapsetags: true用于选择框的多选配置

输入框可以选择性的增加或删减,应用场景可能是输入多个邮箱或者电话号码,通过加减号动态的控制输入框的数量,取值时通过filter函数去除重复部分

4.附加

上述时间日期选择组件为额外封装

可实现限制时间范围,时间格式转换,快速选择范围内时间

封装代码如下:

javascript 复制代码
<template>
	<div class="">
		<el-date-picker style="color: #809AAB;" :shortcuts="shortcuts" v-model="curentTime" type="datetimerange"
			 :start-placeholder="$t('CMP.startTime')" 
			 :disabled-date="disabledDate" :end-placeholder="$t('CMP.endTime')" @change="sureDate" />
	</div>
</template>


<script setup>
	import {
		ref
	} from 'vue'
	const emit = defineEmits()
	let props = defineProps({
		defaultTimeValue: Array
	})
	//如果要设置默认时间使用 此处的v-model值
	const curentTime = ref(props.defaultTimeValue)


	const sureDate = (e) => {
		if (e) {
			console.log(formatDate(e[0]), formatDate(e[1]));
			curentTime.value = [formatDate(e[0]), formatDate(e[1])]
		} else {
			curentTime.value = []
		}
		//将选中的值传递给父组件
		emit('selectedDate', curentTime.value)
	}

	const clearDate = () => {
		curentTime.value = []
	}
	//获取前一个月的今天
	const getPrevMonthSameDay = (num) => {
		const now = new Date();
		const prevMonth = new Date(now.getFullYear(), now.getMonth() - num, 1);
		const daysInPrevMonth = new Date(prevMonth.getFullYear(), prevMonth.getMonth() + 1, 0).getDate();
		const sameDayInPrevMonth = Math.min(now.getDate(), daysInPrevMonth);
		return new Date(prevMonth.getFullYear(), prevMonth.getMonth(), sameDayInPrevMonth);
	};

	// 创建日期限制函数
	const disabledDate = (time) => {
		return time < getPrevMonthSameDay(2) || time > new Date();
	};

	const shortcuts = [{
			text: 'Last week',
			value: () => {
				const end = new Date()
				const start = new Date()
				start.setDate(start.getDate() - 7)
				return [start, end]
			},
		},
		{
			text: 'Last month',
			value: () => {
				const end = new Date()
				const start = new Date()
				start.setMonth(start.getMonth() - 1)
				return [start, end]
			},
		},
		{
			text: 'Last 3 months',
			value: () => {
				const end = new Date()
				const start = new Date()
				start.setMonth(start.getMonth() - 3)
				return [start, end]
			},
		},
	]
	
	//将标准时间格式转为类似于 202408051104 格式
	const formatDate = (date) => {
		var year = date.getFullYear();
		var month = ("0" + (date.getMonth() + 1)).slice(-2); // getMonth返回的是0-11,所以需要+1
		var day = ("0" + date.getDate()).slice(-2);
		var hours = ("0" + date.getHours()).slice(-2);
		var minutes = ("0" + date.getMinutes()).slice(-2);
		var seconds = ("0" + date.getSeconds()).slice(-2);
		return `${year}${month}${day}${hours}${minutes}${seconds}`;
	}

	defineExpose({
		clearDate
	})
</script>



<style scoped>
	:deep(.el-date-editor .el-range-input) {
		color: #fff;
	}
</style>
相关推荐
叫我:松哥8 分钟前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
cc蒲公英39 分钟前
Vue2+vue-office/excel 实现在线加载Excel文件预览
前端·vue.js·excel
好名字082143 分钟前
monorepo基础搭建教程(从0到1 pnpm+monorepo+vue)
前端·javascript
森叶1 小时前
Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题
vue.js·electron·npm
c#上位机1 小时前
C#事件的用法
java·javascript·c#
小小竹子1 小时前
前端vue-实现富文本组件
前端·vue.js·富文本
万物得其道者成1 小时前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
小白小白从不日白1 小时前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风2 小时前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
青稞儿2 小时前
面试题高频之token无感刷新(vue3+node.js)
vue.js·node.js