使用elmentPlus对表格操作

一. 所需环境、依赖

  1. vue3
  2. elmentPlus

二. 一个栗子

  1. 引入一个基础的table组件
<template>
	<el-table :data="tableData" style="width: 100%">
		<el-table-column type="selection" width="50" />  // 添加勾选框
		<el-table-column type="index" width="80" align="center" label="序号" />   // 添加序号
		<el-table-column v-for="item in tableHeader" :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop">
		// 对其中某一列特殊处理(当prop等于tag的时候,把这列数据用tag标签包裹)
			<template #default="scope">
				<el-tag v-if="item.prop == 'tag'" :type="scope.row.tag === 'Home' ? 'warning' : 'success'">{{ scope.row.tag }}</el-tag>
			</template >
		</el-table-column>

		// 单独设置操作列
		<el-table-column fixed="right" label="操作" width="150">
			<template #default="scope">
				<el-button link type="primary" size="small" @click="clickDelete(scope.$index, tableData)">删除</el-button>
				<el-button link type="primary" size="small" @click="clickEdit(scope)">编辑</el-button>
			</template>
		</el-table-column>
	</el-table>
</template>
<script>
	import { tableHeader, tableData } from './content/contentTableData'  // 路径以自己存放的位置为准
</script>
  1. 新建一个ts文件用于存放表头和表格内容的数据
import { reactive } from 'vue'
import nameTag from '../cmpts/nameTag.vue'
// 表头数据
const tableHeader = reactive([
	{
		prop: 'date',
		label: '时间',
		width: 120
	},
	{
		prop: 'name',
		label: '姓名',
		width: 120,
	},
	{
		prop: 'age',
		label: '年龄',
		width: 120,
	},
	{
		prop: 'state',
		label: '国家',
		width: 120
	},
	{
		prop: 'city',
		label: '城市',
		width: 120
	},
	{
		prop: 'address',
		label: '地点',
		width: 250
	},
	{
		prop: 'tag',
		label: '标记',
		width: 120
	}
])

//  表格数据
const tableData = reactive([
	{
		date: '2016-05-03',
		name: 'Tom',
		age: 18,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Home'
	},
	{
		date: '2016-05-02',
		name: 'Tom',
		age: 8,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Office'
	},
	{
		date: '2016-05-04',
		name: 'Tom',
		age: 20,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Home'
	},
	{
		date: '2016-05-01',
		name: 'Tom',
		age: 28,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Office'
	}
])
export { tableHeader, tableData }
  1. 封装一个renderTable组件,配合customRender函数实现对表格任意一列地处理
<template>
	<renderTable />
</template>
<script setup lang="ts">
const props = defineProps({
	render: {
		type: Function,
		require: true
	},
	row: {
		type: Object,
		require: true
	},
	column: {
		type: Object,
		require: true
	}
})

const renderTable = {
	render: () => {
		const { row, column, render: customRender } = props
		const params = { row, column }
		const vnode = customRender!(params)
		return vnode
	}
}
</script>

<style lang="less" scoped></style>
  1. 在表格数据的配置文件中加入customRender函数用于对当前列重新渲染
// 1. 对年龄列:用一个span标签渲染,当年龄大于等于18的时候显示#267EE5颜色,否则显示#FF3543颜色。
// 2. 对姓名列:重新定义了一个nameTag组件,并引入
import { reactive, h } from 'vue'
const tableHeader = reactive([
	{
		prop: 'age',
		label: '年龄',
		width: 120,
		customRender: ({ row }) => {
			return h('span', { style: { color: row.age >= 18 ? '#267EE5' : '#FF3543' } }, row.age)
		}
	},
	{
		prop: 'name',
		label: '姓名',
		width: 120,
		customRender: ({ row }: any) => {
			return h(nameTag, { row })
		}
	},
])
// 说明:h函数用于创建一个vnode,在vue中是createVNode 函数的简写,接收三个参数
// 参数1. 标签名或组件   参数2. 标签的属性或事件  参数3. 内容
  1. 在table组件中加上判断,如果配置了customRender属性,则按照这个渲染
<template #default="scope">
	<renderTable
	  v-if="item.customRender && typeof item.customRender === 'function'"
	  :render="item.customRender"
	  :row="scope.row"
	  :column="scope.column"
	/>
</template>
  1. 栗子的完整代码
    table组件:
<template>
	<el-table :data="tableData" style="width: 100%">
		<!-- 表格部分 -->
		<el-table-column type="selection" width="50" />
		<el-table-column type="index" width="80" align="center" label="序号" />
		<el-table-column v-for="item in tableHeader" :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop">
			<template #default="scope">
				<el-tag v-if="item.prop == 'tag'" :type="scope.row.tag === 'Home' ? 'warning' : 'success'">{{ scope.row.tag }}</el-tag>
				<renderTable
					v-if="item.customRender && typeof item.customRender === 'function'"
					:render="item.customRender"
					:row="scope.row"
					:column="scope.column"
				/>
			</template>
		</el-table-column>

		<!-- 表格操作部分 -->
		<el-table-column fixed="right" label="操作" width="150">
			<template #default="scope">
				<el-button link type="primary" size="small" @click="clickDelete(scope.$index, tableData)">删除</el-button>
				<el-button link type="primary" size="small" @click="clickEdit(scope)">编辑</el-button>
			</template>
		</el-table-column>
		<!-- 表格操作部分 -->
	</el-table>
	<!-- 表格部分 -->
	<el-tree></el-tree>
</template>

<script setup lang="ts">
import { tableHeader, tableData } from './content/contentTableData'
import renderTable from './cmpts/renderTable.vue'

// 删除逻辑
const clickDelete = (index: number, data: any) => {
	data.splice(index, 1)
}

// 编辑逻辑
const clickEdit = (value: any) => {
	console.log(value)
}

// 表格数据按照时间排序,最新的时间在最上面(从大到小)
const timeOrder = () => {
	tableData.sort(function (a: { date: string }, b: { date: string }) {
		return a.date < b.date ? 1 : -1 // 从大到小
	})
}
timeOrder()
</script>
<style lang="less" scoped></style>

nameTag组件:

<template>
	<el-tag>{{ row.name }}</el-tag>
</template>
<script setup lang="ts">
const props = defineProps({
	row: {
		type: Object,
		required: true
	}
})
console.log(props)
</script>
<style lang="less" scoped></style>

renderTable组件:
vue2写法:

<script lang="ts">
export default {
	props: {
		render: {
			type: Function,
			require: true
		},
		row: {
			type: Object,
			require: true
		},
		column: {
			type: Object,
			require: true
		}
	},
	render() {
		const { row, column, render: customRender } = this
		const params = { row, column }
		const vnode = customRender!(params)
		return vnode
	}
}
</script>
<style lang="less" scoped></style>

vue3写法:

<template>
	<renderTable />
</template>
<script setup lang="ts">
const props = defineProps({
	render: {
		type: Function,
		require: true
	},
	row: {
		type: Object,
		require: true
	},
	column: {
		type: Object,
		require: true
	}
})

const renderTable = {
	render: () => {
		const { row, column, render: customRender } = props
		const params = { row, column }
		const vnode = customRender!(params)
		return vnode
	}
}
</script>
<style lang="less" scoped></style>

contentTableData.ts 文件:

import { reactive, h } from 'vue'
import nameTag from '../cmpts/nameTag.vue'
// 表头数据
const tableHeader = reactive([
	{
		prop: 'date',
		label: '时间',
		width: 120
	},
	{
		prop: 'name',
		label: '姓名',
		width: 120,
		customRender: ({ row }: any) => {
			return h(nameTag, { row })
		}
	},
	{
		prop: 'age',
		label: '年龄',
		width: 120,
		customRender: ({ row }) => {
			return h('span', { style: { color: row.age >= 18 ? '#267EE5' : '#FF3543' } }, row.age)
		}
	},
	{
		prop: 'state',
		label: '国家',
		width: 120
	},
	{
		prop: 'city',
		label: '城市',
		width: 120
	},
	{
		prop: 'address',
		label: '地点',
		width: 250
	},
	{
		prop: 'tag',
		label: '标记',
		width: 120
	}
])

//  表格数据
const tableData = reactive([
	{
		date: '2016-05-03',
		name: 'Tom',
		age: 18,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Home'
	},
	{
		date: '2016-05-02',
		name: 'James',
		age: 8,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Office'
	},
	{
		date: '2016-05-04',
		name: 'Tom',
		age: 20,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Home'
	},
	{
		date: '2016-05-01',
		name: 'Tom',
		age: 28,
		state: 'California',
		city: 'Los Angeles',
		address: 'No. 189, Grove St, Los Angeles',
		tag: 'Office'
	}
])
export { tableHeader, tableData }
  1. 结果
    在这里插入图片描述

未完待续...

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值