本文介绍: vue结合elementui后台管理系统,会有很多数据表格,结合数据表格的会有很多搜索选项我们搜索区域一个数据表格搜索条件都不一样,并且在多人开发的情况下样式也不相同布局样式还不能统一

1.背景

介绍

vue结合elementui后台管理系统,会有很多数据表格,结合数据表格的会有很多搜索选项我们的搜索栏区域一个数据表格搜索条件都不一样,并且在多人开发的情况下样式也不相同,布局样式还不能统一

考虑到这一个问题我们封装一个搜索组件统一配置提升开发效率,并且减少一定量代码量。

效果展示
在这里插入图片描述


2.问题分析

项目使用的是elementui框架,搜索栏这种表单提交,首先要使用elform组件封装,而复杂就是表单可能很多种,例如input输入框select选择框、日期时间选择框、日期时间范围选择框、cascader级联选择框等,每一项的字段名prop名称label绑定属性方法都不尽相同。所以不能通过普通的绑定个别属性方式处理,而slot插槽方式也无法简化,最终决定通过传递一个配置数组的形式来解析生成相应的结构


3.组件实现

目前实现方式由两部分组成,一部分form表单组件,接受父组件传递配置数组,一部分封装一些常用表单组件通过vif控制form表单组件引入表单项组件,循环遍历,根据传递表单类型匹配显示具体的表单项。


示例代码1

 <el-form
      class="search-block"
      ref="searchFormRef"
      :model="formModel"
      :inline="props.inline"
    >
      <el-row>
        <el-form-item
          v-for="(item, key) in props.searchForm"
          :key="key"
          :label="item.label"
          :prop="key"
          :class="item.class"
        >
          <template
            v-if="item.component === 'el-date-picker' && item.customContent"
          >
            <el-date-picker
              v-bind="item.attrs"
              v-model="formModel[key]"
              :style="item.style || 'width:258px'"
              clearable
              :editable="false"
              :type="item.type || ''"
              :prefix-icon="item.customPrefix ? customPrefix : ''"
            >
            </el-date-picker>
          </template>
        </el-form-item>
      </el-row>
    </el-form>

示例代码2

<el-form
      class="search-block"
      ref="searchFormRef"
      :model="formModel"
      :inline="props.inline"
    >
      <el-row>
          <component
            :is="item.component"
            v-bind="item.attrs"
            v-on="item.event"
            v-model="formModel[key]"
            :id="item.id"
            clearable
            v-if="!item.customContent"
            :style="item.style || 'width:158px'"
            :prefix-icon="item.customPrefix ? customPrefix : ''"
          >
            <template #default v-if="item.component === 'el-select'">
              <el-option
                v-for="option in item.options"
                :key="option.key"
                :value="option.key"
                :label="option.value"
              >
              </el-option>
            </template>
          </component>
        </el-form-item>
      </el-row>
    </el-form>

4.参数配置

4.1组件内参示例

主要配置接收数据

<script setup>
const props = defineProps({
  title: { type: String, default: '搜索' },
  searchForm: { type: Object }, // 传入的数据
  inline: {
    type: Boolean,
    default: true
  },
  searchBtnShow: { // 是否显示【搜索】【清空按钮
    type: Boolean,
    default: true
  },
  emitSearch: [Object, String] // 解决跳转页码选择器内容为空
})
</script>

4.2组件外传入参数配置示例

// 搜索栏数据
const searchForm = reactive({
  projectName: {
    label: '项目名称',
    component: 'el-input',
    attrs: {
    },
    options: [],
    style: {
    },
    event: {}
  },
  indicatorId: {
    label: '关联病理指标',
    component: 'el-select',
    attrs: {
    },
    options: [],
    style: {
    },
    event: {}
  },
  beginTime: {
    label: '创建时间',
    component: 'el-date-picker',
    attrs: {
      rangeSeparator: '至',
      valueFormat: 'YYYY-MM-DD'
    },
    customPrefix: true,
    customContent: true,
    id: 'start-time',
    type: 'daterange',
    event: {},
    child: {
    }
  }
})

5.使用示例

<template>
 <search :searchForm="searchForm" title="" />
</template>
<script setup>
 import search from '@/components/search'
 // 搜索栏数据
const searchForm = reactive({
  projectName: {
    label: '项目名称',
    component: 'el-input',
    attrs: {
    },
    options: [],
    style: {
    },
    event: {}
  },
  indicatorId: {
    label: '关联病理指标',
    component: 'el-select',
    attrs: {
    },
    options: [],
    style: {
    },
    event: {}
  },
  beginTime: {
    label: '创建时间',
    component: 'el-date-picker',
    attrs: {
      rangeSeparator: '至',
      valueFormat: 'YYYY-MM-DD'
    },
    customPrefix: true,
    customContent: true,
    id: 'start-time',
    type: 'daterange',
    event: {},
    child: {
    }
  }
})
</script>

6.完成代码

1.search.vue

<template>
  <div class="search-module">
    <div class="title-heading" v-if="props.title">
      <span>{{ props.title }}</span>
    </div>
    <!-- 搜索 -->
    <el-form
      class="search-block"
      ref="searchFormRef"
      :model="formModel"
      :inline="props.inline"
    >
      <el-row>
        <el-form-item
          v-for="(item, key) in props.searchForm"
          :key="key"
          :label="item.label"
          :prop="key"
          :class="item.class"
        >
          <template
            v-if="item.component === 'el-date-picker' &amp;&amp; item.customContent"
          >
            <el-date-picker
              v-bind="item.attrs"
              v-model="formModel[key]"
              :style="item.style || 'width:258px'"
              clearable
              :editable="false"
              :type="item.type || ''"
              :prefix-icon="item.customPrefix ? customPrefix : ''"
            >
            </el-date-picker>
          </template>
          <component
            :is="item.component"
            v-bind="item.attrs"
            v-on="item.event"
            v-model="formModel[key]"
            :id="item.id"
            clearable
            v-if="!item.customContent"
            :style="item.style || 'width:158px'"
            :prefix-icon="item.customPrefix ? customPrefix : ''"
          >
            <template #default v-if="item.component === 'el-select'">
              <el-option
                v-for="option in item.options"
                :key="option.key"
                :value="option.key"
                :label="option.value"
              >
              </el-option>
            </template>
          </component>
        </el-form-item>
        <div class="search-btn" v-if="searchBtnShow">
          <el-button type="primary" class="btn-default-blue" @click="searchSubmit('searchFormRef')"
            >搜索</el-button
          >
          <el-button type="primary" class="btn-default-blue" @click="resetSubmit('searchFormRef')"
            >清空</el-button
          >
        </div>
      </el-row>
    </el-form>
  </div>
</template>

<script setup>
const props = defineProps({
  title: { type: String, default: '搜索' },
  searchForm: { type: Object },
  inline: {
    type: Boolean,
    default: true
  },
  searchBtnShow: { // 是否显示【搜索】【清空按钮
    type: Boolean,
    default: true
  },
  emitSearch: [Object, String] // 解决跳转页码选择器内容为空
})
const formModel = ref({})
onBeforeMount(() => {
  const keys = Object.keys(props.searchForm)
  const obj = {}
  keys.forEach(key => {
    obj[key] = props.searchForm[key].defaultValue || ''
  })
  formModel.value = Object.assign({}, formModel.value, obj)
})
const searchFormRef = ref(null)
const emit = defineEmits(['refreshData', 'update:emitSearch'])

// 日期自定义样式
const customPrefix = shallowRef({
  render () {
    return h('p', { class: 'icon-rili-01 font_family icon-size' })
  }
})

const searchSubmit = () => {
  formModel.value.params = {}
  if (formModel.value?.beginTime) {
    const date = {
      beginTime: formModel.value.beginTime[0],
      endTime: formModel.value.beginTime[1]
    }
    formModel.value.params['beginTime'] = date.beginTime
    formModel.value.params['endTime'] = date.endTime
  } else if (!formModel.value.beginTime) {
    formModel.value.params['beginTime'] = ''
    formModel.value.params['endTime'] = ''
  }
  let assignForm = {...formModel.value}
  delete assignForm.beginTime
  emit('update:emitSearch', assignForm)
  emit('refreshData', assignForm, true)
  /* emit('update:emitSearch', Object.assign({}, formModel.value))
  emit('refreshData', Object.assign({}, formModel.value)) */
}
const resetSubmit = () => {
  searchFormRef.value.clearValidate()
  searchFormRef.value.resetFields()
  emit('update:emitSearch', null)
  emit('refreshData', null)
}

defineExpose({
  resetSubmit
})
</script>

<style lang="scss" scoped>
.search-module {
  display: flex;
  // height: 90px;
  // padding: 0 20px;
  flex-direction: column;
  // border-bottom: 1px solid #ccc;
  .title-heading {
    font-size: 20px;
    color: #333333;
    font-weight: 500;
    height: 50%;
    line-height: 3.5;
    // ::before {
    vertical-align: middle;
    // }
  }
  :deep(.el-form-item) {
    margin-bottom: unset;
    margin-right: 40px;
    height: 55px;
    .el-range-separator {
      line-height: 1.5;
    }
  }
  .date-del-margin {
    margin-right: 0px;
  }
  :deep(.el-form-item__label) {
    line-height: 55px;
  }
  /* .date-dash {
    :deep(.el-form-item__label) {
      padding: 0 4px;
    }
  } */
  .search-block {
    display: flex;
    margin: auto 0;
    > div {
      margin-right: 40px;
      /* display: inherit;
      align-items: baseline; */
    }
    :deep(.el-input__inner) {
      height: 30px;
    }
    .search-time {
      :deep(.el-input) {
        width: 158px;
      }
    }
    :deep(.el-input__prefix) {
      right: 5px;
      // left: unset;
    }
    .search-btn {
      // height: 100%;
      line-height: 55px;
      button {
        min-height: unset;
        height: 26px;
        min-width: 62px;
        padding: 0px;
      }
    }
  }
}
</style>

2.index.vue

<template>
 <search :searchForm="searchForm" title="" />
</template>
<script setup>
 import search from '@/components/search'
 // 搜索栏数据
const searchForm = reactive({
  projectName: {
    label: '项目名称',
    component: 'el-input',
    attrs: {
    },
    options: [],
    style: {
    },
    event: {}
  },
  indicatorId: {
    label: '关联病理指标',
    component: 'el-select',
    attrs: {
    },
    options: [],
    style: {
    },
    event: {}
  },
  beginTime: {
    label: '创建时间',
    component: 'el-date-picker',
    attrs: {
      rangeSeparator: '至',
      valueFormat: 'YYYY-MM-DD'
    },
    customPrefix: true,
    customContent: true,
    id: 'start-time',
    type: 'daterange',
    event: {},
    child: {
    }
  }
})
</script>

总结

vue结合elemen-ui的搜索组件封装就写完了,希望小伙伴们喜欢!!!

原文地址:https://blog.csdn.net/qq_27244301/article/details/128674571

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_49388.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注