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

news2024/12/23 10:03:39

由于业务场景的复杂性,需实现:在 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',"")

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

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

相关文章

安装应用与免安装应用差异对比

差异 安装的程序和免安装的应用程序之间有以下几个方面的差别&#xff1a; 安装过程&#xff1a;安装的程序需要通过一个安装程序或安装脚本进行安装。这个过程通常会将应用程序的文件和依赖项复制到指定的目录&#xff0c;并进行一些配置和注册操作。免安装的应用程序则不需要…

vue监听对象属性值变化

一、官方文档 二、实现方法 方法一、直接根据watch来监听 export default {data() {return {object: {username: ,password: }}},watch: {object.username(newVal, oldVal) {console.log(newVal, oldVal)}} }方法二&#xff1a;利用watch和computed来实现监听 利用computed定…

HCL设备启动失败——已经解决

摸索了一个多小时&#xff0c;终于搞定了&#xff0c;首先HCL这款软件是需要安装Oracle VM Visual Box的&#xff0c;小伙伴们安装的时候记得点击安装Visual Box&#xff1b; 安装完后显示设备不能启动&#xff0c;然后我根据这个 HCL模拟器中Server设备启动失败的解决办法_hc…

电路综合-基于简化实频的集总参数电路匹配3-将任意阻抗用集总参数匹配至归一化阻抗

电路综合-基于简化实频的集总参数电路匹配3-将任意阻抗用集总参数匹配至归一化阻抗 前面的相关理论&#xff1a; 电路综合-基于简化实频的集总参数电路匹配1 电路综合-基于简化实频的集总参数电路匹配2-得出解析解并综合 理论这两个已经介绍过了&#xff0c;直接给出案例 代码…

用低代码平台开发应用

低代码一词&#xff0c;有人认为它是第四代编程语言&#xff0c;有人认为它是开发模式的颠覆&#xff0c;也有人认为它是企业管理模式的变革……有很多声音&#xff0c;社区讨论很热烈。 即使这样&#xff0c;至今也有不少人还不知道这项技术&#xff0c;今天笼统的介绍一下低代…

硬件开发笔记(十二):RK3568底板电路电源模块和RTC模块原理图分析

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134429973 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

基于协作mimo系统的RM编译码误码率matlab仿真,对比硬判决译码和软判决译码

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..................................................................... while(Err < TL…

B站批量取消关注

找到关注页面&#xff1a; 右键检查或者按F12进入开发者界面 然后选console&#xff0c;在页面下面输入下面jQuery代码&#xff0c;然后按回车。复制粘贴两次这一页的博主就能全部取消大概20个 然后刷新页面&#xff0c;接着粘贴两边代码&#xff0c;循环如此即可。 $(".…

SSH协议简介与使用

Secure Shell(SSH) 是由 IETF(The Internet Engineering Task Force) 制定的建立在应用层基础上的安全网络协议。它是专为远程登录会话(甚至可以用Windows远程登录Linux服务器进行文件互传)和其他网络服务提供安全性的协议&#xff0c;可有效弥补网络中的漏洞。通过SSH&#xf…

Find My数据线|苹果Find My技术与数据线结合,智能防丢,全球定位

数据线是用来连接移动设备和电脑的&#xff0c;来达到数据传递或通信目的。通俗点说&#xff0c;就是连接电脑与移动设备用来传送视频、铃声、图片等文件的通路工具。现在&#xff0c;随着电子行业日新月异的发展&#xff0c;数据线已经成为了我们生活中不可或缺的部分&#xf…

4核8G服务器价格选择轻量还是CVM合适?

腾讯云服务器4核8G配置优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;轻量应用服务器4核8G12M带宽一年446元、529元15个月&#xff0c;腾讯云百科txybk.com分…

汇编-间接寻址(处理数组)

直接寻址很少用于数组处理&#xff0c;因为用常数偏移量来寻址多个数组元素时&#xff0c;直接寻址并不实用。取而代之的是使用寄存器作为指针(称为间接寻址(indirect addressing) ) 并控制该寄存器的值。如果一个操作数使用的是间接寻址&#xff0c; 就称之为间接操作数(indie…

【机器学习10】循环神经网络

1循环神经网络 RNN通过将神经元串行起来处理序列化的数据。 由于每个神经元能用它的内部变量保存之前输入的序列信息&#xff0c;因此整个序列被浓缩成抽象的表示&#xff0c; 并可以据此进行分类或生成新的序列。 2 循环神经网络的梯度消失或梯度爆炸问题 传统的循环神经网…

再学动态规划

先用一张图来理一下动态规划大纲 参考&#xff1a;https://www.zhihu.com/question/291280715/answer/1007691283 动态规划五个步骤 参考&#xff1a;https://www.zhihu.com/question/25814123 ①判断题目能否用动规解法 ②确定状态 最后一步 子问题 ③转移方程 ④确定初始条…

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-A卷

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-A卷 2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-A卷A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1&#xff1a;登录安全加固&#xff08;Windows, Linux&#xff09;A-2&#…

图像分类系列(四) InceptionV2-V3学习详细记录

前言 上一篇我们介绍了Inception的原始版本和V1版本&#xff1a;经典神经网络论文超详细解读&#xff08;三&#xff09;——GoogLeNet学习笔记&#xff08;翻译&#xff0b;精读代码复现&#xff09; 这个结构在当时获得了第一名&#xff0c;备受关注。但InceptionV1是比较复…

【机器学习】 逻辑回归算法:原理、精确率、召回率、实例应用(癌症病例预测)

1. 概念理解 逻辑回归&#xff0c;简称LR&#xff0c;它的特点是能够将我们的特征输入集合转化为0和1这两类的概率。一般来说&#xff0c;回归不用在分类问题上&#xff0c;但逻辑回归却能在二分类(即分成两类问题)上表现很好。 逻辑回归本质上是线性回归&#xff0c;只是在特…

机器学习中的独立和同分布 (IID):假设和影响

一、介绍 在机器学习中&#xff0c;独立和同分布 &#xff08;IID&#xff09; 的概念在数据分析、模型训练和评估的各个方面都起着至关重要的作用。IID 假设是确保许多机器学习算法和统计技术的可靠性和有效性的基础。本文探讨了 IID 在机器学习中的重要性、其假设及其对模型开…

JUC工具类_CyclicBarrier与CountDownLatch

最近被问到CyclicBarrier和CountDownLatch相关的面试题&#xff0c;CountDownLatch平时工作中经常用到&#xff0c;但是CyclicBarrier没有用过&#xff0c;一时答不上来&#xff0c;因此简单总结记录一下 1.什么是CyclicBarrier&#xff1f; 1.1 概念 CyclicBarrier&#xff…

php中RESTful API使用

1、RESTful AP是什么 RESTful API是一种软件架构风格 RESTful API基于HTTP协议&#xff0c;并遵循一系列约定和原则。它的设计理念是将资源&#xff08;Resource&#xff09;作为核心概念&#xff0c;并通过一组统一的接口对资源进行操作。API的资源通常通过URL进行标识&…