element-ui table组件如何使用render属性的实现


Posted in Javascript onNovember 04, 2019

前言

起因:

在使用 element-ui table组件时,由于表列比较多一个个写特别麻烦,所以想通过将所有表头定义成一个数组,通过遍历多方式去实现。这样解决了手写很多 el-table-column 的情况。

障碍:

类似于下面自定义表列的样式,它是通过 slot-scope 去覆盖 el-table-column 内部slot的样式实现的。那我们在遍历表头数组的时候如何实现呢?

element-ui table组件如何使用render属性的实现

参考:

用过 react 开发会经常用到 ant design ,其中它的 table 组件是可以接受 render属性的,下面使用table组件时,只需要定义好,columns(表头列) data(表的具体数据)即可。整体看起来很简洁 去渲染自定义的组件的。 点击查看 antdesign

demo:

codepen demo地址

const columns = [
 {
 title: 'Name',
 dataIndex: 'name',
 render: (text, row, index) => {
  if (index < 4) {
  return <a>{text}</a>;
  }
  return {
  children: <a>{text}</a>,
  props: {
   colSpan: 5,
  },
  };
 },
 }]
 const const data = [
 {
 key: '1',
 name: 'John Brown',
 age: 32,
 tel: '0571-22098909',
 phone: 18889898989,
 address: 'New York No. 1 Lake Park',
 }]
ReactDOM.render(<Table columns={columns} dataSource={data} bordered />, mountNode);

在 Vue 中实现 render 属性

接下来我们要实现下图的table的样式,但是这一次我们采用 render 传参数的方式

element-ui table组件如何使用render属性的实现 

思路

  1. 父组件将需要渲染的列表通过 props 传递给子组件
  2. 子组件使用 slot 并填充默认渲染的 el-table-column 方式为 prop 渲染 data 中传递的值
  3. 子组件通过 slot 将值传回给父组件,父组件通过 slot-scope 接受到子组件的值,判断该项是否有 render 属性,有的话在组件标签添加 render 属性返回的 html 去覆盖 slot 中默认的值。

子组件定义默认值

有了上面的思路,去实现子组件。我们需要知道一点,每个 el-table-column 只是定义了一列的表头和数据,而 :data="tableList" 中的每项值是定义了一行的数据。所以 el-table-column 是按列来分,data 是按行来分

  • 通过props 去接受表头列表,数据列表
  • 遍历表头数据,并且将 el-table-column 作为默认数据,使用 slot 包裹起来
  • 通过 slot 想父组件传递当前项的数据
<template>
 <el-table :data="tableList" style="width:500px">
  <template v-for="item in propList">
  <slot :content="item">
   <el-table-column :key="item.id" :prop="item.prop" :label="item.label"></el-table-column>
  </slot>
  </template>
 </el-table>
</template>
<script>
 export default {
  props:{
   propList:{
   type:Array,
   default:()=>[]
   },
   tableList:{
   type:Array,
   default:()=>[]
   },
  }
 }
</script>

父组件定义

父组件通过 slot-scope 来接受到子组件传递过来的数据,然后判断是否有 render 属性来确定是否用要去自定义样式覆盖默认的 slot

  • 首先看传递给子组件的表头数据,可以看到,第二,三行列表中有一个render属性,它是一个函数并返回一个 html 的字符串。
  • tableList就是普通的数据,也就是数据的 key 值去渲染对应的数据
  • 图片这列举例子,当父组件通过 props 将 {label,prop,id,render} 传递给子组件后,子组件有通过 slot 将值传递回父组件。
    • 到这里有些人会有疑问,为什么要将数据这样传来传去,因为我们在子组件中定义好了默认样式,而父组件中需要判断该值是否需要自定义样式,去覆盖子组件中的样式。
    • 这些自定义样式就是一开始,在render函数中返回的 html 字符串
    • 为啥 React 直接返回 jsx ,而Vue需要返回 html 字符串,因为react本身就是使用 JSX 来渲染模版的,最终都会通过 babel 编译成 React.createElement ,而Vue是通过 template 来渲染模版的,这里通过定义 template 模版字符串,最终通过 v-html 来解析
  • 为什么这里有两个 slot-scope ,第一个是 slot-item 的,组件内部通过 slot-scope 将值传递出来。而第二个是 el-table-item 的,ui组件内部同样将数据通过 slot-scope 传递传来。
  • 通过第一个 slot-scope 拿到 propList 中的定义的 render 函数,通过第二个 slot-scope 拿到 table 组件内部传递出来的数据,将数据传递给 render 函数去生成自定义模版

最终通过 v-html 去解析生成的字符串模版

<slot-item :propList="propList" :tableList="tableList">
 <template slot-scope="{content}" v-if="content.render">
  <el-table-column :label="content.label">
   <template slot-scope="{$index,row}">
    <div v-html="content.render(row)"></div>
   </template>
  </el-table-column>
 </template>
</slot-item>
 export default {
  components:{
   SlotItem
  },
  data () {
   return { 
    propList:[
     {label:'姓名',prop:'name',id:1},
     {label:'图片',prop:'pic',id:2,render:({pic})=>{
      return `<img style="width:30px;height:30px" src='${pic}' />`
     }},
     {label:'操作',prop:'operate',id:3,render:({text})=>{
      return `<div style="color:#999">${text}</div>`
     }},
    ],
    tableList:[
     {name:'章三',pic:'https://zh-static-files.oss-cn-hangzhou.aliyuncs.com//karazhan/content/poster/2019/11/16e30c192f6.png',text:'新增'},
     {name:'里斯',pic:'https://zh-static-files.oss-cn-hangzhou.aliyuncs.com//karazhan/content/poster/2019/11/16e30c2797e.png',text:'删除'},
     {name:'网舞',pic:'https://zh-static-files.oss-cn-hangzhou.aliyuncs.com//karazhan/content/poster/2019/11/16e30c33144.png',text:'跳转'},
    ]
   }
  }
 }
</script>

结尾

有了render属性,可以想 ant-design 那样简洁的属性 ui组件模版了!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
XML的代替者----JSON
Jul 21 Javascript
JavaScript中SQL语句的应用实现
May 04 Javascript
JavaScript简单实现网页回到顶部功能
Nov 12 Javascript
JavaScript的Backbone.js框架环境搭建及Hellow world示例
May 07 Javascript
Bootstrap模态框(modal)垂直居中的实例代码
Aug 18 Javascript
利用vue-router实现二级菜单内容转换
Nov 30 Javascript
JS日程管理插件FullCalendar简单实例
Feb 07 Javascript
JavaScript实现前端分页控件
Apr 19 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
Sep 07 jQuery
vue组件与复用详解
Apr 08 Javascript
VUE 实现滚动监听 导航栏置顶的方法
Sep 11 Javascript
react 组件传值的三种方法
Jun 03 Javascript
Vue 解决多级动态面包屑导航的问题
Nov 04 #Javascript
vue+elementUI动态生成面包屑导航教程
Nov 04 #Javascript
VUE+elementui面包屑实现动态路由详解
Nov 04 #Javascript
Vuex,iView UI面包屑导航使用扩展详解
Nov 04 #Javascript
vue双向绑定数据限制长度的方法
Nov 04 #Javascript
使用p5.js临摹动态图片
Nov 04 #Javascript
p5.js绘制创意自画像
Nov 04 #Javascript
You might like
发布一个迷你php+AJAX聊天程序[聊天室]提供下载
2007/07/21 PHP
php jquery 实现新闻标签分类与无刷新分页
2009/12/18 PHP
PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
2011/07/01 PHP
php 解压rar文件及zip文件的方法
2014/05/05 PHP
在PHP中运行Linux命令并启动SSH服务的例子
2014/06/12 PHP
php微信公众平台开发(三)订阅事件处理
2016/12/06 PHP
PHP jQuery+Ajax结合写批量删除功能
2017/05/19 PHP
封装html的select标签的js操作实例
2013/07/02 Javascript
javascript中setTimeout的问题解决方法
2014/05/08 Javascript
js Calender控件使用详解
2015/01/05 Javascript
解决angular的post请求后SpringMVC后台接收不到参数值问题的方法
2015/12/10 Javascript
JavaScript中iframe实现局部刷新的几种方法汇总
2016/01/06 Javascript
vue插件tab选项卡使用小结
2016/10/27 Javascript
JS实现向iframe中表单传值的方法
2017/03/24 Javascript
vue-cli+webpack记事本项目创建
2017/04/01 Javascript
初识 Vue.js 中的 *.Vue文件
2017/11/22 Javascript
jQuery NProgress.js加载进度插件的简单使用方法
2018/01/31 jQuery
JavaScript中常见内置函数用法示例
2018/05/14 Javascript
laydate如何根据开始时间或者结束时间限制范围
2018/11/15 Javascript
js实现多张图片每隔一秒切换一张图片
2019/07/29 Javascript
五分钟搞懂Vuex实用知识(小结)
2019/08/12 Javascript
[52:36]VGJ.S vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
2015/05/15 Python
python通过socket查询whois的方法
2015/07/18 Python
Python+微信接口实现运维报警
2016/08/27 Python
python算法演练_One Rule 算法(详解)
2017/05/17 Python
详解python string类型 bytes类型 bytearray类型
2017/12/16 Python
在windows下Python打印彩色字体的方法
2018/05/15 Python
Kali Linux安装ipython2 和 ipython3的方法
2019/07/11 Python
快速解决pymongo操作mongodb的时区问题
2020/12/05 Python
印度网上药店:1mg
2017/10/13 全球购物
美国婴儿服装购物网站:Gerber Childrenswear
2020/05/06 全球购物
大专生自荐书范文
2014/06/22 职场文书
甜品蛋糕店创业计划书
2014/09/21 职场文书
给校长的建议书作文300字
2015/09/14 职场文书
2016党员三严三实心得体会
2016/01/15 职场文书