158 lines
5.1 KiB
Vue
158 lines
5.1 KiB
Vue
<template>
|
|
<el-row class="base-search-form">
|
|
<div class="brand-color-line"></div>
|
|
<el-form :inline="true" :model="dataForm" :rules="headConfig.rules">
|
|
<!-- <el-col :span="opt.span ? +opt.span : 4" v-for="opt in options" :key="opt.id"> -->
|
|
<el-form-item
|
|
v-for="(opt, index) in headConfig.fields"
|
|
:key="opt.prop"
|
|
:label="opt.label ? opt.label : null"
|
|
:prop="opt.prop ?? '' + index"
|
|
:rules="opt.bind?.rules ? opt.bind.rules : undefined"
|
|
>
|
|
<el-input v-if="opt.input" v-model="dataForm[opt.prop]" v-bind="opt.bind" clearable size="small" />
|
|
<el-select v-if="opt.select" v-model="dataForm[opt.prop]" v-bind="opt.bind" clearable size="small">
|
|
<el-option v-for="item in opt.select" :key="item.value" :label="item.label" :value="item.value" />
|
|
</el-select>
|
|
<el-date-picker v-if="opt.timerange" v-model="dataForm[opt.prop]" v-bind="opt.bind" clearable size="small" />
|
|
<el-upload
|
|
v-if="opt.upload"
|
|
size="small"
|
|
:key="'upload_' + Math.random().toString()"
|
|
class="inline-block pl-3"
|
|
action="https://jsonplaceholder.typicode.com/posts/"
|
|
>
|
|
<el-button type="primary">上传文件</el-button>
|
|
</el-upload>
|
|
<el-button
|
|
v-if="opt.button && (!opt.button.permission || $hasPermission(opt.button.permission))"
|
|
:key="'button' + Math.random().toString()"
|
|
size="small"
|
|
:type="opt.button.type"
|
|
v-bind="opt.bind"
|
|
@click="handleBtnClick(opt.button.name)"
|
|
>{{ opt.button.name }}</el-button
|
|
>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-row>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "BaseSearchForm",
|
|
props: {
|
|
headConfig: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
dataForm: {},
|
|
};
|
|
},
|
|
|
|
// 这个 watch 出现得没啥必要......
|
|
// watch: {
|
|
// dataForm: {
|
|
// handler: (val) => {
|
|
// console.log("[BaseSearchForm::watcher::dataForm]", val);
|
|
// },
|
|
// deep: true,
|
|
// },
|
|
// },
|
|
|
|
created() {},
|
|
mounted() {
|
|
console.log("[BaseSearchForm] configs:", JSON.parse(JSON.stringify(this.headConfig)));
|
|
|
|
this.headConfig.fields.forEach((field, index) => {
|
|
// 没有 field.prop ,则为按钮之类的
|
|
if (!field.prop) return;
|
|
|
|
if (!this.dataForm[field.prop]) {
|
|
this.$set(this.dataForm, field.prop, null);
|
|
}
|
|
|
|
if (field.default) {
|
|
// default 必须有个 value 属性!哪怕是 input 输入框
|
|
this.dataForm[field.prop] = field.default.value;
|
|
}
|
|
|
|
// 更新选项列表
|
|
if (!field.watch && field.fn && typeof field.fn === "function") {
|
|
// 设置自身的选项列表
|
|
field.fn().then(({ data: res }) => {
|
|
if (res.code === 0 && res.data) {
|
|
// TODO: 此处需要随具体情况再做更新
|
|
field.select = res.map((_) => {
|
|
// 找到默认项
|
|
if (_.default) {
|
|
this.searchForm[index] = _.value;
|
|
}
|
|
return _;
|
|
});
|
|
console.log("[update] 更新选项列表", res, field.select);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 如果需要监听关联字段, field.watch ===> 需要watch的那个字段的 prop
|
|
// TODO: 此处也需要修改,碰到具体业务需求才更新...
|
|
if (field.watch) {
|
|
// const { index: innerIdx, condition } = field.watch;
|
|
// console.log("=====field.watch=====", innerIdx, this.searchForm[innerIdx], this.headConfig.fields[innerIdx].default);
|
|
// // 设置监听器
|
|
// this.$watch(
|
|
// () => this.searchForm[innerIdx],
|
|
// (val) => {
|
|
// const queryParams = { [condition]: val };
|
|
// // field.watch.condition.forEach(c => {
|
|
// // queryParams
|
|
// // })
|
|
// this.$http(field.url, queryParams).then((res) => {
|
|
// console.log("[==>] 更新有前置条件的字段!!!", queryParams, res);
|
|
// // 此处是外部的 index
|
|
// this.searchForm[index] = Math.floor(Math.random() * 10);
|
|
// });
|
|
// }
|
|
// );
|
|
// console.log("[BaseSearchForm] mounted(): ", this.searchForm);
|
|
// // 如果此时已经有默认值了,就立马根据这个默认值来发起请求
|
|
// if (this.searchForm[innerIdx]) {
|
|
// // TODO: 这个判断好像不太需要...
|
|
// console.log("TODO: 这个判断好像不太需要...");
|
|
// } else {
|
|
// console.log("TODO: 监听的字段还没来得及设置值呢...");
|
|
// }
|
|
}
|
|
});
|
|
},
|
|
methods: {
|
|
handleBtnClick(name) {
|
|
this.$emit("btn-click", { btnName: name, payload: this.dataForm });
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.base-search-form {
|
|
display: flex;
|
|
/* align-items: center; */
|
|
/* position: relative; */
|
|
}
|
|
|
|
.brand-color-line {
|
|
display: inline-block;
|
|
height: 20px;
|
|
width: 6px;
|
|
margin-right: 8px;
|
|
margin-top: 10px;
|
|
border-radius: 2px;
|
|
background: #0b58ff;
|
|
/* position: absolute; */
|
|
}
|
|
</style>
|