当前位置: 首页 > news >正文

三、ElementPlus下拉搜索加弹窗组件的封装

        近期产品提出了一个需求,要求一个form的表单里面的一个组件既可以下拉模糊搜索,又可以弹窗搜索,我就为这个封装了一个组件,下面看效果图。

        00eef765102e486482f9b2a0a92043b5.gif

d9bef8291ae24f4493f29edbabea8504.png

 

效果大家看到了,下面就看组件封装和实现方法

 

第一步,组件封装,我取名为C_SerachBtn 组件,其中的C_Select组件也可以用el-select组件来代替,C_Select使我们自己封装的组件。

1fb50761e1e44a21a732c5d27c864127.png

 

<template><div class="search-box"><C_Selectv-bind="$attrs"v-model="_modelValue"filterableremoteclearablereserve-keywordremote-show-suffix:remote-method="overhaulProjectCodeMethod":options="_options || []":loading="_loading"@focus="focus"@change="handleChangeSearchBtn($event)"/><el-button:icon="Search"color="#f5f7fa"class="search-box-btn"@click="handleBtnClick"/></div>
</template><script lang="ts" setup>
import { isFunction } from '@/utils/d_is'
import { Search } from '@element-plus/icons-vue'interface Props {value: anylabel?: anyoption?: anyoptions?: any[]// query代表的值queryValue: string// 列表label代表的字段labelField?: string// 列表label代表的字段valueField?: stringdisabledField?: string// 下拉数据请求接口api?: (arg?: any) => Promise<any>// 接口参数params?: any//返回的值和赋值的值callBackNames: any[],// 返回列表数据字段resultField?: string// 是否立即请求接口,否则将在第一次获取焦点时触发请求immediate?: boolean// 是否多选multiple?: boolean
}const props = withDefaults(defineProps<Props>(), {labelField: 'label',valueField: 'value',disabledField: 'disabled',resultField: 'records',queryValue:'',callBackNames:[],immediate: true,
})
const emits = defineEmits(['update:value','update:label','update:option','change','visible-change','remove-tag','clear','blur','focus',// 下拉接口重新请求,数据更新后触发'options-change',//按钮点击'btn-click',
])
const _selectRef = ref()
const _modelValue = ref(props.value || '')
const _options = ref(props.options || [])
const _option = ref(props.option || {})
const _loading = ref(false)watch(() => props.options,(newVal) => {if (props.api) return_options.value = newVal},{deep: true,}
)watch(() => props.option,(newVal) => {_option.value = newVal},{deep: true,}
)watch(() => props.value,(newVal) => {if (props.multiple && !Array.isArray(newVal)) {console.error('multiple 为true时,传入的value数据类型必须为array')}_modelValue.value = newVal},{immediate: true,}
)watch(() => _modelValue.value,() => {emits('update:value', _modelValue.value)},{immediate: true,}
)//标准项目编号-搜索开始
const overhaulProjectCodeMethod = async (query: string) => {if (query) {const api = props.apiif (!api || !isFunction(api)) return_options.value = []_loading.value = truelet obj= {pageNum: 1,pageSize: 10,...props.params,}obj[props.queryValue] = querylet res = await api(obj)_loading.value = falselet arr = props.labelField.split(',')_options.value = res.records.map((item) => {let str =''arr.forEach(p=> str += item[p] +' ')return {label: str,value: item[props.valueField],name: item[props.valueField],key: item[props.valueField],...item,}})} else {_options.value = []}
}async function handleChangeSearchBtn(val) {if(!val){props.callBackNames.forEach(p=>{_option.value[p.value]  = ''})return}let obj = _options.value.filter((el) => el.value == val)[0]props.callBackNames.forEach(p=>{_option.value[p.value]  = obj[p.name]})change(val)
}//按钮点击
const handleBtnClick = () => {emits('btn-click', unref(_options))
}// 下拉接口重新请求,数据更新后触发
const emitChange = () => {emits('options-change', unref(_options))
}
// 当 input 获得焦点时触发
const focus = (e) => {emits('focus', e)
}
// 选中值发生变化时触发
const change = (val) => {let data = _options.value?.filter((x) => x.value == val)emits('change', val, data)
}
// 下拉框出现/隐藏时触发
const visibleChange = (val: boolean) => {handleFetch()emits('visible-change', val)
}
// 多选模式下移除tag时触发
const removeTag = (val) => {emits('remove-tag', val)
}
// 可清空的单选模式下用户点击清空按钮时触发
const clear = (e) => {emits('clear', e)
}
// 当 input 失去焦点时触发
const blur = (e) => {emits('blur', e)
}
const getOptions = () => _options.value
defineExpose({ selectMethods: _selectRef, getOptions })
</script><style scoped>
.search-box{display: flex;width: 100%;.search-box-btn{border-top-left-radius: 0px;border-bottom-left-radius: 0px;border-top: 1px solid #dcdfe6;border-right: 1px solid #dcdfe6;border-bottom: 1px solid #dcdfe6;color: #a8abb2;}
}
</style>

第二步,页面使用,在页面中el-table中当做slot使用,我的slot取名为 overhaulProjectCode

  <!-- 标准项目编号 --><template #overhaulProjectCode="{ row, index }"><C_SearchBtnv-model:value="row.overhaulProjectCode":placeholder="'请选择'":api="ListOverhaulProject":option="row":queryValue="'overhaulCode'":params="{deviceCode: 0,status: 3,}":labelField="'overhaulCode,overhaulName'":valueField="'overhaulCode'":options="[]":callBackNames="[{name: 'id',value: 'overhaulProjectId',},{name: 'overhaulCode',value: 'overhaulProjectCode',},{name: 'overhaulName',value: 'overhaulProjectName',},]"@btn-click="handleOverhaulCodeModalVisible(row, index)"@focus="handleFocus(index)"/></template>

第三步,弹窗,和一般的弹窗一样,自行封装。

<!-- 生产设备 --><materialOnetitle="选择生产设备"v-if="materialOneModalVisible":data="curRow"v-model:visible="materialOneModalVisible"@select="handleMaterialOneSelect2"@close="materialOneModalVisible = false"/>

以上就是基本的做的c_SerachBtn的组件的封装,其中的一些例如handleOverhaulCodeModalVisibl  和 handleFocus   方法需要自己定义,根据自己的具体的需求进行修改。

 

http://www.lryc.cn/news/462772.html

相关文章:

  • androidStudio编译导致的同名.so文件冲突问题解决
  • 大学新生编程入门指南:如何选择编程语言与制定学习计划
  • SpringAI快速上手
  • 07 django管理系统 - 部门管理 - 搜索部门
  • 数据操作学习
  • 什么是网络代理
  • 安防监控摄像头图传模组,1公里WiFi无线传输方案,监控新科技
  • 问:JVM中GC类型有哪些?触发条件有哪些?区别是啥?
  • 【操作系统的使用】Linux 输入输出重定向:掌握控制台的高级用法
  • 无线通信中的四个关键概念:OFDM、多径效应、CSI和信道均衡
  • 如何高效规划千人大会?数字化会议管理的实战经验分享!建议收藏!
  • mysql指令笔记(基本)
  • web前端-----html5----用户注册
  • bug的定义和测试
  • Kamailio-Sngrep 短小精悍的利器
  • 9.6 Linux_I/O_IO模型
  • React 探秘(一):fiber 架构
  • poi通过在word中写入了表格,通过libreoffice转换成PDF后,word中刚才画的表格宽度无限拉伸问题的解决。
  • 尚硅谷rabbitmq2024 集群篇仲裁队列 第52节 答疑
  • 《Spring Cloud 微服务:构建高效、灵活的分布式系统》
  • OpenFeign 入门与实战:快速搭建 Spring Cloud 微服务客户端
  • 上门按摩系统开发方案源码搭建
  • 【数据结构】宜宾大学-计院-实验四
  • selenium的IDE插件进行录制和回放并导出为python/java脚本(10)
  • 从0到1封装一个image/pdf预览组件
  • Android build子系统(02)Ninja语法与复杂依赖构建解读
  • JavaScript的第三天
  • 初识git · 有关模型
  • 基于SpringBoot+Vue+uniapp的海产品加工销售一体化管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 解锁机器人视觉与人工智能的潜力,从“盲人机器”改造成有视觉能力的机器人(下)