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