本文详细介绍如何在Vue.js项目中封装通用的Table组件,旨在简化后台管理系统的开发流程。通过定义统一的数据结构,支持普通数据展示、自定义插槽以及多种按钮操作场景。文章涵盖组件的全局注册方法、handleFilter数据处理逻辑及分页组件的集成,帮助开发者实现高效、可复用的表格组件。
近期启动新项目,本文简要分享Table组件的封装思路与实践。
问题分析
封装的必要性
封装并非单纯为了追求技术高度,更多是出于提升效率的考量。为了避免在创建新表格时重复粘贴复制代码,通过封装Table组件,开发者只需填充数据即可快速生成表格,从而减少冗余工作。
封装范围
本次封装主要包含两个部分:核心的Table组件以及配套的分页组件。
明确上述目标后,即可着手进行组件的封装工作。
Table组件封装步骤
确定数据结构
首先需明确数据格式,参考Element UI的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>
接下来考虑数据类型,包括label、prop、width、按钮类型及事件处理等字段。
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文件夹,将组件放入其中。建议每个组件单独占用一个文件夹,以便于后续维护。
创建名为FrTable的table.vue组件,具体实现细节稍后说明,先介绍引用方式。
全局使用配置
将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)
页面中的具体应用
<fr-table />
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 UI的分页组件进行设计。
<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组件的封装工作即告完成。
总结
至此,关于Vue.js管理后台Table组件封装的文章介绍完毕。更多相关Vue后台Table封装内容,请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!