Use elmentPlus to operate on the table

1. Required environment and dependencies

  1. view 3
  2. gonePlus

2. A chestnut

  1. Introduce a basic table component
<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. Create a new ts file to store the data of the table header and table content
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. Encapsulate a renderTable component, and cooperate with the customRender function to process any column of the table
<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. Add the customRender function to the configuration file of the tabular data to re-render the current column
// 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. Add judgment to the table component, if the customRender attribute is configured, render according to this
<template #default="scope">
	<renderTable
	  v-if="item.customRender && typeof item.customRender === 'function'"
	  :render="item.customRender"
	  :row="scope.row"
	  :column="scope.column"
	/>
</template>
  1. Chestnut's complete code
    table component:
<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 component:

<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 component:
vue2 writing method:

<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 writing method:

<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 file:

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. result
    insert image description here

未完待续...

Guess you like

Origin blog.csdn.net/du_aitiantian/article/details/131376163
Recommended