Vue3 二次封装el-table以适配移动端

介绍

el-table有两个组件el-table,el-table-column。都要对其进行二次封装,随后在main.js里全局引用即可。使用方法仍然是熟悉的味道
pc效果
pc效果
mobile效果
mobile效果

使用示例

el-table一模一样的写法

<el-table-plus v-loading="loading" :data="data" @selection-change="handleSelectionChange">
	<el-table-column-plus type="selection" width="55" align="center" />
	<el-table-column-plus label="编号" align="center" prop="id" show-overflow-tooltip />
	<el-table-column-plus label="图片" align="center" prop="image" width="100" show-overflow-tooltip>
		<template #default="scope">
			<image-preview :src="scope.row.image" :width="50" :height="50" />
		</template>
	</el-table-column-plus>
	<el-table-column-plus label="文本" align="center" prop="text" />
</el-table-plus>

封装实现

el-table-plus
在v-if="$store.state.app.device == ‘desktop’"处修改自己的设备识别规则

<template>
	<el-table :data="props.data" @selection-change="selectionChange" :border="props.border" v-if="$store.state.app.device == 'desktop'">
		<slot></slot>
	</el-table>
	<div v-else>
		<template v-for="(item,i) in props.data" :key="item.id">
			<el-card shadow="never">
				<el-form label-position="top" label-width="100px" style="max-width: 460px">
					<el-checkbox v-model="item['_checked']" label="选中" @change="handleSelectionChange"
						v-if="isNeedSelection" />
					<template v-for="citem in proxy.$slots['default']()" :key="citem">
						<template v-if="citem.props">
							<template v-if="citem.props.type === 'index'">
							</template>
							<template v-else-if="citem.props.type === 'expand'">
							</template>
							<template v-else-if="citem.props.type === 'selection'">
							</template>
							<el-form-item v-else :label="citem.props.label">
								<template v-if="citem && citem.children">
									<component :is="citem" :scope="item" :prop="citem.props.prop"></component>
								</template>
								<template v-else>
									<component :is="citem" :scope="item"></component>
								</template>
								<!-- <el-divider></el-divider> -->
							</el-form-item>
						</template>
					</template>
				</el-form>
			</el-card>
			<el-divider v-if="i+1 != props.data.length"></el-divider>
		</template>
	</div>
</template>

<script setup>
	const {
		proxy
	} = getCurrentInstance(); // 获取实例中的proxy

	 console.log(proxy)
	 console.log(proxy.$slots['default']())
	 console.log(proxy.$slots['default']()[0].type.render())

	const props = defineProps({
		data: {
			type: Array,
			default: function() {
				return [];
			}
		},

		size: String,

		width: [String, Number],

		height: [String, Number],

		maxHeight: [String, Number],

		fit: {
			type: Boolean,
			default: true
		},

		stripe: Boolean,

		border: Boolean,

		rowKey: [String, Function],

		context: {},

		showHeader: {
			type: Boolean,
			default: true
		},

		showSummary: Boolean,

		sumText: String,

		summaryMethod: Function,

		rowClassName: [String, Function],

		rowStyle: [Object, Function],

		cellClassName: [String, Function],

		cellStyle: [Object, Function],

		headerRowClassName: [String, Function],

		headerRowStyle: [Object, Function],

		headerCellClassName: [String, Function],

		headerCellStyle: [Object, Function],

		highlightCurrentRow: Boolean,

		currentRowKey: [String, Number],

		emptyText: String,

		expandRowKeys: Array,

		defaultExpandAll: Boolean,

		defaultSort: Object,

		tooltipEffect: String,

		spanMethod: Function,

		selectOnIndeterminate: {
			type: Boolean,
			default: true
		},

		indent: {
			type: Number,
			default: 16
		},

		treeProps: {
			type: Object,
			default () {
				return {
					hasChildren: 'hasChildren',
					children: 'children'
				};
			}
		},

		lazy: Boolean,

		load: Function
	});


	const indexList = ref([]);

	const selectionChange = (selection) => {
		proxy.$emit('selectionChange', selection)
	}

	const handleSelectionChange = () => {
		const selection = props.data.filter(item => item['_checked'])
		 console.log(selection)
		selectionChange(selection)
	}

	const isNeedSelection = computed(() => {
		let result = proxy.$slots['default']().filter(item => {
			if (item && item.props && item.props.type === 'selection') {
				return true
			}
			return false
		})
		return result.length > 0
	})
</script>

el-table-column-plus

<template>
	<el-table-column v-if="$store.state.app.device == 'desktop' && props.type === 'index'" type="index"
		:label="props.label" :width="props.width" :align="props.align" />
	<el-table-column v-else-if="$store.state.app.device == 'desktop' && props.type === 'selection'" type="selection"
		:label="props.label" :width="props.width" :align="props.align" />
	<el-table-column v-else-if="$store.state.app.device == 'desktop' " :type="props.type" :label="props.label"
		:align="props.align" :prop="props.prop" :show-overflow-tooltip="props.showOverflowTooltip" :width="props.width"
		:fixed="props.fixed">
		<template #default="scope">
			<slot :row='scope.row'>
				<div>
					{{scope.row[props.prop]}}
				</div>
			</slot>
		</template>
	</el-table-column>
	<div v-else>
		<slot :row='props.scope'>
			<div>
				{{props.scope[props.prop]}}
			</div>
		</slot>
	</div>
</template>

<script setup>
	const {
		proxy
	} = getCurrentInstance(); // 获取实例中的proxy


	 console.log(`proxy`)
	 console.log(proxy)
	 console.log(`proxy`)
	const props = defineProps({
		scope: {

		},
		type: {
			type: String,
			default: 'default'
		},
		label: String,
		className: String,
		labelClassName: String,
		property: String,
		prop: String,
		width: {},
		minWidth: {},
		renderHeader: Function,
		sortable: {
			type: [Boolean, String],
			default: false
		},
		sortMethod: Function,
		sortBy: [String, Function, Array],
		resizable: {
			type: Boolean,
			default: true
		},
		columnKey: String,
		align: String,
		headerAlign: String,
		showTooltipWhenOverflow: Boolean,
		showOverflowTooltip: Boolean,
		fixed: [Boolean, String],
		formatter: Function,
		selectable: Function,
		reserveSelection: Boolean,
		filterMethod: Function,
		filteredValue: Array,
		filters: Array,
		filterPlacement: String,
		filterMultiple: {
			type: Boolean,
			default: true
		},
		index: [Number, Function],
		sortOrders: {
			type: Array,
			default () {
				return ['ascending', 'descending', null];
			},
			validator(val) {
				return val.every(order => ['ascending', 'descending', null].indexOf(order) > -1);
			}
		}
	})
</script>
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值