基于vue2.x的jsx二次封装element-ui的table实验

300 阅读1分钟

自从接触vue后,不管是写项目还是做组件的封装,都是基于template。虽然,是用起来很方便简洁,但如果做一些更基础的组件封装时,功能是能实现,但是代码看起来很别扭。感觉template虽好,有些场景用来不是很灵活。在看到其他作者推荐使用jsx做组件封装时,自己也打算试试,一份方面是走出自己的舒适区,另一方通过使用vue的render和实例property也对vue有更好的了解。 这是拿element-ui的table二次封装练练手。

子组件部分:

<script>
export default {
  inheritAttrs: false,
  props: {
    datas: { //数据
      type: Array,
      default: () => []
    },
    config: {// 绑定参数,标题显示
      type: Array,
      default: () => []
    }
  },
  render() {
    const elTableColumns = this.config.map(config => {
      if (config.selection) {
        return <el-table-column type="selection" width={config.width || 55}></el-table-column>
      } else {
        return <el-table-column label={config.label} {...{
          scopedSlots: {
            default: props => {
              if (config.slot) {
                return this.$scopedSlots[config.slot](props.row)
              }
              else {
                return <span>{props.row[config.prop]}</span>
              }
            }
          }
        }}>
        </el-table-column>
      }
    })
    const elTable = <el-table data={this.datas} on={this.$listeners} >{elTableColumns}</el-table>;
    return (elTable);
  }
}
</script>

父组件

<template>
  <div id="app">
    <cus-element-ui
      :datas="datas"
      :config="config"
      @selection-change="handleSelectionChange"
      width="100%"
      background-color="red"
    >
      <template v-slot:name="scope"><el-input v-model="scope.name" /></template>
      <template v-slot:age="scope"><el-input v-model="scope.age" /></template>
    </cus-element-ui>
  </div>
</template>

<script>
import cusElementUi from '@/components/cus-element-ui'
export default {
  name: 'App',
  components: {
    cusElementUi
  },
  data() {
    return {
      config: [
        { selection: "selection" },
        { prop: 'name', label: '姓名', slot: 'name' },
        { prop: 'age', label: '年龄', slot: 'age' },
        { prop: 'height', label: '身高' }
      ],
      datas: [
        { name: '小明', age: 18, height: '180cm' },
        { name: '小红', age: 18, height: '160cm' },
        { name: '小王', age: 18, height: '160cm' },
      ]
    }
  },
  methods: {
    handleSelectionChange(value) {
      console.log(value);
    }
  }
}
</script>

最总效果,感觉还不错。

1632149707(1).png