当前项目当中有很多栏目都大差不差,于是就寻思弄一个通用的组件简单封装下
<!--
封装表单通用组件
labelWidth: '84px',
configs: [
{
type: "select",
size: "mini",
dict: "zrUnit",
label: "责任单位",
prop: "dw",
transForValue: "orgId",
transForLabal: "orgName",
clearable: true,
disabled: false,
placeholder: "请选择",
options: [
{
label: "市统计局",
value: 'id1',
},
{
label: "市市场监管局",
value: 'id2',
},
{
label: "市水利局",
value: 'id3',
},
],
},
{
type: "month",
size: "mini",
label: "发布时间",
prop: "startTime",
// format:'yyyy-MM',
valueFormat: "yyyy-MM",
placeholder: "请输入",
// 如果有时间要求
pickerOptions: {},
},
{
type: "select",
size: "mini",
label: "风险等级",
prop: "level",
clearable: true,
disabled: false,
placeholder: "请选择",
options: [
{
label: "严重违反",
value: 1,
},
{
label: "轻度违反",
value: 2,
},
{
label: "无风险",
value: 3,
},
],
},
],
暴露方法 handleQuery
暂时类型不多,后期扩展
-->
<template>
<div class="common-table-search">
<div class="search-wrapper">
<!--用户数据-->
<el-col :span="20" :xs="24">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
:label-width="labelWidth"
:label-position="labelPosition"
>
<template v-for="(item, index) in configs">
<el-form-item
v-if="item.type === 'cascader'"
:label="item.label"
:prop="item.prop"
:label-width="item.labelWidth"
>
<el-cascader
:options="item.options"
:props="{
value: item.cascaderProps.value,
label: item.cascaderProps.label,
children: item.cascaderProps.children,
checkStrictly: item.cascaderProps.checkStrictly,
}"
:placeholder="`${item.placeholder}${item.label}`"
:clearable="item.clearable"
v-model="queryParams[item.prop]"
@change="(val) => handleCascaderChange(val, item)"
>
</el-cascader>
</el-form-item>
<el-form-item
v-if="item.type === 'autocomplete'"
:label="item.label"
:prop="item.prop"
:label-width="item.labelWidth"
>
<el-autocomplete
class="inline-input"
v-model="queryParams[item.prop]"
:fetch-suggestions="(queryString, cb) => querySearchAsync(queryString, cb, item)"
:placeholder="`${item.placeholder}${item.label}`"
:trigger-on-focus="item.triggerOnFocus"
clearable
@select="(val) => handleSelect(val, item)"
@input="changeData"
></el-autocomplete>
</el-form-item>
<el-form-item
v-if="item.type === 'month' || item.type === 'date'"
:label="item.label"
:prop="item.prop"
:key="Math.random() + item.prop + index"
:label-width="item.labelWidth"
>
<el-date-picker
v-model="queryParams[item.prop]"
:type="item.type"
:format="item.format"
:value-format="item.valueFormat"
:placeholder="`${item.placeholder}${item.label}`"
>
</el-date-picker>
</el-form-item>
<el-form-item
v-if="item.type === 'select'"
:label="item.label"
:prop="item.prop"
:key="Math.random() + item.prop + index"
:label-width="item.labelWidth"
>
<el-select
:clearable="item.clearable"
:disabled="item.disabled"
:placeholder="`${item.placeholder}${item.label}`"
v-model="queryParams[item.prop]"
@change="(val) => handlerChange(val, item)"
>
<el-option
v-for="i in item.options"
:label="i.label"
:value="i.value"
:key="i.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
v-if="item.type === 'input'"
:label="item.label"
:prop="item.prop"
:key="Math.random() + item.prop + index"
:label-width="item.labelWidth"
>
<el-input
:clearable="item.clearable"
:disabled="item.disabled"
:placeholder="`${item.placeholder}${item.label}`"
v-model="queryParams[item.prop]"
>
</el-input>
</el-form-item>
</template>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>查询</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
</el-col>
</div>
</div>
</template>
<script>
export default {
props: {
// 搜搜表单配置
configs: {
type: Array,
default: () => [],
},
// 默认整个搜索项宽
labelWidth: {
type: String,
default: "80px",
},
labelPosition: {
type: String,
default: 'right'
}
},
data() {
return {
name: "",
queryParams: {},
// 查询参数
cityQueryParams: {
deptName: undefined,
status: undefined,
},
};
},
watch: {
configs: {
handler(v) {
this.updateConfig(v);
},
immediate: true,
},
queryParams: {
handler(){
this.handleQuery('noSearch')
},
deep:true
}
},
methods: {
querySearchAsync(queryString, cb, item) {
// 这里需要优化
// 因为暂时去掉了这个输入搜索
let restaurants = item.options || [];
let results = queryString
? restaurants.filter(this.createStateFilter(queryString))
: restaurants;
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
cb(results);
}, 3000 * Math.random());
},
createStateFilter(queryString) {
return (state) => {
return (
state.value.toLowerCase().indexOf(queryString.toLowerCase()) > -1
);
};
},
handleCascaderChange(val, item) {
console.log(val, item);
// this.queryParams[item.prop] = val[val.length - 1]
},
//@select 点击选中建议项时触发
handleSelect(val, item) {
console.log(val, item);
},
//@input 在 Input 值改变时触发
changeData(val, item) {
console.log(val, item);
},
handlerChange(val, item) {
console.log(val, item);
},
handleQuery(flag) {
this.$emit("searchQuery", this.queryParams,flag);
},
resetQuery() {
this.$refs.queryForm.resetFields();
this.queryParams = {};
this.$emit("resetQuery", this.queryParams);
},
},
};
</script>
<style lang="scss" scoped>
.common-table-search{
background-color: #fff;
padding: 10px 10px 0 10px;
margin-bottom: 10px;
.search-wrapper {
display: flex;
}
}
附上updateConfig 的方法
export function updateConfig(config) {
// 针对数据options做针对性判断
config.forEach(async (s) => {
// 如果是城市级联数据
if (s.type === "cascader" && s.flag === "city") {
listDept2(this.cityQueryParams).then((response) => {
s.options = this.handleTree(response.data, "deptId");
});
}
// 如果存在字典项
if (s.dict) {
// 无需关联
const result = await getDicts(s.dict); // 获取字典数据并填充到options中
if (result.code === 200) {
s.options = result.data.map((item) => ({
value: item.dictValue,
label: item.dictLabel,
})); // 字典数据转换为 select options 格式, 并填充到 options 中
}
}
});
}
因为当前框架式基于若依的所以像handleTree 就用他自带的了
</style>