在 el-table 中嵌入 el-checkbox el-input el-upload 多组件,实现复杂业务场景

由于业务场景的复杂性,需实现:在 el-table 表格中 嵌入 el-checkbox 多选框 及 el-input 输入框 及 el-upload 上传组件 ,先附上实现效果图。

在这里插入图片描述

从图片可以看出其实就是一个规格可以带有多个属性的规格表,实现此效果需涉及到的知识点大概有以下:

  1. 阻止冒泡
  2. this.$set() 动态绑定
  3. 图片上传,预览
  4. Scoped slot 获取到 table 内部的状态管理数据

首先搭建表格框架(固定两列),这个比较简单

<el-table>
	<el-table-column
         prop=""
         label="规格"
         width="220px">
    </el-table-column>
    <el-table-column
         prop=""
         label="属性"
         width="660px">
    </el-table-column>
</el-table>

由于行数不固定,行内容非普通的静态数据展示,故需用到 slot 来自定义

:data 属性绑定 commodityPropertyList数据,scope 获取 row, column, $index 和 store 等的表格内部数据

实现表格第一列

<el-table
	:data="commodityPropertyList"
	style="width: 100%"
	>
	<el-table-column
         prop=""
         label="规格"
         width="220px">
         	<template slot-scope="scope">
         		<span style="font-size: 14px;">{{scope.row.propertyName}}</span><i style="margin-left: 10px;" class="el-icon-delete" @click="deleteProperty(scope)" ></i>
         		<div style="display: flex;align-items: center;cursor: pointer;" class="property" @click="changeGPicFlag(scope)">
         			<i  v-if="scope.row.gPicFlag == 1" class="el-icon-circle-check"></i>
         			<i class="el-icon-circle-close" v-else></i>
         			<div>开启图片上传</div>
         		</div>
         	</template>
    </el-table-column>
    <el-table-column
         prop=""
         label="属性"
         width="660px">
    </el-table-column>
</el-table>

补充表格第二列

<el-table
	:data="commodityPropertyList"
	style="width: 100%"
	>
	<el-table-column
         prop=""
         label="规格"
         width="220px">
         	<template slot-scope="scope">
         		<span style="font-size: 14px;">{{scope.row.propertyName}}</span><i style="margin-left: 10px;" class="el-icon-delete" @click="deleteProperty(scope)" ></i>
         		<div style="display: flex;align-items: center;cursor: pointer;" class="property" @click="changeGPicFlag(scope)">
         			<i  v-if="scope.row.gPicFlag == 1" class="el-icon-circle-check"></i>
         			<i class="el-icon-circle-close" v-else></i>
         			<div>开启图片上传</div>
         		</div>
         	</template>
    </el-table-column>
    <el-table-column
         prop=""
         label="属性"
         width="660px">
         	<template slot-scope="scope">
         		<el-checkbox-group v-model="checkPropertyList">
         			<el-checkbox v-for="(item1,index) in scope.row.options"   :label="item1" :key="item1.id" :disabled="pageType == 'view'">
         				<div  style="display: flex;justify-content: center;align-items: center;margin-bottom: 20px;">
         					<div style="width: 50%;font-size: 14px;">{{item1.optionValue}}</div>
         					<el-input :disabled="pageType == 'view'" style="margin-right: 20px;" size="mini" v-model="item1.optionAlias" placeholder="备注(可选)"></el-input>
         					<el-input :disabled="pageType == 'view'" size="mini" v-model="item1.optionSort" placeholder="排序,输入数字"></el-input>
         					<span v-if="scope.row.gPicFlag == 1" style="margin-left: 20px;">
         						<div v-if="item1.gPicUrl" style="display: inline;">
         							<el-image ref="preview2"  :preview-src-list="[showgPicUrl]" style="width: 20px;height: 20px;" :src="item1.gPicUrl"></el-image>
         							<i @click.stop.prevent="deleteImage(scope,index)" v-if="pageType != 'view'"  style="margin-left: 10px;font-size: 12px;" class="el-icon-delete" ></i>
         							<i style="margin-left: 10px;font-size: 12px;" @click.stop.prevent="previewImage2(scope,index)" class="el-icon-view"></i>
         						</div>
         						<el-upload v-show="!item1.gPicUrl && pageType != 'view'" ref="upload" class="insert-block" 
                                      style="display: inline-block; vertical-align: top; margin-right: 8px;"
                                       action="/api/mdm/upload/image" :limit="1"  accept=".jpg,.jpeg,.png"  
                                       :on-success="handleSuccess2" :on-error="handleFormatError"
                                          :file-list="imgFilesListOfOnce" :show-file-list="false">
                                           <i slot="default" @click.stop.prevent="uploadImage(scope,index)" class="el-icon-upload2"></i>
                                 </el-upload>
                                 <span>尺寸:800*800px,最多1</span>
         					</span>
         				</div>
         			</el-checkbox>
         		</el-checkbox-group>
         	</template>
    </el-table-column>
</el-table>

到此,表格的页面及样式已基本完成,接下来还需处理事件逻辑。

表格第一列事件处理

changeGPicFlag(scope) {
     if(this.pageType == 'view') {
          return
      }
     this.commodityPropertyList.forEach((item,index) => {
          if(index == scope.$index) {
               item.gPicFlag = item.gPicFlag == 1 ? 0 : 1
          }
      })
          this.commodityPropertyList = [...this.commodityPropertyList]
               
}

表格第二列事件处理

deleteImage(scope,index) {
          this.commodityPropertyList[scope.$index].options[index].gPicUrl = ""
          this.commodityPropertyList = [...this.commodityPropertyList] //实时更新修改的数据
},

previewImage2(scope,index) {
      this.showgPicUrl = this.commodityPropertyList[scope.$index].options[index].gPicUrl
      this.$refs.preview2[0].showViewer = true
},

uploadImage(scope,index) {
      let num = 0
      let list = []
      list = this.commodityPropertyList.filter((item,index) => index < scope.$index)
      list.forEach(item => { num += item.options.length})
       //阻止冒泡到选checkbox
      this.upload2Flag.propertyIndex = scope.$index
      this.upload2Flag.optionsIndex = index
      this.$refs['upload'][num+index].$refs['upload-inner'].handleClick()
},

表格“属性”列由 多选框checkbox、输入框input、 图片上传upload 等组件组成,从代码可看出 checkbox-group 包裹 input等组件,所以当在输入框输入或点击上传图片等操作时,都会触发勾选/取消勾选多选框。这效果不是我们想要的,我们只是想操作上传图片,所以需要在定义事件时加 @click.stop.prevent = 事件名 来阻止冒泡(阻止触发勾选操作)

于是又有问题出现了,当在 el-upload 组件加上 @click.stop.prevent = 事件名 时,你会发现,操作点击时不会触发弹出选择文件窗口,这是因为加了阻止冒泡后没有触发到选择文件的操作,这就需要我们自己在事件处理中写逻辑去触发。

1.需要在 el-upload 组件定义 ref
2.用 index 结合 num 找出被点击的那个 el-upload 组件

    uploadImage(scope,index) {
       let num = 0
       let list = []
       list = this.commodityPropertyList.filter((item,index) => index < scope.$index)
       list.forEach(item => { num += item.options.length})
         //阻止冒泡到选checkbox
       this.upload2Flag.propertyIndex = scope.$index
       this.upload2Flag.optionsIndex = index
       this.$refs['upload'][num+index].$refs['upload-inner'].handleClick()//触发选择文件的弹窗
 },

在实现的过程中,我还碰到一个输入框不能输入的问题,我操作输入之后,没有动静,再点击勾选操作时就可以正确显示出来了。于是我猜想了很多种可能并一一去验证
1.el-checkbox 不能包裹其他标签?(从网上搜集到很少有这样复杂地使用多选框)
2.没有加 slot-scope="scope" ?

最后在控制台打印后端返回的 commodityPropertyList 数据中发现,其 options 数组下没有 optionAliasoptionSort 字段,需要前端这边自己加,最开始我是这样加的

//在commodityPropertyList获取数据的地方
......
this.commodityPropertyList.forEach((group) => {
      if (group.options && group.options.length) {
             group.options.forEach((item) => {
                 item.optionAlias = ""
				 item.optionSort = ""
                  var key = item.propertyCode + ":" + item.optionCode
                  var prop = this.propSpenMap.get(key)
                     if (prop) {
                           group.gPicFlag = prop.gPicFlag == 1 ? 1  : 0    
                           propList.push(prop)
                           this.checkPropertyList.push(item)
                     }
             })
        }
})

最后发现还是不可以,于是我尝试 this.$set() 就可以了,是因为 v-model 需要双向绑定,而 this.$set() 则是启用了动态绑定

将上面代码的
item.optionAlias = ""
item.optionSort = ""

改成
this.$set(item,'optionAlias',"")
this.$set(item,'optionSort',"")

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter NestedScrollView 、SliverAppBar全解析,悬浮菜单的应用

在我们开发过程中经常会使用到悬浮菜单的使用&#xff0c;当我们滑动到指定位置后&#xff0c;菜单会自动悬浮。 实现效果如下&#xff08;左为滑动前、右为滑动后&#xff09;&#xff1a; 上述便是通过NestedScrollView 、SliverAppBar实现的效果&#xff0c;通过两个控件我…

二层、三层交换机之间到底有什么区别?

简单地说 二层交换机&#xff0c;没有充当三层网关角色的能力&#xff08;Capability&#xff09;。三层交换机&#xff0c;首先也是二层交换机。但是&#xff0c;它有一个额外的能力&#xff08;Capability&#xff09;&#xff0c;软件配置一下&#xff0c;可以充当三层网关…

新加坡金融科技节,IMF呼吁加快CBDCs数币的框架

CBDCS,那CBDC是什么呢&#xff1f; 中央银行数字货币 CBDC&#xff08;英文&#xff1a;Central Bank Digital Currency&#xff09;&#xff0c;指的是数字版本的国家货币. 我们现在经常听到的数字人民币&#xff0c;也就是中国的CBDC. 在传统与创新的交汇处&#xff0c;一种…

Python自动化测试之request库(五)

在做接口测试的过程中&#xff0c;我们经常会遇到参数关联&#xff0c;也就是我们经常所说的上一个接口返回是下一个接口的请求。 参数关联 在应用业务接口中&#xff0c;完成一个业务功能时&#xff0c;有时候一个接口可能不满足业务的整个流程逻辑&#xff0c;需要多个接口…

Linux线程创建,退出,等待

目录​​​​​​​ 一 为什么使用线程 1.1概念 1.2使用线程的理由 二 线程的创建&#xff0c;退出&#xff0c;等待 2.1 线程创建 2.2 线程退出 2.3.线程等待 2.4. 线程ID获取及比较 一 为什么使用线程 1.1概念 概念&#xff1a;"进程——资源分配的最小单位&…

拼多多商家私信群发脚本,按键精灵版工具,源码分享

也是用按键精灵写的&#xff0c;实现的功能就是通过图色识别拼多多商品列表然后逐个对商家客服进行私信&#xff0c;私信内容可以在脚本里面提前配置好&#xff0c;代码怎么部署&#xff1f;回答&#xff1a;粘贴到你的按键精灵就行了&#xff0c;因为代码完全开源。 UI界面&a…

uni-app 使用vscode开发uni-app

安装插件 uni-create-view 用于快速创建页面 配置插件 创建页面 输入页面名称&#xff0c;空格&#xff0c;顶部导航的标题&#xff0c;回车 自动生成页面并在pages.json中注册了路由 pages\login\login.vue <template><div class"login">login</d…

数字化医学影像管理系统PACS源码

PACS系统&#xff0c;意为影像归档和通信系统。它是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;各种X光机&#xff0c;各种红外仪、显微仪等设备产生的图像&#xff09;通过各…

技术实践|高斯集群服务器双缺省网关故障分析

导语&#xff1a;当前国产化数据库使用范围越来越广泛&#xff0c;在GaussDB数据库的使用过程中难免会遇到一些问题&#xff0c;有的问题是由于在安装过程中没有注意细节而产生的&#xff0c;多数隐患问题都是在特定场景下才会暴露出来&#xff0c;且暴露的时间未知&#xff0c…

SOLIDWORKS参数化设计之主参数设置

SOLIDWORKS参数化设计是通过主参数来驱动整个模型的变化&#xff0c;因此确定主参数是很重要的部分。主参数可以是数值&#xff0c;也可以是条件&#xff0c;可以手动输入&#xff0c;也可以做成下拉列表。今天我们就来看看主参数的下拉列表是如何做到的。 SolidKits.AutoWork…

2023-11-17 LeetCode每日一题(最大和查询)

2023-11-17每日一题 一、题目编号 2736. 最大和查询二、题目链接 点击跳转到题目位置 三、题目描述 给你两个长度为 n 、下标从 0 开始的整数数组 nums1 和 nums2 &#xff0c;另给你一个下标从 1 开始的二维数组 queries &#xff0c;其中 queries[i] [xi, yi] 。 对于…

企鹅h5充值encrypt_msg h5 1.0.21补环境算法

如图 主要的加密参数就是这个版本号为H5_1.0.21的encrypt_msg参数 这次采用的方式为jsdom补环境 需要注意的是 我们得从前置页面&#xff08;https://pay.***.com/h5/index.shtml?xxxx&#xff09;拿到关键的入参 用正则匹配出ops大数组以及用户信息openId/openKey等参数 成品…

在誉天学习华为认证,有真机吗

通过培训机构学习华为认证&#xff0c;特别是在HCIE的课程学习中&#xff0c;很多人关心的就是培训机构是否有真机能够进行华为认证的相关实验&#xff0c;今天我们一起来看看&#xff0c;在誉天学习华为认证&#xff0c;有真机吗&#xff1f; 誉天总部数据中心机房和誉天总部一…

el-select组件绑定change怎么获取label和value值

组件中change回调只能获取到value,但是有时候需求是要传两个参数&#xff08;elementui 封装的change只能获取到value,我们可以通过原生事件去获取option值&#xff09;。 如果要在element组件上触发原生事件&#xff0c;一律都得加.native修饰符&#xff0c;否则无法触发事件。…

适用于4×4MiMo 4G/5G,支持GNSS和WiFi 6E的车载天线解决方案

德思特Panorama智能天线致力于为用户提供在各类复杂场景中稳定供给5G、WIFI和GNSS信号的卓越性能和支持。随着5G新频段逐渐应用、WIFI 6E频率升级以及多频定位应用的普及&#xff0c;传统的BAT[G]M-7-60[-24-58]系列天线已不再适用于当前多变的环境。 然而&#xff0c;BAT天线的…

c语言学习记录 c语言本身有什么

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

骨传导耳机品牌排名前十,盘点最受欢迎的五款TOP级骨传导耳机

骨传导耳机品牌排名前十&#xff0c;最受欢迎的五款TOP级骨传导耳机是什么&#xff1f; 耳机市场上有很多品牌和型号的骨传导耳机&#xff0c;每个人对耳机的需求和使用场景也不尽相同。因此&#xff0c;在选择耳机时&#xff0c;确实不能盲目跟风或者仅仅看重品牌。为了帮助大…

中部高标准农田建设大会将于2024年8月在郑州召开

无农不稳、无粮则乱。农业保的是生命安全、生存安全&#xff0c;粮食安全是国家安全的重要基础。河南作为全国重要农业大省是国家重要粮食主产区&#xff0c;始终把粮食安全扛在肩上、抓在手上&#xff0c;把加快建设农业强省摆在重要位置。由振威国际会展集团等单位联合主办的…

骨传导蓝牙耳机排行榜,音质最好的五款TOP级骨传导耳机

骨传导蓝牙耳机排行榜中&#xff0c;音质最好的骨传导耳机有哪些呢&#xff1f; 目前骨传导耳机市场上有许多品牌&#xff0c;每个品牌都有自己的特点和优势。然而&#xff0c;在音质等性能方面&#xff0c;南卡品牌可以被认为是最好的。许多使用过骨传导耳机的用户都知道&…

鉴源实验室 | DoIP协议网络安全攻击

作者 | 付东杰 上海控安可信软件创新研究院工控网络安全组 来源 | 鉴源实验室 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 01 背 景 随着科技的迅猛发展&#xff0c;汽车行业正经历着前所未有的数字化变革。现代汽车中使用70多个电子控制单元&#x…