7
实现方式
我们以文本类的查询为例进行介绍,我们先做一个查询方式的组件,然后做一个文本的查询子控件。
查询方式
<template> <el-dropdown @command="handleCommand"> <span class="el-dropdown-link"> {{kindName}}<i class=" el-icon--right" :class="{'el-icon-arrow-down': isUp, 'el-icon-arrow-up': !isUp}">i> span> <template #dropdown> <el-dropdown-menu> <el-dropdown-item v-for="kindId in findKind" :key="'s_kind_'+ kindId" :command="kindId" > {{findKindList[kindId].name}} el-dropdown-item> el-dropdown-menu> template> el-dropdown> template>
使用 el-dropdown 做一个选择列表。
import { defineComponent, ref } from'vue' import { findKindList } from'/nf-control-web' // 查询方式的 select exportdefault defineComponent({ name: 'el-find-kind', props: { // 返回选择的查询方式 modelValue: [Number], // 需要显示的查询方式 findKind: { type: Array, default: () => { return [411] } } }, emits: ['update:modelValue', 'change'], setup (props, context) { const kindName = ref(findKindList[props.modelValue].name) const handleCommand = (command) => { kindName.value = findKindList[command].name context.emit('update:modelValue', command) context.emit('change', command) } return { isUp, kindName, findKindList, handleCommand } } })
查询子控件
<template> <div style="float:left;width:65px;text-align:center;"> <find-kind v-model="findChoiceKind" :findKind="findKind" @change="myChange" /> div> <div :style="{width: (150 * colCount - 10 ) + 'px'}" style="float:left;"> <div style="float:left;" :style="{width: (150 * colCount - 40 ) + 'px'}"> <component :is="ctlList[controlType]" v-model="findText" v-bind="$attrs" :delay="delay" :colName="colName" @myChange="myChange"> component> div> div> template>
放置查询方式和查询用的组件。
import { defineComponent } from'vue' // 引入查询子控件的管理类 import { findItemManage } from'/nf-control-web' // 查询方式的控件 import selectFindKind from'./s-findkind.vue' // 异步组件,引入表单子控件 import { formItemToFindItem } from'../nf-el-find-item/map-el-find-item.js' /* * 查询子控件,文本类 * * 单行文本 * * 多行文本 * * ulr、电话、邮箱等 */ exportdefault defineComponent({ name: 'el-find-item-text', inheritAttrs: false, props: { controlId: Number, // 控件ID controlType: Number, // 控件类型 colName: String, // 字段名称 modelValue: [Array, String], // 查询结果,数组形式 colCount: { // 占用空间 type: Number, default: 1 }, findKind: { // 查询方式 type: Array, // , 407, 408 default: () => { return [403, 401, 402, 404, 405, 406] } }, delay: { // 防抖 type: Number, default: 600 } }, components: { 'find-kind': selectFindKind }, emits: ['update:modelValue', 'my-change'], setup (props, context) { // 表单子控件 to 查询子控件 的 字典 const ctlList = formItemToFindItem const { findChoiceKind, // 选择的查询方式 findText, // 一个关键字查询 mySubmit } = findItemManage(props, context) // 设置默认查询方式 findChoiceKind.value = props.findKind[0] // 提交查询结果 const myChange = () => { // 一个关键字查询 mySubmit(findText.value) } return { ctlList, // 控件字典,用于加载具体的控件 findChoiceKind, // 查询方式 findText, // 一个查询关键字 myChange // 触发提交事件 } } })
设置需要的属性,比如具体的查询方式、防抖时间间隔等。因为文本查询比较简单,所以只需要简单的提交查询条件即可。
查询控件
<template> <el-card class="box-card"> <el-scrollbar> <div class="flex-content" style="min-width:400px;"> <el-form inline label-position="right" :model="findItemModel" ref="formControl" class="demo-form-expand" label-width="1px" size="mini" > <el-form-item style="width:100px"> <el-dropdown size="small"> <el-button type="primary"> 快捷查询<i class="el-icon-arrow-down el-icon--right">i> el-button> <template #dropdown> <el-dropdown-menu> <el-dropdown-item @click="quickClick(0)" > 快捷查询 el-dropdown-item> <el-dropdown-item v-for="(item, key, index) in customer" :key="'quick_' + index" @click="quickClick(key)" > {{item.title}} el-dropdown-item> el-dropdown-menu> template> el-dropdown> el-form-item> <el-form-item v-for="(ctrId, index) in arrQuickFind" :key="'find_quick_'+index" style="border:1px solid #cfe1f3;min-height:33px;" :style="{width: ( 160 * getCtrMeta(ctrId).colCount + 80) + 'px'}" > <template v-if="getCtrMeta(ctrId).controlType === 1"> <slot :name="ctrId">父组件没有设置插槽slot> template> <template v-else> <component :is="ctlList[getCtrMeta(ctrId).controlType]" v-model="findItemModel[ctrId]" v-bind="getCtrMeta(ctrId)" @myChange="mySubmit"> component> template> el-form-item> <el-form-item style="width:60px"> <el-button type="primary" round @click="moreOpen">更多el-button> el-form-item> el-form> div> el-scrollbar> el-card> <findmore :allFind="allFind" :reload="reload" :itemMeta="itemMeta" :findKind="findKind" :moreFind="moreFind" v-model:isShow="isShow" /> template>
这里是快捷查询,更多查询做成了单独的组件,这样可以让模板代码简洁一点,不至于太乱。
/** * @function div 格式的查询控件 * @description 可以依据 json 动态生成查询控件 * @returns {*} Vue 组件,查询控件 */ exportdefault { name: 'el-find-div', components: { findmore }, props: { ...findProps }, setup (props, context) { // 控件字典 const ctlList = findItemListKey // 依据ID获取组件的meta,因为 model 不支持[]嵌套 const getCtrMeta = (id) => { return props.itemMeta[id] || {} } const { moreFind, // 接收更多查询 更多查询里面子控件的事件 isShow, // 抽屉是否打开 arrQuickFind, // 快捷栏的数组 findItemModel, // 查询子控件的model moreOpen, // 点击更多,清空快捷 quickClick, // 个性化方案的单击事件 mySubmit // 查询子控件的事件 } = findManage(props, context) return { isShow, // 抽屉是否打开 moreFind, // 接收更多查询 arrQuickFind, // 快捷栏的数组 ctlList, // 子控件字典 resetForm, // 重置表单 formControl, // 获取表单的dom getCtrMeta, // 返回子控件的meta findItemModel, // 查询子控件的model moreOpen, // 点击更多,清空快捷 quickClick, // 个性化方案的单击事件 mySubmit } } }
代码比较多,这里是 setup 部分,主要负责代码函数的整合。减少代码混乱的程度。