vue+element-ui el-descriptions 详情渲染组件二次封装(Vue项目)

2023-09-17 18:30:52

目录

1、需求

2.想要的效果就是由图一变成图二

​编辑

3.组件集成了以下功能

4.参数配置

示例代码

参数说明 

5,组件 

6.页面使用


1、需求

一般后台管理系统,通常页面都有增删改查;而不外乎就是渲染新增/修改的数据(由输入框变成输入框禁用),因为输入框禁用后颜色透明度会降低,显的颜色偏暗;为解决这个需求于是封装了详情组件

2.想要的效果就是由图一变成图二

3.组件集成了以下功能

操作按钮自定义
字典类型(即后台返回的是数字类型)过滤转成中文
自定义模版 数组类型 对象类型 
渲染图片

4.参数配置

示例代码

    <orderDetail :descList="detailModule" :data="renderData"></orderDetail>

参数说明 

 * [
     * {
     * title:String 分类标题
     * column:Number 每行几个(默认2)
     * size:String 大小 medium / small / mini(默认 medium)
     * border:Boolean边框(默认true)
     * keyArr:[
     * {
     * icon:String,(描述标题的图标)
     * label:String,描述标题
     * keyName:String(对应的翻译值)
     * innerKey:String 数组时对应的翻译值
     * detailType:"image"渲染图片
     * formatter:Function :自定义渲染
     * getTranslation:Function:为对象时处理翻译的值
     * }
     * ]
     * extra:{ '操作按钮'
     * text:String(按钮文案)
     * methods:function(方法回调)
     * }
     * }
     * ]

5,组件 

<template>
  <div class="detail-box demo-image__error cell-44">
    <el-descriptions v-for="(item, index) in descList" :border="item.border || true" :key="'descList' + index"
      class="mb20" :title="item.title || ''" :column="item.column || 2" labelClassName="custom-label"
      contentClassName="custom-content" :size="item.size || 'medium'">
      <template slot="extra" v-if="item.extra">
        <el-button type="primary" size="small" @click="item.extra.methods(item, index)">{{ item.extra.text }}</el-button>
      </template>
      <!-- 描述title -->
      <el-descriptions-item v-for="(descKey, innerIndex) in item.keyArr" :key="innerIndex + 'desc'">
        <template slot="label" v-if="descKey.label">
          <i class="el-icon-user" v-if="item.icon"></i>
          {{ descKey.label }}
        </template>
        <!-- 图片类型数据 -->
        <div class="cell" v-if="descKey.detailType == 'image'">
          <el-image style="width: 44px; height: 44px" :src="data[descKey.keyName]">
            <div slot="error" class="image-slot">
              <i class="el-icon-picture-outline"></i>
            </div>
          </el-image>
        </div>
        <!-- 自定义模版 -->
        <div v-else-if="descKey.formatter" v-html="descKey.formatter(data)"></div>
        <!-- 数组对象、或数组 -->
        <template v-else-if="Array.isArray(data[descKey.keyName])">
          <el-tag v-for="(innerItem, innerI) in data[descKey.keyName]" :key="'tag' + innerI" size="small"
            class="mr10 mb10">
            {{ (descKey.innerKey ? innerItem[descKey.innerKey] : innerItem) || "--" }}
          </el-tag>
        </template>
        <!-- 默认键值对 -->
        <span v-else-if="(data[descKey.keyName] || data[descKey.keyName] === 0) &&
          typeof data[descKey.keyName] !== 'object'
          ">
          {{
            data[descKey.keyName] || data[descKey.keyName] == 0
            ? data[descKey.keyName]
            : "--"
          }}
        </span>
        <!-- 对象类型数据 -->
        <span v-else-if="typeof data[descKey.keyName] === 'object'">
          <el-descriptions :data="data[descKey.keyName]" :border="false">
            <el-descriptions-item v-for="(value, key) in data[descKey.keyName]" :key="key">
              <template slot="label">{{ descKey.getTranslation(key, index) }}</template>
              <span>{{ value }}</span>
            </el-descriptions-item>
          </el-descriptions>
        </span>
        <!-- 没有匹配项目 -->
        <span v-else>--</span>

      </el-descriptions-item>
    </el-descriptions>
  </div>
</template>

<script>
export default {
  props: {
    /**
     * [
     * {
     * title:String 分类标题
     * column:Number 每行几个(默认2)
     * size:String 大小 medium / small / mini(默认 medium)
     * border:Boolean边框(默认true)
     * keyArr:[
     * {
     * icon:String,(描述标题的图标)
     * label:String,描述标题
     * keyName:String(对应的翻译值)
     * innerKey:String 数组时对应的翻译值
     * detailType:"image"渲染图片
     * formatter:Function :自定义渲染
     * getTranslation:Function:为对象时处理翻译的值
     * }
     * ]
     * extra:{ '操作按钮'
     * text:String(文案)
     * methods:function(方法回调)
     * }
     * }
     * ]
     */
    descList: {
      type: Array,
      default: () => {
        return [];
      },
    },
    data: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
};
</script>

<style lang="scss">
.custom-label,
.custom-content {
  width: 25% !important;
}

.demo-image__error .image-slot,
.demo-image__placeholder .image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: #f5f7fa;
  color: #909399;
  font-size: 14px;
}

.cell-44 {
  .cell {
    height: 44px;
    line-height: 44px;
  }
}
</style>

6.页面使用

<template>
  <div class="table-page">
    <FormDetail :descList="detailModule" :data="renderData"></FormDetail>
  </div>
</template>
<script>
import FormDetail from "@/components/FormDetail/details.vue";
export default {
  components: {
    FormDetail,
  },
  data() {
    return {
      detailModule: [
        {
          translations: { age: "年龄", name: '姓名' },
          title: "信息",
          keyArr: [
            { label: "账户名称", keyName: "AccountName" },
            { label: "账户id", keyName: "AccountId" },
            { detailType: 'image', label: '头像', keyName: 'image' },
            {
              formatter: (data) => {
                console.log(data, '------');
                return `<span style="white-space: nowrap;color: dodgerblue;">${data.status}</span>`;
              },
              label: '自定义',
            },
            { label: '数组', keyName: 'list', innerKey: 'asList' },
            {
              label: "测试", keyName: "obj",
              getTranslation: (key, index) => {
                return this.detailModule[index].translations[key] || key; // 如果找不到翻译,返回键本身
              }
            }
          ],
          extra: {
            text: 'text',
            methods: (item, index) => {
              console.log(item, index);
            }
          },


        },
      ],
      renderData: {
        AccountId: "1",
        AccountName: "张三",
        image: 'https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png',
        status: '开启',
        list: [
          { asList: "5" },
          { status: "5" },
          { asList: "5" },
        ],
        obj: {
          age: 8,
          name: 'zs',
          sex: 'nan',
        }
      },
    }
  },
};
</script>

更多推荐

【每日一题】2603. 收集树中金币

文章目录Tag题目来源题目解读解题思路方法一:拓扑排序写在最后Tag【拓扑排序】【树】题目来源2603.收集树中金币题目解读有一个有n个节点的无相无根图,节点编号从0到n-1。有一个表示图中节点间连接关系的数组edges,长度为n-1,edges[i]=[ai,bi]表示节点ai和bi之间有一条边。还有一个数组coin

点灯科技实现 “ESP8266-01/01s + 继电器” 远程开关

教程视频ESP-01S继电器插座怎么使用?所需硬件继电器ESP-01S继电器插座WIFI模块esp8266-01swifi模块烧录器软件准备ArduinoIDE需安装好esp8266扩展点击下载下载并安装blinkerAPPAndroid下载:点击下载或在android应用商店搜索“blinker”下载安装IOS下载:

十几款IDEA开发必备的插件,新手必用

IDEA有很多优秀的插件,使用它们不仅大大增加了开发效率,也能给大家带来更好的coding体验。“工欲善其事必先利其器”,以下插件基本都可以通过IDEA自带的插件管理中心安装。1、CodeGlance拖动浏览代码更加方便,还有放大镜功能。2、Restfultoolkit一套RESTful服务开发辅助工具集,完美代替po

车企大军「涌进」零部件赛道,毫米波雷达市场被重估

垂直整合,是新一轮竞争周期的关键词。从芯片、传感器,到域控制器;从三电总成到智能底盘,不管是特斯拉、比亚迪,还是蔚来、零跑、哪吒等后来者,自研+自产+自销,玩法不一。比如,特斯拉率先开启智能驾驶芯片的自研,彻底奠定了在自动驾驶领域的领先地位(不受制于第三方芯片供应商)。从算法(软件甚至功能)出发设计芯片架构,成为车企自

企业直播如何实现多画面多场景切换?

企业直播如何实现多画面多场景切换?应用场景主要应用于:企业的会议直播、小型会务直播、异地讲师培训授课,实现较低成本的导播台场景切换效果(阿酷TONY注,比不上硬件导播台,但整体还可以,能达到场景画面切换效果)。轻导播客户端(版本:1.2.0)官方介绍是:轻量级导播软件,10分钟速成导播能手直播画面自由布局、多人连麦自由

路由和node环境搭建

路由和node环境搭建1.1什么是路由1.2案例实操1.2.3效果展示二、配置Node.js2.1新建两个文件夹2.2配置环境变量1.1什么是路由在计算机网络中,路由(Routing)是指根据某种算法将数据包从源节点传输到目标节点的过程。在Web开发中,路由则指的是根据URL地址的不同,将用户请求导向对应的处理程序或页

解锁前端Vue3宝藏级资料 第五章 Vue 组件应用 3( Slots )

5.4Slots我们已经了解到组件能够接收任意类型的JavaScript值作为props,但组件要如何接收模板内容呢?在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。Slots可用于将Html内容从父组件传递到子组件进行显示。例如,你创建一个名为Button的组件,并且只想更改按

2个比较经典的PHP加密解密函数分享

项目中有时我们需要使用PHP将特定的信息进行加密,也就是通过加密算法生成一个加密字符串,这个加密后的字符串可以通过解密算法进行解密,便于程序对解密后的信息进行处理。最常见的应用在用户登录以及一些API数据交换的场景。笔者收录了一些比较经典的PHP加密解密函数代码,分享给大家。加密解密原理一般都是通过一定的加密解密算法,

JavaScript 基础 - 第1天笔记

JavaScript基础-第1天了解变量、数据类型、运算符等基础概念,能够实现数据类型的转换,结合四则运算体会如何编程。体会现实世界中的事物与计算机的关系理解什么是数据并知道数据的分类理解变量存储数据的“容器”掌握常见运算符的使用,了解优先级关系知道JavaScript数据类型隐式转换的特征介绍掌握JavaScript

头歌平台相关verilog练习

以下题目不具有难易程度的连续性文章目录1、三人表决电路2、多路选择器3、电路功能描述—门级原始结构4、电路功能描述—行为定义—连续赋值5、电路功能描述—行为定义—过程语句1、三人表决电路本关需要你根据所学的组合逻辑及数字电路的知识完成三人表决电路的设计,实现少数服从多数的表决规则,根据逻辑真值表和逻辑表达式完成表决功能

netty之数据读写源码阅读

数据读写write从client端的写开始看client与服务端建立完connect后可以从future里拿到连接的channel对象。这里的channel是io.netty.channel.Channel对象。调用其channel.writeAndFlush(msg);方法可以进行数据发送。writeAndFlush

热文推荐