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

news2024/12/28 4:31:21

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

        

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

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

<template>
  <div class="search-box">
    <C_Select
      v-bind="$attrs"
      v-model="_modelValue"
      filterable
      remote
      clearable
      reserve-keyword
      remote-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: any
  label?: any
  option?: any
  options?: any[]
  // query代表的值
  queryValue: string
  // 列表label代表的字段
  labelField?: string
  // 列表label代表的字段
  valueField?: string
  disabledField?: 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.api
    if (!api || !isFunction(api)) return
    _options.value = []
    _loading.value = true
    let obj= {
      pageNum: 1,
      pageSize: 10,
      ...props.params,
    }
    obj[props.queryValue] = query
    let res = await api(obj)
    _loading.value = false
    let 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_SearchBtn
            v-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>

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2209982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第1章 开发板功能及使用介绍

1.开发板功能及使用介绍 本章主要内容 1.开发板功能介绍 2.开发板使用方法 介绍 STM32介绍 本章主要内容&#xff1a; 1.什么是STM32 2.STM32与ARM的关系 3.STM32F407ZGT6介绍 4.STM32能做什么 1.什么是STM32 从字面意义来看&#xff1a; ST&#xff1a;意法半导体&#xf…

HarmonyOS NEXT 应用开发实战(三、ArkUI页面底部导航TabBar的实现)

在开发HarmonyOS NEXT应用时&#xff0c;TabBar是用户界面设计中不可或缺的一部分。本文将通过代码示例&#xff0c;带领大家一同实现一个常用的TabBar&#xff0c;涵盖三个主要的内容页&#xff1a;首页、知乎日报和我的页面。以模仿知乎日报的项目为背景驱动&#xff0c;设定…

【Spring AI】Java实现类似langchain的第三方函数调用_原理与详细示例

Spring AI 介绍 &#xff1a;简化Java AI开发的统一接口解决方案 在过去&#xff0c;使用Java开发AI应用时面临的主要困境是没有统一且标准的封装库&#xff0c;导致开发者需要针对不同的AI服务提供商分别学习和对接各自的API&#xff0c;这增加了开发难度与迁移成本。而Sprin…

Android常用界面控件——ProgressBar

ProgressBar 目录 ProgressBar 在XML中定义ProgressBar ProgressBar风格样式 ProgressBar常用XML属性 在Java代码中控制ProgressBar 实例 什么是ProgressBar&#xff1f; ProgressBar是Android中的一个视图控件&#xff0c;主要用于表示一个任务的进度情况&#xff0c;…

针对Ubuntu20.04 中的 Docker 配置可用镜像源(包含国内可用镜像源)

文章目录 写在前面一、Docker 官方源二、更换Docker 国内可用镜像源 &#xff08;推荐使用&#xff09;参考链接 写在前面 自己的测试环境&#xff1a; Ubuntu20.04&#xff0c;docker-27.3.1 一、Docker 官方源 打开 /etc/docker/daemon.json文件&#xff1a; sudo gedit …

Python快速编程小案例--逢7拍手小游戏

提示&#xff1a;&#xff08;个人学习&#xff09;&#xff0c;案例来自工业和信息化“十三五”人才培养规划教材&#xff0c;《Python快速编程入门》第2版&#xff0c;黑马程序员◎编著 逢7拍手游戏的规则是&#xff1a;从1开始顺序数数&#xff0c;数到有7或者包含7的倍数的…

查缺补漏----时间复杂度

1.如果每一次循环变量都是&#xff0c;那么直接将每一层变量的最大遍历次数相乘 第一个代码段&#xff1a;O&#xff08;n^3&#xff09; 第二个代码段&#xff1a;O&#xff08;n*i*j&#xff09;,由于 i 的范围0~n-1&#xff0c;所以取n&#xff0c;j 同理&#xff0c;所以最…

Java | Leetcode Java题解之第473题火柴拼正方形

题目&#xff1a; 题解&#xff1a; class Solution {public boolean makesquare(int[] matchsticks) {int totalLen Arrays.stream(matchsticks).sum();if (totalLen % 4 ! 0) {return false;}int len totalLen / 4, n matchsticks.length;int[] dp new int[1 << n…

【hot100-java】从前序与中序遍历序列构造二叉树

二叉树篇 首先创建一个映射来存储中序遍历中值与索引的关系&#xff0c;然后通过递归调用函数dfs来构建二叉树。函数dfs接受前序遍历和中序遍历的左右边界索引以及前序遍历和中序遍历的列表和映射作为参数&#xff0c;在每次递归中&#xff0c;先判断边界条件&#xff0c;如果左…

部署 Open WebUI

1. 安装docker 2.启动Hyper-v 3.下载 安装 WSL 4. 打开 DeskDocker 5. 打开 运行 ollama 参考 Windows 部署 ollama-CSDN博客 6. 部署 运行 open webui docker docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gateway -v open-webui:/app/backend/data -…

Flutter Transform 学习

Transform可以在其子组件绘制时对其应用一些矩阵变换来实现一些特效,允许在渲染子部件之前对它们进行变换。 一、Transform构造函数与属性 class Transform extends SingleChildRenderObjectWidget {/// Creates a widget that transforms its child.const Transform({super.k…

C语言 | 第十六章 | 共用体 家庭收支软件-1

P 151 结构体定义三种形式 2023/3/15 一、创建结构体和结构体变量 方式1-先定义结构体&#xff0c;然后再创建结构体变量。 struct Stu{ char *name; //姓名 int num; //学号 int age; //年龄 char group; //所在学习小组 float score; //成绩 }; struct Stu stu1, stu2; //…

InternVL2-40B 荣登开源模型榜首丨SuperCLUE中文多模态大模型基准10月榜单

在今年 7 月 4 日举行的 2024 WAIC 科学前沿主论坛上&#xff0c;书生万象多模态大模型&#xff08;InternVL 2.0&#xff09;正式发布&#xff0c;并陆续开源了 1B、2B、4B、8B、26B、40B 以及 76B 共 7 个参数版本的模型。书生万象支持图像、视频、文字、语音、三维点云等模态…

Qt媒体播放器实现

本文介绍Qt媒体播放器实现。 Qt应用程序有时会涉及到视频文件的播放&#xff0c;Qt提供了QVideoWidget类实现视频和音频的播放&#xff0c;本文基于QVideoWidget类实现一个简单的媒体播放器。 1.自定义类&#xff08;基于QVideoWidget类&#xff09; 由于Qt并未提供专门的控…

手写简易shell

我们如果要写一个简易的shell我们要&#xff0c;其实我们搞一个程序替换就行了。 我们分为五部完成 在其中我们最难搞的就是环境变量的更新&#xff0c;因为当我们搞一个子程序出来时&#xff0c;我们子进程的环境变量表是从父进程继承下来的&#xff0c;当我们用cd命令时只会更…

C# 屏幕录制工具

屏幕录制工具 开发语音&#xff1a;C# vb.net 下载地址&#xff1a;https://download.csdn.net/download/polloo2012/89879996 功能&#xff1a;屏幕录制&#xff0c;声卡采集&#xff0c;麦克风采集。 屏幕录制&#xff1a;录制屏幕所有操作&#xff0c;并转换视频格式&…

电脑无线网wifi和有线网同时使用(内网+外网同时使用)

一、要求 我这里以无线网wifi为外网&#xff0c;有线网卡为内网为例&#xff1a; 一、基本信息 无线wifi&#xff08;外网&#xff09;&#xff1a;ip是192.168.179.235&#xff0c;网关是192.168.179.95有线网&#xff08;内网&#xff09;&#xff1a;ip是192.168.10.25&…

《鸟哥的Linux私房菜基础篇》---1 Linux的介绍与如何开启Linux之路

目录 一、Linux的简单介绍 1、Linux的简介 2、Linux的起源与发展 3、主要特点 4、应用场景 二、开启Linux之路 1、学习Linux的相关知识 2、正规表示法、管线命令、数据流重导向 前言 整体大纲预览 一、Linux的简单介绍 1、Linux的简介 &#xff08;1&#xff09;Linu…

【Trulens框架】用TruLens 自动化 RAG 应用项目评估测试

前言&#xff1a; 什么是Trulens TruLens是面向神经网络应用的质量评估工具&#xff0c;它可以帮助你使用反馈函数来客观地评估你的基于LLM&#xff08;语言模型&#xff09;的应用的质量和效果。反馈函数可以帮助你以编程的方式评估输入、输出和中间结果的质量&#xff0c;从而…

K8S---01初识Kubernetes

一.简介 摘取官网: 概述 | KubernetesKubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统&#xff0c;其服务、支持和工具的使用范围广泛。https://k…