两种方式对el-table二次封装

news2024/10/6 18:28:41

1、序言

        完整源码:el-table-example: 两种方式对el-table二次封装

        最近在公司写了好多的后台管理系统,管理系统很大部分都是elementui下的el-table,el-table中有很多 <el-table-column></el-table-column>是重复的,像这样:

        能不能通过配置项让其自动生成 <el-table-column></el-table-column>,省去冗余代码。下一次管理系统添加新模块相似的内容,就不用复制粘贴了。有一说一,复制粘贴完成需求速度非常快、并且效果不错,但是代码就像屎山,冗余度、可维护性都比较差,长期复制粘贴没什么成长!

2、自定义组件方式封装el-table

  2.1、封装

        (1)在src下建立components文件夹

        (2)在components文件夹下建立Table/index.vue、index.js两个文件夹

        (3)index.js文件全局注册封装的Table组件

import Vue from 'vue';
import Table from './index.vue';

/* 封装的表格组件 */

// 全局注册<Table>组件
Vue.component('CommonTable', Table);

        (4)index.vue文件封装Table组件

        遇到一些自定义列就使用作用域名插槽填充,名称为prop值,并在coloum中配置slot属性。像这样:

 

<!-- 表格组件 -->
<template>
    <div>
        <el-table :data="data" stripe style="width: 100%" v-loading="loading" @selection-change="handleSelectionChange">
            <!--选择-->
            <el-table-column v-if="hasSelection" type="selection" width="55" />
            <!--序号-->
            <el-table-column v-if="hasIndex" type="index" width="55" />
            <!--数据源-->
            <template v-for="(column, index) in columns">
                <!-- 表头存在type类型 -->
                <el-table-column v-if="
                    column.type &&
                    (column.type == 'selection' || column.type == 'index')
                " :type="column.type" />

                <!-- 表头是数据或操作内容 -->
                <el-table-column v-else :label="column.label">
                    <template v-if="!column.type" slot-scope="{ row, $index}">
                        <slot v-if="column.slot" :name="column.slot" :row="row" :index="$index" />
                        <span v-else>{{ row[column.prop] }}</span>
                    </template>
                </el-table-column>
            </template>
        </el-table>
    </div>
</template>
<script>
export default {
    name: 'Table',
    props: {
        loading: {
            type: Boolean,
            default: () => false
        },
        // 是否可以选择
        hasSelection: {
            type: Boolean,
            default: () => false
        },
        // 是否有序列项
        hasIndex: {
            type: Boolean,
            default: () => false
        },
        // 这是相应的字段展示
        columns: {
            type: Array,
            default: () => []
        },
        // 这是数据源
        data: {
            type: Array,
            default: () => []
        }
    },
    methods: {
        // 将选中的行发送到父组件
        handleSelectionChange(val) {
            const selectionArr = []
            val.forEach(item => {
                selectionArr.push(item)
            })
            this.$emit('commitSelection', selectionArr)
        },
    },
}
</script>

         (5)main.js中引入全局注册组件

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import "./assets/css/main.css";

/* 全局注册的组件 */
import './components/Table/index'; // 表格组件

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

  2.2、使用

<template>
    <div>
        <common-table :columns="columns" :data="tableData">
            <template slot="isPublic" slot-scope="{ row }">
                {{ transformPublic(row.isPublic) }}
            </template>
            <template slot="operation" slot-scope="{ row }">
                <el-button type="primary">
                    编辑
                </el-button>
                <el-button type="danger">
                    删除
                </el-button>
            </template>
        </common-table>
    </div>
</template>

<script>
export default {
    data() {
        return {
            tableData: [{
                id: 11,
                name: '绿色天使幼儿园',
                count: 100,
                address: '北京',
                isPublic: 1,
            }, {
                id: 22,
                name: '金苹果幼儿园',
                count: 200,
                address: '上海',
                isPublic: 1,
            }, {
                id: 33,
                name: '童趣幼儿园',
                count: 300,
                address: '广州',
                isPublic: 0,
            }, {
                id: 44,
                name: '快乐星球幼儿园',
                count: 400,
                address: '深圳',
                isPublic: 0,
            }],
            columns: [
                { prop: 'id', label: 'id' },
                { prop: 'name', label: '名称' },
                { prop: 'count', label: '人数' },
                { prop: 'isPublic', label: '是否公办', slot: 'isPublic' },
                { prop: 'address', label: '地址' },
                {
                    label: "操作",
                    slot: "operation"
                }
            ]
        }
    },
    computed: {
        transformPublic() {
            return function (isPublic) {
                let t = {
                    1: '是',
                    0: '否'
                }
                return t[isPublic]
            }
        }
    }
}
</script>

<style scoped></style>

3、jsx方式封装el-table

  3.1、jsx

        我看网上还有使用jsx方式来封装el-table,jsx能够抽象组件,jsx是一种javascript和xml结合的一种语法,它既有javascript的灵活性,也有xml的规范性,但是有一说一,写起来真不习惯、真不舒服!

        babel能将es6转换成es5,还能将jsx转换成javascript,所以babel插件必不可少!惊喜的发现脚手架cli已经配置好babel插件,基本可以直接上手写jsx了!jsx语法和vue语法还是有一些差别的,详细去看看网上例子,掌握好它上手react比较容易!

        写jsx记得要把vue中的template、script、style标签去掉

  3.2、封装

        (1)src/components/JsxTable/index.js 建立文件夹

        (2)render()中 return <div> <el-table></el-table>  </div>

        (3)自定义指令v-loading还有语法糖@selection-change 使用不了,需要转译一下让jsx识别

        // @selection-change语法糖没法在jsx直接使用,需要转译一下
        const listeners = {
            on: {
                ['selection-change']: val => this.$emit('commitSelection', val)
            }
        };

        // v-loading没法在jsx直接使用,需要转译一下
        const directives = {
            directives: [{ name: 'loading', value: loading }]
        };

        (4)attrs和scopedSlots 

        attrs 属性是用于将父组件属性传递(除了 prop 传递的属性、class 和 style )给子组件, 这通常用于将事件监听器和自定义属性传递给子组件。

        scopedSlots 是用于将父组件的作用域插槽(scoped slot)传递给子组件,以便子组件可以在父组件提供的数据上进行渲染。在父组件中,标签并设置slot-scope属性来创建作用域插槽,然后在子组件中使用this.$slots属性来获取这些插槽


        // 渲染列
        const renderColumn = () => {
            return columns.map(item => {
                const attribute = {
                    attrs: { ...item }
                };
           
                if (item.slot) {
                    attribute.scopedSlots = {
                        default: this.$scopedSlots[item.slot]
                    };
                }
                return <el-table-column {...attribute} />;
            });
        };

        (5)将属性、事件、指令组装到el-table中,并通过render()返回组装好的el-table

        // 渲染表格
        const renderTable = (
            <el-table data={dataList} {...listeners} {...directives} style="width: 100%" >
                {renderColumn()}
            </el-table >
        );
        return <div>{renderTable}</div>;

  3.3、使用

<template>
    <div>
        <jsx-table :columns="columns" :dataList="tableData" hasSelection @commitSelection="getselected">
            <template slot="isPublic" slot-scope="{ row }">
                {{ transformPublic(row.isPublic) }}
            </template>
            <template slot="operation" slot-scope="scope">
                <el-button type="primary">
                    编辑
                </el-button>
                <el-button type="danger">
                    删除
                </el-button>
            </template>
        </jsx-table>
    </div>
</template>

<script>
import JsxTable from '@/components/JsxTable'
export default {
    components: {
        JsxTable
    },
    data() {
        return {
            tableData: [{
                id: 11,
                name: '绿色天使幼儿园',
                count: 100,
                address: '北京',
                isPublic: 1,
            }, {
                id: 22,
                name: '金苹果幼儿园',
                count: 200,
                address: '上海',
                isPublic: 1,
            }, {
                id: 33,
                name: '童趣幼儿园',
                count: 300,
                address: '广州',
                isPublic: 0,
            }, {
                id: 44,
                name: '快乐星球幼儿园',
                count: 400,
                address: '深圳',
                isPublic: 0,
            }],
            columns: [
                { prop: 'id', label: 'id' },
                { prop: 'name', label: '名称' },
                { prop: 'count', label: '人数' },
                { prop: 'isPublic', label: '是否公办', slot: 'isPublic' },
                { prop: 'address', label: '地址' },
                {
                    label: "操作",
                    slot: "operation"
                }
            ]
        }
    },
    methods: {
        // 获取选中行
        getselected(val) {
            console.log('val:', val);
        }
    },
    computed: {
        transformPublic() {
            return function (isPublic) {
                let t = {
                    1: '是',
                    0: '否'
                }
                return t[isPublic]
            }
        }
    }
}
</script>

<style scoped></style>

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

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

相关文章

Redis_概述_特性_IO模型

本章要点 掌握NoSql数据库的概念和与sql数据库的区别初步了解Redis内存数据库了解Redis内存数据库的优点及其原因掌握Redis的多线程IO模型学习Redis的安装和配置 Redis简介 Redis 全称 Remote Dictionary Server 远程字典服务! 使用C语言编写,支持网络,可基于内存也可以持久化…

Scrapy爬虫框架(概念)

Scrapy 入门教程 | 菜鸟教程 (runoob.com) Scrapy是一个快速功能强大的网络爬虫框架 Scrapy的安装 通过 pip 安装 Scrapy 框架: pip install Scrapy 安装后小测&#xff1a; 执行 scrapy ‐h Scrapy不是一个函数功能库&#xff0c;而是一个爬虫框架。 Scrapy架构图(绿线是…

【ROS2指南-4】理解ROS2话题

目标&#xff1a;使用 rqt_graph 和命令行工具来反思 ROS 2 主题。 教程级别&#xff1a;初学者 时间&#xff1a; 20分钟 内容 背景 先决条件 任务 1 设置 2 rqt_graph 3 ros2主题列表 4 ros2主题回显 5 ros2 主题信息 6 ros2界面展示 7 ros2主题发布 8 ros2 主题赫…

光纤能取代网线吗?

光纤与铜缆之间的较量已持续了十多年。现如今随着云计算、5G 等新型业务的不断涌现&#xff0c;数据中心规模不断的扩大&#xff0c;其架构与布线也越来越复杂&#xff0c;而光纤的轻量化及逐渐降低的成本&#xff0c;使得主干网设备对光纤的需求也越来越旺盛&#xff0c;在大型…

pikachu靶场-xss

XSS漏洞攻击原理跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中Web里面的Script代码会被执行&#xff0c;从而达到恶意攻击用户的目的。一般XSS可以分为如下几种常见类型&#xff1a;1.反射性XSS;2.存储型XSS;3.…

成为钢铁侠!只需一块RTX3090,微软开源贾维斯(J.A.R.V.I.S.)人工智能AI助理系统

梦想照进现实&#xff0c;微软果然不愧是微软&#xff0c;开源了贾维斯(J.A.R.V.I.S.)人工智能助理系统&#xff0c;贾维斯(jarvis)全称为Just A Rather Very Intelligent System&#xff08;只是一个相当聪明的人工智能系统&#xff09;&#xff0c;它可以帮助钢铁侠托尼斯塔克…

何为智能驾驶的「摩尔定律」?这家芯片方案商给出自己的答案

“我觉得&#xff08;高速NOA&#xff09;价格下降的速度可能会是非常快的&#xff0c;”4月6日&#xff0c;地平线技术开放日上&#xff0c;地平线副总裁、软件平台产品线总裁余轶南在与高工智能汽车沟通中称&#xff0c;“到2024年底&#xff0c;约100TOPS的高速NOA&#xff…

Lottie加载的一些坑

Lottie是一个非常强大的动画库&#xff0c;可以渲染一些非常绚丽的动画。然而在使用的过程中&#xff0c;会遇到一些诡异的问题。通常&#xff0c;这不是使用方式上有什么问题&#xff0c;大都是UE产出的lottie本身存在问题。本来之前的UE小哥还不错的&#xff0c;跳槽后来了个…

【详解 进程通信】之 System V 共享内存

简介大致操作步骤介绍结果展示key值的获取创建 | 获取共享内存使用共享内存段解除共享内存段销毁共享内存段&#xff08;重点&#xff09;命令行方式销毁共享内存段系统调用销毁共享内存使用共享内存进行进程间通信简介 共享内存可以让多个进程共享同一块内存&#xff0c;也就…

如何实现Chatgpt写文章(附chatgpt3.5免费接口)

申明&#xff1a;本次只是说一下实现思路&#xff0c;官方的接口以及如何实现方式&#xff0c;本文没有提及&#xff0c;这次只是一个思路&#xff0c;若想代替人工完成质量还差的很远&#xff0c;请审核大大放行 今天再次优化了代码&#xff0c;修复了一些bug&#xff0c;考虑…

单片机程序是如何运行起来

多年前在学习计算机原理的时候曾经问过老师一个问题&#xff0c;就是我们编写的程序是怎么在计算机中运行起来的&#xff0c;希望有个完整的思路&#xff0c;现在通过网络收集和整理了这个问题&#xff0c;相当于对这个问题又做了一个认识&#xff0c;有了新的体会。以stm32单片…

Go 语言切片是如何扩容的?

原文链接&#xff1a; Go 语言切片是如何扩容的&#xff1f; 在 Go 语言中&#xff0c;有一个很常用的数据结构&#xff0c;那就是切片&#xff08;Slice&#xff09;。 切片是一个拥有相同类型元素的可变长度的序列&#xff0c;它是基于数组类型做的一层封装。它非常灵活&am…

VCS4 debug with DVE

1、重点讲解&#xff1a; 在verilog源代码中嵌入VCD 系统函数&#xff0c;重点如testbench文件中。VCD文件是VCS产生的仿真波形文件&#xff0c;未经压缩&#xff0c;占用空间较大。VCD是压缩后的波形文件。 编译、仿真以生成VCD文件。 在后处理模式中使用激活DVElog对产生的…

【Javaee】SpringMVC_day01

文章目录1&#xff0c;SpringMVC简介1.1 SpringMVC概述2&#xff0c;SpringMVC入门案例2.1 需求分析2.2 案例制作步骤1:创建Maven项目&#xff0c;并导入对应的jar包步骤2:创建控制器类步骤3:创建配置类步骤4:创建Tomcat的Servlet容器配置类步骤5:配置Tomcat环境步骤6:启动运行…

JS字符串对象

、 JS字符串对象 1.1 内置对象简介 在 JavaScript 中&#xff0c;对象是非常重要的知识点。对象可以分为两种:一种是“自定义对象”外一种是“内置对象”。自定义对象&#xff0c;指的是需要我们自己定义的对象&#xff0c;和“自定义函数”是一些道理;内置对象&#xff0c;…

力扣刷题笔记26——最小的k个数/快速排序学习/快排与冒泡的时间复杂度

最小的k个数/快速排序学习/快排与冒泡的时间复杂度问题我的代码示例代码快速排序代码问题 来自力扣&#xff1a; 输入整数数组 arr &#xff0c;找出其中最小的 k 个数。例如&#xff0c;输入4、5、1、6、2、7、3、8这8个数字&#xff0c;则最小的4个数字是1、2、3、4。示例 …

1672_MIT 6.828 xv6中如何通过构建环境让系统中增加一个可执行调用文件

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 前面已经分析了如何实现一个系统调用&#xff0c;这个过程的梳理也已经整理成了一份学习笔记。这一次看一下&#xff0c;如何让OS的系统中增加这样的一个可执行的文…

10.网络爬虫—MongoDB详讲与实战

网络爬虫—MongoDB详讲与实战MongoDBMongoDB安装创建数据目录1.数据库操作2.集合操作3.文档操作4.索引操作5.聚合操作6.备份与恢复MongoDB增删改查mongodb集合的增删改查数据插入到表数据的查看删除数据更新数据PyMongo连接数据库第二步 选择需要使用的数据库和集合PyMongo增删…

公司分布式锁加锁错误原因

目录一、问题二、问题复现三、为什么产生这个错误四、解决方案一、问题 第一次设置锁成功, 但是返回false, 后续在循环获取的时候, 因为已经设置成功, 调用setIfAbsent不会返回true, 导致等锁3s失败 private boolean lockWait(String key, long wait, long expire) { long tot…

【CV】Latent diffusion model 扩散模型体验

note 文章目录note一、diffusion模型1.1 Stable Diffusion简介1.2 和GAN对比的优势二、Latent diffusion model原理2.1 潜在空间(Lantent Space)2.2 自动编码器和U-Net2.3 文本编码器三、代码实践3.1 模型权重checkpoints3.2 Stable Diffusion v1模型推理3.3 安装Stable Diffus…