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

前言

原由:
在使用 element-ui table组件时,因为表列比较多一个个写特别麻烦,因此想经过将全部表头定义成一个数组,经过遍历多方式去实现。这样解决了手写不少 el-table-column 的状况。
障碍:
相似于下面自定义表列的样式,它是经过 slot-scope 去覆盖 el-table-column 内部slot的样式实现的。那咱们在遍历表头数组的时候如何实现呢? html

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

demo:
codepen demo地址react

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

思路

  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 是按行来分数组

  1. 经过props 去接受表头列表,数据列表
  2. 遍历表头数据,而且将 el-table-column 做为默认数据,使用 slot 包裹起来
  3. 经过 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 属性来肯定是否用要去自定义样式覆盖默认的 slotbash

  1. 首先看传递给子组件的表头数据,能够看到,第二,三行列表中有一个render属性,它是一个函数并返回一个 html 的字符串。babel

  2. tableList就是普通的数据,也就是数据的 key 值去渲染对应的数据antd

  3. 图片这列举例子,当父组件经过 props 将 {label,prop,id,render} 传递给子组件后,子组件有经过 slot 将值传递回父组件。antdesign

    • 到这里有些人会有疑问,为何要将数据这样传来传去,由于咱们在子组件中定义好了默认样式,而父组件中须要判断该值是否须要自定义样式,去覆盖子组件中的样式。
    • 这些自定义样式就是一开始,在render函数中返回的 html 字符串
    • 为啥 React 直接返回 jsx ,而Vue须要返回 html 字符串,由于react自己就是使用 JSX 来渲染模版的,最终都会经过 babel 编译成 React.createElement ,而Vue是经过 template 来渲染模版的,这里经过定义 template 模版字符串,最终经过 v-html 来解析
  4. 为何这里有两个 slot-scope ,第一个是 slot-item 的,组件内部经过 slot-scope 将值传递出来。而第二个是 el-table-item 的,ui组件内部一样将数据经过 slot-scope 传递传来。函数

  5. 经过第一个 slot-scope 拿到 propList 中的定义的 render 函数,经过第二个 slot-scope 拿到 table 组件内部传递出来的数据,将数据传递给 render 函数去生成自定义模版post

  6. 最终经过 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组件模版了!

相关文章
相关标签/搜索