|
@@ -0,0 +1,172 @@
|
|
|
|
+<template>
|
|
|
|
+ <div id="c-search">
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-col :span="24" class="title" v-if="is_title">
|
|
|
|
+ <el-col :span="24" class="title_1">
|
|
|
|
+ <span>{{ title || $route.meta.title }}</span>
|
|
|
|
+ <span>{{ tip }}</span>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="24" class="title_2">
|
|
|
|
+ <span>{{ remark }}</span>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="24" class="search" v-if="is_search">
|
|
|
|
+ <el-form ref="formRef" :model="form" label-width="auto">
|
|
|
|
+ <el-col :span="24" class="form">
|
|
|
|
+ <template v-for="(item, index) in fields">
|
|
|
|
+ <el-col :span="8" class="form_1" :key="'form-field-' + index" v-if="item.isSearch == true">
|
|
|
|
+ <el-form-item :label="getField('label', item)" :prop="item.model">
|
|
|
|
+ <template v-if="!item.custom">
|
|
|
|
+ <template v-if="item.type === 'select'">
|
|
|
|
+ <el-select v-model="form[item.model]" v-bind="item.options" filterable clearable @change="dataChange(item.model)">
|
|
|
|
+ <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
|
+ </el-select>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="form[item.model]"
|
|
|
|
+ :type="getField('type', item)"
|
|
|
|
+ :placeholder="getField('place', item)"
|
|
|
|
+ clearable
|
|
|
|
+ v-bind="item.options"
|
|
|
|
+ @change="dataChange(item.model)"
|
|
|
|
+ ></el-input>
|
|
|
|
+ </template>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
|
+ <!-- <el-input v-model="form[item.model]" clearable :placeholder="`输入${item.label}`"></el-input> -->
|
|
|
|
+ </template>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ </template>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="24" class="btn">
|
|
|
|
+ <el-button type="primary" @click="toSubmit()">查询</el-button>
|
|
|
|
+ <el-button type="danger" @click="toReset()">重置</el-button>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-form>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="24" class="back" v-if="is_back">
|
|
|
|
+ <el-button type="primary" @click="toBack()">返回</el-button>
|
|
|
|
+ <slot name="custombtn"></slot>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="24" class="slot">
|
|
|
|
+ <slot name="isslot"></slot>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
+import { ref, toRefs } from 'vue';
|
|
|
|
+import type { Ref } from 'vue';
|
|
|
|
+import _ from 'lodash';
|
|
|
|
+interface fieldsItem {
|
|
|
|
+ model: string;
|
|
|
|
+ type: string;
|
|
|
|
+ // readonly: string;
|
|
|
|
+ options: object;
|
|
|
|
+ custom: string;
|
|
|
|
+ // required: string;
|
|
|
|
+ // limit: number | undefined;
|
|
|
|
+ isSearch: boolean;
|
|
|
|
+}
|
|
|
|
+const props = defineProps({
|
|
|
|
+ is_title: { type: Boolean, default: true },
|
|
|
|
+ is_search: { type: Boolean, default: false },
|
|
|
|
+ is_back: { type: Boolean, default: false },
|
|
|
|
+ fields: { type: Array<fieldsItem> },
|
|
|
|
+ title: { type: String },
|
|
|
|
+ tip: { type: String },
|
|
|
|
+ remark: { type: String },
|
|
|
|
+});
|
|
|
|
+const { is_title } = toRefs(props);
|
|
|
|
+const { is_search } = toRefs(props);
|
|
|
|
+const { is_back } = toRefs(props);
|
|
|
|
+const { fields } = toRefs(props);
|
|
|
|
+const { title } = toRefs(props);
|
|
|
|
+const { tip } = toRefs(props);
|
|
|
|
+const { remark } = toRefs(props);
|
|
|
|
+
|
|
|
|
+let form: Ref<{}> = ref({});
|
|
|
|
+const emit = defineEmits(['search', 'toReset', 'toBack', 'dataChange']);
|
|
|
|
+const toSubmit = () => {
|
|
|
|
+ const obj = _.pickBy(form.value);
|
|
|
|
+ emit('search', { ...obj });
|
|
|
|
+};
|
|
|
|
+// 重置
|
|
|
|
+const toReset = () => {
|
|
|
|
+ form.value = {};
|
|
|
|
+ emit('search', form.value);
|
|
|
|
+};
|
|
|
|
+// 文字描述
|
|
|
|
+const getField = (item: any, data: any) => {
|
|
|
|
+ let res = _.get(data, item, null);
|
|
|
|
+ if (item === 'type') res = res === null ? `text` : res;
|
|
|
|
+ if (item === 'place') res = res === null ? `请输入${data.label}` : res;
|
|
|
|
+ if (item === 'required') res = res === null ? false : res;
|
|
|
|
+ if (item === `error`) res = res === null ? `${data.label}错误` : res;
|
|
|
|
+ return res;
|
|
|
|
+};
|
|
|
|
+// 获取输入值
|
|
|
|
+const dataChange = (model: string) => {
|
|
|
|
+ const value = form.value[model];
|
|
|
|
+ emit('dataChange', { model, value });
|
|
|
|
+};
|
|
|
|
+// 返回
|
|
|
|
+const toBack = () => {
|
|
|
|
+ emit('toBack');
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.title {
|
|
|
|
+ margin: 0 0 5px 0;
|
|
|
|
+ .title_1 {
|
|
|
|
+ margin: 0 0 5px 0;
|
|
|
|
+ span:first-child {
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ font-weight: 700;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ }
|
|
|
|
+ span:last-child {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #979797;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .title_2 {
|
|
|
|
+ span {
|
|
|
|
+ color: #8baae7;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ margin-top: 10px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.search {
|
|
|
|
+ margin: 0 0 10px 0;
|
|
|
|
+ .form {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+ .form_1 {
|
|
|
|
+ padding: 0 0 0 10px;
|
|
|
|
+ .el-form-item {
|
|
|
|
+ float: left;
|
|
|
|
+ width: 100%;
|
|
|
|
+ margin: 0 0 10px 0;
|
|
|
|
+ }
|
|
|
|
+ .el-select {
|
|
|
|
+ width: 100%;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .btn {
|
|
|
|
+ text-align: right;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.back {
|
|
|
|
+ text-align: left;
|
|
|
|
+ margin: 0 0 10px 0;
|
|
|
|
+}
|
|
|
|
+</style>
|