vue2/vue3基于elementui-table实现render函数

vue2/vue3基于element-table实现render函数

vue2实现render

// 只展示核心代码
// standarTable.vue
<el-table
  :data="dataSource"
  ref="standarTable"
>
  <template v-for="(col, key) in columns || []">
    <!-- 操作列/自定义列 -->
    <slot v-if="col.slot" :name="col.prop || col.slot"></slot>
    <el-table-column v-else>
      <template slot-scope="scope">
        <!-- 正常渲染 -->
        <template v-if="!col.render">
          <template v-if="col.formatter">
            <span v-html="col.formatter(scope.row, col)"></span>
          </template>
          <template v-else>
            <span>{{scope.row[col.prop]}}</span>
          </template>
        </template>
        <!-- render函数 -->
        <template v-else>
          {{ renderToHtml(col, scope.row) }}
          <slot :name="col.prop"></slot>
        </template>
      </template> 
    </el-table-column>
  </template>
  <template slot="empty">
    <avue-empty desc="暂无数据" />
  </template>
</el-table>
    
<script>
export default {
	name: "standarTable",
	methods: {
		// 使用js动态新增一个slot实现render函数jsx语法渲染
    	renderToHtml(col, row) {
     		if (typeof col.render === 'function') {
        		this.$slots[col.prop] = [col.render(row)]
        		return
      		}
      		return
    	},
	}
}
</script>
// 调用
<template>
	<standar-table :columns="columns"></standar-table>
</template>
<script>
	export default {
		data() {
			return {
				columns: [
		          {
		            label: "测试",
		            prop: "upperLimit",
		            align:'center',
		            render:(row) => {
		              return <span>{row.upperLimit}</span>
		            }
		          }
		        ]
			}
		}
	}
</script>

vue3实现render
由于vue3试了很多方法都没法实现js动态添加slot,就换了种实现方式。

// 先安装支持jsx语法的依赖,方便render函数里使用html标签
npm install @vitejs/plugin-vue-jsx --save-dev
// 在vite.config.js配置文件里添加插件配置
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from '@vitejs/plugin-vue-jsx'

export default ({ mode }) => defineConfig({
	plugins: [
	  vue(),
      // 支持jsx语法
      vueJsx(),
	]
})
// 只展示核心代码
// standarTable.vue
  <el-table
    :data="tableData"
    v-loading="loading"
  >
    <el-table-column label="序列号" v-if="showIndex" width="70" align="center">
      <template #default="scope">
        <span>{{ (pageObj.page - 1) * pageObj.size + scope.$index + 1 }}</span>
      </template>
    </el-table-column>
    <el-table-column
      v-for="(column, index) in columns"
    >
      <template #default="scope">
        <!-- 正常渲染 -->
        <template v-if="!column.render">
          <div v-if="column.slot">
            <slot
              :item="tableData[scope.$index]"
              :index="scope.$index"
              :name="column.slot"
            ></slot>
          </div>
          <span v-else>{{ scope.row[column.prop] }}</span>
        </template>
        <!-- render函数 -->
          <!-- 如果rander函数里需要套上html标签,父组件《script lang="jsx》需要加上lang="jsx" -->
        <template v-else>
          <expandDom :column="column" :row="scope.row" :render="column.render" :index="scope.$index"></expandDom>
        </template>
      </template>
    </el-table-column>
  </el-table>
  
<script>
// 引入利用render渲染的组件,后缀名定的是什么类型的文件要将后缀名写全
import expandDom from './commonJs/expandDom.jsx'

export default {
	name: "standarTable",
	components:{expandDom},
	props: {...}
}
</script>
// expandDom.jsx
// 不使用template模板渲染,使用render方式渲染,解析传进来的函数
import { defineComponent } from 'vue';
export default defineComponent({
  name: 'expandDom',
    props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
            type: Object,
            default: null
        }
    },
    render() {
    	// 这里能使用react的空标签<>就是@vitejs/plugin-vue-jsx插件的功劳
    	// return this.render(this.row)
        return <>{this.render(this.row)}</>
    }
})
// 调用
<template>
	<standarTable
      :columns="columns"
      ref="standarTable"
    >
    </standarTable>
</template>

// 加上lang="jsx"才能支持jsx语法
<script lang="jsx">
export default {
	components:{...},
	setup(props) {
		const columns = [
	    { prop: "title", name: "标题", width: 150,render:(row) => {
	        // return row.title
	        return <span>{row.title}</span>
	       }}
		}]
}
</script>
上一篇:118. 杨辉三角


下一篇:C语言小项目之三子棋