二次封装el-table组件
element-ui
不同于其他的ui框架,table的字段可以传入一个数组就可以,而是每次都需要写结构 所以想自己封装一个像其他ui框架的组件,方便自己使用。也为了可以偷懒
先简单封装分页器
<template>
<div style="display: flex;justify-content: space-between;margin: 10px">
<div class="legend">
<!-- 左边的提示内容 -->
<slot></slot>
</div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes="pageSizes || [12, 20, 30, 40]"
:page-size="listQuery.limit"
:current-page="listQuery.page"
:pager-count="pagerCount"
:layout="layout"
:total="count">
</el-pagination>
</div>
</template>
<script>
export default {
name: "Pagination",
props: {
listQuery: {
type: Object,
default: ()=>{}
},
count: {
type: Number,
default: 0
},
pagerCount: {
type: Number,
default: 7
},
layout:{
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
pageSizes:{
type:Array,
default:[12, 20, 30, 40]
}
},
data: () => ({
}),
methods: {
handleSizeChange(v){
let listQuery = this.listQuery
listQuery.limit = v
this.$emit('update:listQuery',listQuery)
this.$emit('getList')
},
handleCurrentChange(v){
let listQuery = this.listQuery
listQuery.page = v
this.$emit('update:listQuery',listQuery)
this.$emit('getList')
}
}
}
</script>
封装el-table (暂时兼容二级表头 后面再兼容多层)
主要利用
$listeners
https://v2.cn.vuejs.org/v2/api/#vm-listeners
$attrs
https://v2.cn.vuejs.org/v2/api/#vm-attrs
v-slot
https://v2.cn.vuejs.org/v2/api/#v-slot
<template>
<div id="renderTable">
<el-table v-bind="$attrs" :data="data" class="table" v-on="$listeners">
<template #default>
<el-table-column
v-for="item in columns"
v-bind="item"
:header-align="item.headerAlign || 'center'"
:align="item.align || 'center'"
:key="item.prop"
>
<template
v-if="item.slot && !item.children"
v-slot="{ row, column, $index }"
>
<slot :name="item.prop" v-bind="{ row, column, $index }"></slot>
</template>
<el-table-column
v-for="jtem in item.children"
:header-align="jtem.headerAlign || 'center'"
:align="jtem.align || 'center'"
:key="jtem.prop"
v-bind="jtem.slot ? dealSlot(jtem) : jtem"
>
<template v-if="jtem.slot" v-slot="{ row, column, $index }">
<slot :name="jtem.prop" v-bind="{ row, column, $index }"></slot>
</template>
</el-table-column>
</el-table-column>
</template>
</el-table>
<Pagination
v-if="paging"
:listQuery.sync="listQuery"
:count.sync="count"
v-on="$listeners"
></Pagination>
</div>
</template>
<script>
export default {
name: "renderTable",
inheritAttrs: false,
props: {
columns: {
type: Array,
required: true,
},
data: {
type: Array,
required: true,
},
paging: {
type: Boolean,
default: false,
},
listQuery: {
type: Object,
},
count: {
type: Number,
},
},
methods: {
dealSlot(obj) {
//深克隆的方法可以自己处理
let res = this.$deepClone(obj)
delete res.slot
return res
},
},
}
</script>
<style lang="scss" scoped>
table {
width: 100%;
}
</style>
import App from "./App.vue"
import router from "./router"
import store from "./store"
const Pagination = () => import("./components/Pagination")
const renderTable = () => import("./components/table/renderTable")
Vue.component("Pagination", Pagination) // 注册分页组件
Vue.component("renderTable", renderTable) // 注册表格组件
使用
<template>
<div class="table">
<renderTable
:data="tableData"
:columns="columns"
:border="true"
:stripe="true"
v-loading="loading"
:paging="true"
:listQuery.sync="listQuery"
:count.sync="count"
@getList="getList"
>
<template #order="{ $index }">
<span> {{ (listQuery.page - 1) * listQuery.limit + $index + 1 }}</span>
</template>
<template #sex="{ row }">
<span> {{ row.sex ? "男" : "女" }}</span>
</template>
<template #merry="{ row }">
<span> {{ row.merry ? "已婚" : "未婚" }}</span>
</template>
</renderTable>
</div>
</template>
<script>
export default {
data() {
return {
listQuery: {
vagueSearch: "",
dateArr: [],
page: 1,
limit: 12,
},
count: 10,
tableData: [
{
id: 1,
name: "小明",
sex: "1",
age: 18,
nation: "汉族",
phone: "13000000000",
merry: 0,
address: "广州市天河区",
},
],
columns: Object.freeze([
{prop: "order",label: "序号",width: 150,slot: true},
{prop: "name",label: "姓名",width: 200},
{prop: "sex",label: "性别",width: 200,slot: true},
{prop: "age",label: "年龄",width: 200},
{prop: "info",label: "个人信息",width: 300,
children: [{prop: "phone",label: "手机号"},{prop: "address",label: "联系地址"}]},
{prop: "nation",label: "民族",width: 200},
{prop: "merry",label: "婚姻状况",width: 200,slot: true},
])
}
},
methods: {
getList() {},
},
}
</script>