首页 > 其他分享 >组件封装-双el-select联动搜索-实现方案&经验分享

组件封装-双el-select联动搜索-实现方案&经验分享

时间:2024-10-22 17:20:45浏览次数:3  
标签:el 封装 产品 组件 id select 设备

前情提要:

        最近业务中需要实现产品与设备的联动搜索功能,需要两个el-select框,并且每个Select框是支持筛选的,毕竟设备和产品数量较多。这个功能在之前迭代的模块中实现过,但是并没有封装成为组件,现在要开发一个新的业务,其中”产品+设备“的联动搜索效果应用场景还有很多,因此决定将其封装成组件,方便之后使用。

一、组件介绍

(1)product-device-select组件-”产品+设备“ 的概念

        因为我们是做物联网(IoT)平台的相关业务,所以,对这个概念比较熟悉了。就是我登录自己的账号,其中有我公司创建的10个产品,其中不同的产品下有不同数量的设备。如果你不太明白的话,再举个例子:把产品比喻成名著,我有四个产品分别是:西游记、水浒传、三国演义、红楼梦;那么设备就比喻成其中的人物。西游记中可以有孙悟空、猪八戒等;三国演义中有刘备、曹操等等。水浒传里有武松、林冲等等。

        这下应该能理解的多,这样可以方便各位在封装自己公司业务中的组件时,看看是否有相关类似的业务也可以仿照这个思路。

思路图:

如上图所示,我们的最终目的就是封装使用product-device-select组件,方便业务组件使用双select搜索的功能

效果图:

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="vV09Qaz6-1729585520327" src="https://live.csdn.net/v/embed/430506"></iframe>

产品-设备联动搜索

二、组件封装

(1)之前的实现:

    
//页面html部分
    <el-form :inline="true" class="demo-form-inline">
      <el-form-item label="请选择产品:">
       
           <el-select
                :model-value="modelValue"
                :loading="productLoading"
                :remote-method="filterProductList"
                filterable
                remote
                clearable
                placeholder="请选择"
                remote-show-suffix
                :disabled="disabled"
                @change="handleSelectedChange"
           >
             <el-option v-for="item in productOptions" :key="item.productKey" 
                 :label="item.productName" :value="item.productKey!" />
           </el-select>
      </el-form-item>
      <el-form-item label="请选择设备:">

              <el-select
                :model-value="modelValue2"
                :loading="deviceLoading"
                :remote-method="filterDeviceList2"
                filterable
                remote
                placeholder="请选择设备"
                remote-show-suffix
                :disabled="disabled"
                @change="handleSelectedChange"
               >
                  <el-option v-for="item in deviceOptions" :key="item.iotId" 
                   :label="item.deviceName" :value="item.deviceName" />
               </el-select>
      </el-form-item>
      <el-form-item v-if="searchButton">
        <el-button type="primary" @click="onSubmit()">
          查询
        </el-button>
        <!-- <el-button @click="onReset">
          重置
        </el-button> -->
      </el-form-item>
    </el-form>

(2)封装之后: 

        在之前的基础之上我们已经封装过了产品<product-select>与设备<device-select>两个搜索组件,把选择产品的数据和逻辑以及接口调用封装在<product-select>中,把选择设备的数据和逻辑以及接口调用封装在<device-select>组件中,改进之后如下:

    
<el-form :inline="true" class="demo-form-inline">
      <el-form-item label="请选择产品:">
        <product-select v-model="productKey" @change="handleCancelSelect" />
      </el-form-item>
      <el-form-item label="请选择设备:">
        <device-select v-model="deviceName" :product-key="productKey" :disabled="disabled" @change="handleCancelSelect2" />
      </el-form-item>
      <el-form-item v-if="searchButton">
        <el-button type="primary" @click="onSubmit()">
          查询
        </el-button>
        <!-- <el-button @click="onReset">
          重置
        </el-button> -->
      </el-form-item>
</el-form>

js部分:

<script lang="ts" setup>
import ProductSelect from 'components/product-select/index.vue'
import { queryProductList } from '@/api/product'
import type { Product } from '@/types/global'
import DeviceSelect from '@/components/device-select/index.vue'
import { deviceTableList } from '@/api/device'

withDefaults(defineProps <{
  disabled?: boolean,
  deviceTypeParams?: any, // 由业务组件传入,以确定产品的设备类型的不同组合 全部产品可以不传,其他组合以数组形式传入
  searchButton?: boolean,
  label1?: string,
  label2?: string,
}>(), {
  disabled: false,
  deviceTypeParams: undefined,
  searchButton: false,
  label1: '产品:',
  label2: '设备:',
})
const emits = defineEmits(['update', 'change'])

const vm = getCurrentInstance()!
const { $message } = vm.appContext.config.globalProperties

const productKey = ref('')
const deviceName = ref('')
// 设备选择框禁用
const disabledDevice = ref(true)

// 产品回传
function handleCancelSelectProductKey(val:any) {
  console.log('handleCancelSelectProductKey', val)
  productKey.value = val
  deviceName.value = ''
  // 判断产品是否有设备
  deviceTableList({ pageNum: 1, pageSize: 10000, productKey: val }).then((res) => {
    if (!res.deviceDTOList) {
      disabledDevice.value = true
      $message.error('此产品暂无设备,无法调试')
    }
  })
  // 判断产品是否有设备
  if (productKey.value)
    disabledDevice.value = false
  else
    disabledDevice.value = true
}

// 设备回传
function handleCancelSelectDevice(deviceName:any) {
  // 将产品id+设备id 回传给父组件
  emits('change', productKey.value, deviceName)
}

</script>

目前已经大大精简了我们的代码。

(3)封装功能的数据流转及逻辑注意点:

        1.首先在<product-select>中调接口拿到全部产品数据列表,作为给产品的el-select组件中el-option的数据,同时给产品的el-select绑定change事件,当选定产品后,通过change事件使用emits实现子传父,将产品id传递给父组件product-device-select使用

        2.product-device-select组件拿到产品id,通过父传子,传递给<device-select>组件,<device-select>中再根据产品id调用接口获取这个产品下的全部设备的数据。给<device-select>组件中的select同样绑定change事件,监听设备的变化,同样通过emits实现子传父,传递设备id供给product-device-select使用

        3.最后product-device-select中通过自定义事件中,再次使用emits,将获取的产品id和设备id传递给业务组件使用。

注意:

        1.第一个select中的产品值被修改之后,需要同时删除之前的设备值,不然会出现二者不匹配的情况。比如”西游记“中出现了”刘备“,这是不被允许的。

         2.当产品值为空时,设备选择框置灰不可点击选择,这一点也是防止数据紊乱。

三、经验分享

组件封装的基本要求:

        (1)首先就是”开箱即用“。别人几乎无需修改,直接引用后使用。

        (2)”高复用“。在业务中”使用频率较高“的时候,这种功能有必要封装成为组件使用。把组件封装好之后,可以简化之后的业务开发。

        (3)好的拓展性。如果碰到业务上的特殊的需求,可以根据业务中的字段区分判断出来。

        (4)高内聚低耦合。这里的联动搜索,配合使用了两个子组件搜索,有一定的耦合性。应该避免其中的两个子组件修改影响到父组件。

        (5)单一职责原则:一个组件应该只有一个职责,即一个组件只负责完成一个特定的功能。这样可以降低组件的复杂度,易于理解和维护。如果一个组件的功能过于复杂,应该将其拆分成多个独立的组件。

标签:el,封装,产品,组件,id,select,设备
From: https://blog.csdn.net/LM0916/article/details/143157379

相关文章

  • 海量大模型如何一键部署上云?函数计算 x ModelScope 社区给出答案
    作者:魔搭官方大模型在过去一年多时间里的一路技术狂奔,深刻的改变了今天模型和AI的整体应用生态,也给开发者提供纷繁复杂的模型选择。在多样化大模型的背后,OpenAI得益于在领域的先发优势,其API接口今天也成为了业界的一个事实标准。许多开源工具和框架,包括LlamaIndex,LangChain......
  • element-ui中,使用this.$message.success(“登录成功“),如何修改文字的样式呢?
    在element-ui中使用this.$message.success(“注册成功”);时,直接修改文字样式并没有暴露出很方便的接口,因为ElementUI的消息提示组件Message是通过JavaScript动态创建的。但是你可以通过以下方法自定义消息的样式:方法1:使用customClass属性ElementUI的Me......
  • shell脚本技巧—创建和清空文件
    写这篇文章的起因是因为在分析一个脚本时,看到这么一句脚本,如下所示................................>$RMAN_BACKUP/script/rman_backup.sql................................最开始我以为它就是将文件rman_backup.sql清空,这个类似于cat/dev/null>$RMAN_BACKUP/script/rman_......
  • Features of three electronic component platforms: Findchips, JLCPCB, and ICgoodF
    Thecharacteristicsofthreeelectroniccomponentplatforms:Findchips,JLCPCB,andICgoodFindareasfollows:Findchips:Powerfulsearchanddataintegrationfunction.Itcanaggregatedatafrommajordistributors.Userscansearchforinformationonse......
  • el-table回显默认勾选-弹窗
    要使用nextTick()方法+element表格中的toggleRowSelection()方法记得在table标签中添加ref <el-table:data="list"ref="multipleTableRef"><el-table-columntype="selection"width="55"></el-table-column>......
  • [题解]CF825E Minimal Labels
    LPhang为什么是神?思路显然可以想到一个错误的贪心:直接拓扑排序,每一次选择当前可以拓展的点中最小的元素进行编号。由于可能存在一个值较小的元素被藏在一个较大的元素后面,这种贪心就会出问题。出问题的本质原因就是我们希望字典序最小,就得使得越小的位置分配到更小的值。不妨......
  • Amazon Q Developer 实践:零基础创建贪吃蛇游戏
    本文探讨了如何使用AmazonQDeveloper根据结构化的提示词,直接生成一个贪吃蛇游戏原型,并剖析了其背后人工智能的思考和迭代完善过程,展示了人工智能能快速进行游戏原型创作的巨大潜力。原文出处来自作者于2024年9月在community.aws发表的技术文章:“FromConcepttoPlaya......
  • pipeline scm方式
    pipelinescm方式通过scm获取Jenkinsfile1.代码仓库gitlab上项目根目录里包含jenkinsfile文件(可重命名)2.jenkinsjobpipeline作业里选择scm及git配置,路径,文件名称####我们在Jenkins新建一个pipelinejob,命名为My-pipeline-job01,前2步,同上一个示例一样,在M......
  • easyExcel生成excel并导出自定义样式(三)指定列字体样式
    publicclassExcelRowColorHandlerimplementsCellWriteHandler{privatefinalIntegercolumnIndex;privatefinalSet<Integer>redRowIndex;privatefinalSet<Integer>yellowRowIndex;privatefinalSet<Integer>greenRowInd......
  • 动态生成excel动态表头easyExcel
    动态生成excel,内容跟随表头填充 组装调用工具方法:List<FileTitleEntity>titleEntityList=newArrayList<>();titleEntityList.add(newFileTitleEntity("name","姓名"));titleEntityList.add(newFileTitleEntity("idNumber"......