封装一个Element-ui生成一个可行内编辑的表格(vue2项目)

news2025/7/20 9:50:49

这个封装的是一个供整个项目使用的表格,可多次复用.放在一个全局使用的公共组件文件下.

大致功能介绍,封装自定义指令,点击获得焦点,显示输入框,失去焦点显示文本内容,类型是字典决定类型,图片可以显示图片名还是上传图片

 

子组件

<script>
export default {
  props: {
    //生成表头
    fields: {
      type: Array,
      default: () => [],
    },
    //数据
    tableData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {};
  },
  created() {},
// 自定义指令
  directives: {
    focus: {
      inserted: function (el) {
        el.querySelector("input").focus();
      },
    },
  },
  methods: {
    // 点击框 获取焦点 column列,row 行
    cellClick(column, row) {
      column.iseditor = true;
      row.isnameSelected = true;
    },
    //输入框失去焦点触发,此处用提示框提示修改
    blurEvent(column, row) {
      //  console.log(column, row);
      column.iseditor = false;
      row.isnameSelected = false;
    },
   
  },
};
</script>
<template>
  <div>
    <el-table :data="tableData" border style="width: 100%">
      <el-table-column
        :prop="field.prop"
        :label="field.label"
        :min-width="field.minWidth || 140"
        v-for="(field, index) in fields"
        :key="index"
        show-overflow-tooltip
      >
        <template slot-scope="scope">
          <div v-if="field.slot">
            <slot :name="field.slot" :row="scope.row" />
          </div>
          <div v-else>
            <div>
              <el-input
                v-if="field.iseditor && scope.row.isnameSelected"
                v-model="scope.row[field.prop]"
                @focus="cellClick(field, scope.row)"
                @blur="blurEvent(field, scope.row)"
                v-focus
              >
              </el-input>
              <p @click="cellClick(field, scope.row)" v-else>
                {{ scope.row[field.prop] || "--" }}
              </p>
            </div>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<style scoped>
</style>
<style>
.el-tooltip__popper {
  max-width: 1000px;
}
.disabled .el-upload--picture-card {
  display: none;
}
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

父组件

这里还有封装了一个文件上传的组件嵌套在表格中,算是拓展

<script>
import editComponents from "../../components/editComponents";
export default {
  components: { editComponents },
  data() {
    return {
      fields: [
        {
          prop: "industryCode",
          label: "产品",
          iseditor: false,
        },
        {
          prop: "id",
          label: "id",
          iseditor: false,
        },
        {
          prop: "paragraphType",
          label: "产品类型",
          iseditor: false,
          slot: "paragraphType",
//根据这个slot来决定是否要使用插槽,让父组件可以更好地使用数据,不用传来传去,下面是一样的
        },
        {
          prop: "paragraphImage",
          label: "产品图片",
          slot: "paragraphImage",
          iseditor: false,
        },
        {
          prop: "action",
          label: "操作",
          slot: "action",
        },
      ],
      tableData: [
        {
          industryCode: "苹果",
          id: "15",
          paragraphType: "1",
          paragraphImage: "15.png",
        },
        {
          industryCode: "苹果",
          id: "16",
          paragraphType: "2",
          paragraphImage: "15.png",
        },
        {
          industryCode: "苹果",
          id: "17",
          paragraphType: "1",
          paragraphImage: "15.png",
        },
      ],
      fileList: [], //文件总数
      fileList1: [], //详情文件总数
      dialogImageUrl: "",
      dialogVisible: false,
      disabled: false,
    };
  },
  computed: {
    //文件上传地址
    upLoadUrl() {
      //process.env.VUE_APP_BASE_API 检测当前环境来决定接口路径
      //测试环境 VUE_APP_BASE_API = '/stage-api'
      if (process.env.VUE_APP_BASE_API == "/stage-api") {
        return "接口地址"; //   例如:'/minio/upload'
        // 生产
      } else if (process.env.VUE_APP_BASE_API == "生产接口") {
        return "接口地址";
      } else {
        // 本地
        return "接口地址";
      }
    },
  },
  created() {
    this.getlist();
  },
  methods: {
    //获取数据
    getlist() {
      // 发请求获取数据写在这里
      this.tableData = this.tableData.map((item) => {
        return { ...item, isnameSelected: false };
      });
    },
    // 添加
    hAdd() {
      const productObj1 = {
        industryCode: "",
        id: "",
        paragraphType: "",
        paragraphImage: "",
        iseditor: false,
        uuId: Math.random(),
      };

      this.tableData.push(productObj1);
    },
    // 删除
    del(row) {
      this.tableData = this.tableData.filter(
        (item) => item.uuId !== row.uuId || item.id !== row.id
      );
    },
    //图片上传===========================
    handleRemove(file) {
      console.log(file);
      console.log(this.$refs.upload);
      let uploadFiles = this.$refs.upload.uploadFiles;
      for (var i = 0; i < uploadFiles.length; i++) {
        if (uploadFiles[i]["url"] == file.url) {
          uploadFiles.splice(i, 1);
        }
      }
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    handleDownload(file) {
      console.log(file);
    },
    // 文件上传成功-----------------
    async handleSuccess(response, row) {
      // 处理上传成功后的逻辑
      console.log("上传成功", response, row);
      this.fileName = response.data.fileName;
      row.paragraphImage = response.data.fileName;
    },
    handleError(err, file, fileList) {
      // 处理上传失败后的逻辑
      console.error("上传失败", err);
    },
    //  selectedLabel(selectedValue) {
    //   if (selectedValue === "1") {
    //     return "选择一";
    //   } else if (selectedValue === "2") {
    //     return "选择二";
    //   }
    // },
    async onSubmit() {
      // 删除不需要的属性
      this.tableData.forEach(function (obj) {
        if (obj.hasOwnProperty("iseditor")) {
          delete obj.iseditor;
        }
        if (obj.hasOwnProperty("uuId")) {
          delete obj.uuId;
        }
        if (obj.hasOwnProperty("isnameSelected")) {
          delete obj.isnameSelected;
        }
      });
      // 新增
      if (!this.industryCode) {
        //   新增请求写在这里
        console.log(res);
        if (res.message == "success") {
          this.$message({
            message: res.data,
            type: "success",
            duration: 1000,
          });
        } else {
          this.$message.error(res.data);
        }
      } else {
        // 修改请求写在这里
        console.log(res);
        if (res.message == "success") {
          this.$message({
            message: res.data,
            type: "success",
            duration: 1000,
          });
          this.goBack();
        } else {
          this.$message.error(res.data);
        }
      }
    },
  },
};
</script>
<template>
  <div>
    <el-button @click="hAdd" type="primary">添加</el-button>
    <editComponents :fields="fields" :tableData="tableData">
      <template #action="{ row }">
        <el-button type="text" size="small" @click="del(row)">删除</el-button>
      </template>
      <template #paragraphImage="{ row }">
        <div>
          <p>{{ row.paragraphImage || "--" }}</p>
          <el-upload
            ref="upload"
            :file-list="fileList1"
            :action="upLoadUrl"
            list-type="picture-card"
            :on-success="(e) => handleSuccess(e, row)"
            :on-error="handleError"
          >
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{ file }">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url"
                alt=""
              />
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePictureCardPreview(file)"
                >
                  <i class="el-icon-zoom-in"></i>
                </span>

                <span
                  v-if="!disabled"
                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </div>
          </el-upload>
          <el-dialog :visible.sync="dialogVisible">
            <img width="100%" :src="dialogImageUrl" alt="" />
          </el-dialog>
        </div>
      </template>
      <template #paragraphType="{ row }">
        <div>
          <el-select v-model="row.paragraphType" placeholder="请选择">
            <el-option label="选择一" value="1"></el-option>
            <el-option label="选择二" value="2"></el-option>
          </el-select>
          <!-- <p @click="cellClick(row)">
              {{ selectedLabel(row.titleTypeSecond) || "--" }}
              {{row}}
            </p> -->
        </div>
      </template>
    </editComponents>
    <el-card>
      <div>
        <el-button type="primary" round @click="onSubmit">提交</el-button>
      </div>
    </el-card>
  </div>
</template>
<style scoped>
</style>


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

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

相关文章

6.4 图的存储结构

思维导图&#xff1a; 前言&#xff1a; --- **6.4 图的存储结构** - **核心问题**&#xff1a;由于图的结构复杂性&#xff0c;我们不能仅仅依赖于元素在存储区的物理位置来表示它们之间的关系。 - **邻接矩阵**&#xff1a; - **基本思路**&#xff1a;虽然图没有顺序存…

基于混沌博弈优化的BP神经网络(分类应用) - 附代码

基于混沌博弈优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于混沌博弈优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.混沌博弈优化BP神经网络3.1 BP神经网络参数设置3.2 混沌博弈算法应用 4.测试结果…

在Objective-C中使用ASIHTTPRequest发送HTTP请求并获取HTML内容

在网络爬虫开发中&#xff0c;发送HTTP请求并获取目标网站的HTML内容是一项常见任务。通过发送HTTP请求&#xff0c;我们可以模拟浏览器行为&#xff0c;访问网页并获取其中的数据。这些数据可以用于数据分析、信息收集、自动化测试等多种用途。为了实现这个目标&#xff0c;开…

基于堆优化优化的BP神经网络(分类应用) - 附代码

基于堆优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于堆优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.堆优化优化BP神经网络3.1 BP神经网络参数设置3.2 堆优化算法应用 4.测试结果&#x…

数组越界访问导致死循环的情况

这个问题是在学习程序地址空间的时候回忆C语言学习时想到的 我们会遇到下面的情况 int main() {int i 0;int arr[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };for(i 0; i < 12; i){arr[i] 0;}return 0; }程序死循环了 问题就出在程序的存储空间上&#xff0c;i和arr都是局…

BFD基础

1.BFD概述 BFD提供了一个通用的、标准化的、介质无关的、协议无关的快速故障检测机制&#xff0c;有以下两大优点&#xff1a; ①对相邻转发引擎之间的通道提供轻负荷、快速故障检测。 ②用单一的机制对任何介质、任何协议层进行实时检测。 BFD是一个简单的“Hello”协议。两个…

分享一份适合练手的软件测试实战项目

最近&#xff0c;不少读者托我找一个能实际练手的测试项目。开始&#xff0c;我觉得这是很简单的一件事&#xff0c;但当我付诸行动时&#xff0c;却发现&#xff0c;要找到一个对新手友好的练手项目&#xff0c;着实困难。 我翻了不下一百个web网页&#xff0c;包括之前推荐练…

YOLOv5算法改进(6)— Neck网络介绍(AFPN和BiFPN)

前言:Hello大家好,我是小哥谈。Neck网络是目标检测中的一个重要组成部分,主要用于对检测器提取的特征进行进一步处理和融合,以提高检测精度。通常,Neck网络由一系列卷积层、池化层、上采样层等组成,可以将不同层次的特征进行融合,同时也可以对特征进行降维和升维操作。本…

VT-MVTW-1-16/D VTS0234-47/AP025 可以用模拟或数字输入来控制

VT-MVTW-1-16/D VTS0234-47/AP025 可以用模拟或数字输入来控制 伺服驱动器可以用模拟或数字输入来控制。本质上&#xff0c;伺服驱动器的作用是将来自控制器的低功率命令信号转换成高功率电压和电流给电机。根据应用&#xff0c;伺服驱动器可以调节和适当协调电机的期望位置、…

【MySQL】索引介绍、索引的数据结构

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 索引 一、索引概述二、索引结构2.1 BTree2.…

Linux文件管理(上)

一、VIM编辑器 1、vi概述 vi&#xff08;visual editor&#xff09;编辑器通常被简称为vi&#xff0c;它是Linux和Unix系统上最基本的文本编辑器&#xff0c;类似于Windows 系统下的notepad&#xff08;记事本&#xff09;编辑器。 2、vim编辑器 Vim(Vi improved)是vi编辑器…

CSS之布局系列--顶部导航栏二级菜单居中展示

原文网址&#xff1a;CSS之布局系列--顶部导航栏二级菜单居中展示_IT利刃出鞘的博客-CSDN博客 简介 本文介绍CSS将顶部导航栏居中展示并支持二级菜单下拉展示的方法。 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-…

基于人工水母优化的BP神经网络(分类应用) - 附代码

基于人工水母优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于人工水母优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.人工水母优化BP神经网络3.1 BP神经网络参数设置3.2 人工水母算法应用 4.测试结果…

Wireshark 通过 nrf-sniffer for BLE 抓包环境配置说明

1 准本工作 1.1 购买 nrf sniffer 抓包工具 购买链接&#xff1a;https://item.taobao.com/item.htm?spma21n57.1.0.0.46291dafMXbO9s&id718103919140&ns1&abbucket15#detail 1.2 下载文件 下载 CP2101 驱动 下载链接&#xff1a;http://www.wxlrf.com/downloa…

基于springboot实现民宿管理平台项目【项目源码+论文说明】

摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于民宿管理平台系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了民宿管理平台系统&#xff0c;它彻底改变了过…

利用Tomcat服务器实现一个简单的web应用

2023.10.17 昨天使用Tomcat服务器实现了一个简单的web应用&#xff0c;但是显示的页面是静态页面&#xff0c;今天来实现一个动态的web应用。 对于一个动态的web应用&#xff0c;一个请求和响应的过程中&#xff0c;有哪些角色参与&#xff0c;角色间有哪些协议&#xff1f; 角…

解决方案-LBS用户位置GEO附近人/店铺

附近人 附近人列表功能mysqlredis GEOthinkphp 附近人列表功能 方案优势缺点Mysql外接正方形逻辑清晰&#xff0c;实现简单&#xff0c;支持多条件筛选效率较低&#xff0c;不适合大数据量&#xff0c;不支持按距离排序MysqlGeohash借助索引有效提高效率&#xff0c;支持多条件…

密码学三 btc 钱包 节点 挖矿 51%攻击 双花攻击

03-BTC-数据结构_哔哩哔哩_bilibili 哈希指针并解释 比特币的每个区块都包含一个区块头和区块体两部分。 在区块头中,有一个字段是用于存储前一个区块的哈希值,我们把这个存储前一个区块哈希值的字段称为“哈希指针”。 这个哈希指针的作用是将本区块指向前一个区块,连接起整…

Library projects cannot set applicationId. applicationId is set to

Library projects cannot set applicationId. applicationId is set to com.xxx.library_cache in default config. 删掉即可

RTSP/Onvif安防视频平台EasyNVR级联至EasyNVS系统不显示通道,是什么原因?

视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入&#xff0c;并能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。 我们在此前的文章中也介绍过关于EasyNVR级联EasyNVS上云网关综合管理平台的内容&#xff…