基于element-ui 二次封装(未完成)
大约 2 分钟
基于element-ui 二次封装(未完成)
对于组件的封装先要了解以下属性
$attrs 属性
使用
v-bind="$attrs"
可以将父组件的属性传递给子组件
子组件使用$attrs
来获取父组件传递给子组件的属性值
子组件就可以通过$attrs
来访问和使用父组件传递的属性值。
子组件打印console.log(this.$attrs);
$listeners 属性
使用
v-on="$listeners"
可以将父组件的事件监听器传递给子组件
子组件可以通过访问$listeners
来获取父组件传递给子组件事件监听器
子组件就可以通过$listeners
来访问和使用父组件传递的监听器。
子组件打印console.log(this.$listeners);
@eventname
监听父组件传递过来的事件,并在相应的事件处理函数中处理这些事件
$scopedSlots
用于访问父组件的具名插槽
includes()
在 js 中字符串 includes 方法,查找字符串,如果找到返回 true
<template>
<div>
<el-table ref="table" :data="tempData" :header-cell-style="headerCellStyle" :cell-style="cellStyle" v-bind="$attrs"
v-on="$listeners">
<!-- append 表格底部 -->
<template v-if="$slots.append" slot="append">
<slot name="append"></slot>
</template>
<template v-for="item in columns">
<!-- 判断是否有'selection', 'index' 属性 父组件表头数据中加入type -->
<el-table-column v-if=" item.type && ['selection', 'index'].includes(item.type)" :key="`${item.prop}-if`" v-bind="item">
<template v-slot:header="scope">
<slot :name="`header-${item.prop}`" v-bind="scope"></slot>
</template>
</el-table-column>
<el-table-column v-else :key="item.prop" v-bind="item">
<!-- v-if="$scopedSlots[`header-${item.prop}`] 判断名为 item.prop 的插槽是否存在
自定义表头文字 父组件中 <template #header-列的字段名> 例如:<template #header-name>
-->
<template v-slot:header="scope">
<span v-if="$scopedSlots[`header-${item.prop}`]">
<slot :name="`header-${item.prop}`" v-bind="scope"></slot>
</span>
<span v-else>{{ scope.column.label }}</span>
</template>
<template slot-scope="scope">
<span v-if="$scopedSlots[item.prop]">
<slot :name="item.prop" :scope="scope" :item="item"></slot>
</span>
<span v-else>{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</template>
</el-table>
<!-- 前端根据数据列表分页 -->
<!-- <el-pagination class="pagination" v-bind="tempPagination" :current-page="currentPage" :page-size="pageSize"
:total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination> -->
<!-- 后台分页 -->
<!-- <el-pagination class="pagination" v-bind="tempPagination" :current-page="currentPage" :page-size="pageSize"
:total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination> -->
</div>
</template>
<script>
const defaultPagination = { background: true, layout: 'total, sizes, prev, pager, next, jumper' }
export default {
name: 'newTable',
props: {
/** 表头数据 */
columns: {
type: Array,
default: () => []
},
/**
* 分页数据对象 例如:
* {
* currentPage: 1, 当前页
* pageSize: 10, 每页数据
* }
**/
pagination: {
type: Object,
default: () => ({})
},
data: {
type: Array,
default: () => []
},
/** 表头单元格样式配置 */
headerCellStyle: {
type: Function || Object,
default: () => {
return {
'background-color': '#f5f6f7',
'font-size': '12px',
'padding': '10px',
}
}
},
/** 表格单元格的样式配置 */
cellStyle: {
type: Function || Object,
default: () => {
return {
'font-size': '12px',
'padding': '10px'
}
}
},
},
data() {
return {
currentPage: 1,
pageSize: 10,
tempData: [],
}
},
computed: {
paging() {
const offset = (this.currentPage - 1) * this.pageSize
return { offset, limit: this.pageSize }
},
total() {
// return this.data?.length || 0
return this.data?.length || 0
},
tempPagination() {
return { ...defaultPagination, ...this.pagination }
}
},
watch: {
pagination: {
handler(nVal) {
this.currentPage = nVal.currentPage || 1
this.pageSize = nVal.pageSize || nVal.pageSizes?.[0] || 10
},
immediate: true,
deep: true,
},
paging: {
handler() {
this.getTableData()
},
immediate: true,
deep: true,
}
},
mounted() {
const tempStore = this.$refs?.table || {}
for (const key in tempStore) {
if (typeof tempStore[key] === 'function') {
this[key] = tempStore[key]
}
}
},
methods: {
handleSizeChange(val) {
this.pageSize = val;
this.getTableData();
},
handleCurrentChange(val) {
this.currentPage = val;
this.getTableData();
},
getTableData() {
const { offset, limit } = this.paging || {};
this.tempData = this.data.filter((v, i) => i >= offset && i < (offset + limit))
},
}
}
</script>