最近开了新的项目,简单说了自己的table封装。
问题分析
为什么封装
首先为什么封装,是因为追求技术吗,不,是因为懒,不想一直的去粘贴复制代码,所以就想把table封装下,可以在创建新的table的时候,只需要填充数据就行了。
封装的内容都有哪些
主要有两个,一个是table组件,一个是分页组件
搞清楚这个些,就可以开始封装组件了。
封装table组件
确认数据格式
先确定数据格式,这个我们需要看下el-table组件
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180" />
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
<el-button type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>
现在我们考虑数据类型,例如lebel, prop, widht 按钮类型, 事件等等,
let paramsType = {
data: Array, // 数据
loading: Boolean,
selectionShow: Boolean,
columns:Array = [
{
label: String,
prop: String,
filter: Function,
isSlot: Boolean,
width: Number,
tempalte: Function,
btns: Array = [
{ name: String,
btnType: String,
clickType: String,
routerType: String,
url: String,
query: Function,
btnClick: Function
}
]
}
]
}
定义号数据文档后,我们就可以开始封装组件了
封装组件
封装全局组件
之所以封装全局组件是为了省事,所有的目的,全都是为了偷懒。
src下创建components文件,里边写我们的组件,每个组件建议单独文件夹,便于我们维护。
创建自己的table.vue组件,名字我的叫FrTable,内容暂时先不说,先说引用。
全局使用
导入FrTable文件到components下的index.js文件中,在这里遍历所有的组件,并导出
代码如下:
import TrTable from './FrTable/index'
const components = [TrTable]
const install = (Vue) => {
components.map(component => {
Vue.component(component.name, component)
})
}
if (typeof Window !== 'undefined' && window.Vue) {
install(Window.Vue)
}
export default {
install
}
然后导出到main.js中,通过Vue.use()来使用组件,如下
import globalComponents from '@/components/index'
Vue.use(globalComponents)
页面中的使用
table组件封装
考虑的问题
table中有多少种情况,
第一种的类型那我们其实是不需要操作太多,只需要通过for循环渲染就可以了。
第二种其实也还好,我们可以通过slot做定制化处理
第三种,按钮的操作。按钮其实可以分多种类型
按钮的类型
- 按钮的正常使用,点击功能
- 按钮起跳转作用
- 按钮起打开新页面的作用
- 按钮起自定义事件的作用
代码的编写
通过上边,我们已经分析了table的所有问题,现在只需要敲代码就可以了。
第一种情况
<el-table :data="data" border :loading="loading">
<!-- 勾选 -->
<el-table-column v-if="selectionShow" type="selection" width="50" align="center" :reserve-selection="true" />
<template v-for="(item, index) in columns">
<el-table-column :key="index" v-bind="item">
<!-- 自定义表头 -->
<template v-if="item.customHeader" slot="header">
<slot :name="item.headerProp" />
</template>
<template slot-scope="scope">
<span v-html="handleFilter(item, scope.row, item.prop)" />
</template>
</el-table-column>
</template>
</el-table>
这里我们可以看到handleFilter方法
这个方法来处理数据,
数据类型分为正常数据类型,需要转化的数据类型,模板转化的数据类型,
代码如下
handleFilter(item, val, prop) {
let value = val[prop]
if (item.templet) value = item.templet(val)
return item.filter ? this.$options.filters[item.filter](val[prop]) : value
},
第一种情况比较简单,只是简单的数据渲染,和定制化的表头渲染,上边总体的是多选功能+正常的表单
第二种情况
自定义的列表
<template slot-scope="scope">
<!-- 自定义内容 -->
<slot
v-if="item.isSlot"
:name="item.prop"
:row="scope.row"/
>
</template>
自定义的类别,我们只需要isSlot设置为true,name为prop,row为data
第三种
第三种按钮分四种情况
<template v-if="item.btns">
<el-button
v-for="(btn, i) in item.btns"
:key="i"
class="mr_10"
:size="btn.mini ? btn.mini: 'small'"
:type="btn.type ? btn.type: 'primary'"
@click="btnClickfunc(btn, scope.row)"
>
{{ btn.name }}
</el-button>
</template>
按钮其实还是循环渲染的,主要是事件的分析,通过btnClickfunc事件操作。
btnClickfunc(column, row) {
const path = {
[column.routerType]: column.url,
query: column.query ? column.query(row) : ''
}
if (column.clickType === 'router') {
this.$router.push(path)
} else if (column.clickType === 'router_blank') {
const routeData = this.$router.resolve(path)
window.open(routeData.href, '_blank')
} else if (column.clickType === 'btnClick') {
column.btnClick(row)
} else {
this.$emit('btnClickFunc', { column: column, row: row })
}
},
分不同的类型,我们做不同的处理。
props传参的值
当前的参数,和我们定义的参数是一致的,因此代码如下
// 数据
data: {
type: Array,
required: true
},
// 表头参数
columns: {
type: Array,
required: true
},
loading: {
type: Boolean,
default: false
},
// 多选框选择
selectionShow: {
type: Boolean,
default: false
},
自此,只剩下了组件的使用方式了
组件的使用
<fr-table
ref="mt"
:loading="loading"
:data="list"
:columns="columns"
>
</fr-table>
大致如下,如果需要使用多选的时候,自行定义方法,排序也一样。
分页组件封装
参考element分页组件
<el-pagination
style="margin-top:40px;"
background
layout="prev, pager, next"
:page-size="pageLimit"
:total="total"
:current-page="currentPage"
@current-change="handleCurrentChange"
/>
handleCurrentChange(val) {
console.log(val)
}
数据定义
定义如下:
total: Number,
pageLimit: Number,
currentPage: Number,
封装
<el-pagination
style="margin-top:40px;"
background
layout="prev, pager, next"
:page-size="pageLimit"
:total="total"
:current-page="currentPage"
@current-change="handleCurrentChange"
/>
handleCurrentChange(val) {
this.$emit('currentChange', val)
}
看上去是不是很简单,其实就是这么简单。
然后我们在组件上把分页事件和参数加上,我们整个table的组件封装就完成了,至此,我们完成了整个table组件封装的全部工作。
总结
到此这篇关于vue.js管理后台table组件封装的文章就介绍到这了,更多相关vue后台table封装内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论