100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > vue结合 element-ui实现强大的后台管理系统表格组件

vue结合 element-ui实现强大的后台管理系统表格组件

时间:2020-05-02 09:37:48

相关推荐

vue结合 element-ui实现强大的后台管理系统表格组件

vue结合 element-ui实现强大的后台管理系统表格组件

简介

表格作为后台管理系统的最重要的基础组件之一,功能越强大,后续所做的开发量就越小,这里把常见的提炼出来,分享给大家。基础功能支持loading,分页,按钮操作,数据格式化,数据选择等。

主要依赖说明 (先安装,步骤略)

{"element-ui": "2.11.1", "vue": "^2.6.10","vue-router": "^3.0.1","font-awesome": "4.7.0"}

正文

1.组件

src/components/Table.vue

<template><div><!-- 表头 --><div v-if="title" class="table-title">{{ title }}</div><!-- 表格主体 --><el-table:ref="ref"v-loading="listLoading":data="tableData":border="isBorder":element-loading-text="loadingText":header-cell-style="{backgroundColor: '#e5e9f2', color: '#333' }"highlight-current-rowstripesize="small"empty-text="暂无数据"@selection-change="handleSelectionChange"><!-- 多选配置 --><el-table-column v-if="isSelection" type="selection" width="55"></el-table-column><!-- 表格索引 --><el-table-column v-if="isShowNumber" fixed="left" type="index" :index="tableIndex"></el-table-column><!-- 表格行 item.showOverflowTooltip 设置表格文字过长显示省略号 --><el-table-columnv-for="(item, index) in config":key="index":prop="item.prop":label="item.label":width="item.width":show-overflow-tooltip="item.showOverflowTooltip"><template slot-scope="scope"><!-- format = img, 显示图片 --><span v-if="item.format === 'img'"><img title="点击查看大图" alt="图片" class="image-size" :src="scope.row[item.prop]" /></span><!-- format = timestamp, 把时间戳转换成YYYY-MM-dd HH:mm:ss ,parseTime过滤器后文会提到 --><span v-else-if="item.format === 'timestamp'">{{ scope.row[item.prop] | parseTime }}</span><!-- format = money, 显示金额 --><span v-else-if="item.format === 'money'">{{ '¥'+scope.row[item.prop] }}</span><!-- format = rate, 显示比例 --><span v-else-if="item.format === 'rate'">{{ scope.row[item.prop]+"%" }}</span><!-- format = number, 显示数字--><span v-else-if="item.format === 'number'">{{ Number(scope.row[item.prop]) }}</span><!-- format = a, 网页跳转 --><span v-else-if="item.format === 'a'"><u class="link"><a :href="scope.row[item.prop]" target="_blank">{{ scope.row[item.prop] }}</a></u></span><!-- 需要添加其他数据处理,继续添加 v-else-if="item.format === ''" 就好 --><!-- 没有format --><span v-else>{{ scope.row[item.prop] }}</span></template></el-table-column><!-- 表格操作按钮栏 --><el-table-columnv-if="isHasButtons"class="clearfix":width="optionColumnWidth+'px'"fixed="right"label="操作"><template slot-scope="scope"><!-- 基本操作 --><spanv-for="(option, index) in getOptionsName(scope.row.buttonKey).slice(0,buttonCount)":key="index"class="button-margin-left"><el-buttonsize="small":type="index == 0 ? 'primary' : ''"@click="handleClickOption(scope.$index, scope.row, option,$event)"><span v-html="getButtonHtml(option)"></span></el-button></span><!-- 更多操作 --><el-dropdownv-if="getOptionsName(scope.row.buttonKey).length > buttonCount"trigger="click"><span class="el-dropdown-link">更多<i class="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu slot="dropdown" class="custom-dropdown-menu"><el-dropdown-itemv-for="(option, index) in getOptionsName(scope.row.buttonKey).slice(buttonCount)":key="index"class="custom-dropdown-menu-item"><el-buttonsize="small"@click="handleClickOption(scope.$index, scope.row, option,$event)"><span v-html="getButtonHtml(option)"></span></el-button></el-dropdown-item></el-dropdown-menu></el-dropdown></template></el-table-column></el-table><!-- 分页组件 --><div v-if="isShowPagination && total > 0" class="pagination-container"><el-paginationbackgroundlayout="total, sizes, prev, pager, next, jumper":current-page="page":page-sizes="pageSizeList":page-size="limit":total="total"@current-change="handleCurrentChange"@size-change="handleSizeChange"></el-pagination></div></div></template><script>export default {name: 'AppTable',props: {// 是否需要序号isShowNumber: {type: Boolean,default: true},// 是否需要翻页组件isShowPagination: {type: Boolean,default: true},// 是否需要栅格isBorder: {type: Boolean,default: true},// 是否是多选表格,默认非多选 :ref="'multipleTable'"isSelection: {type: Boolean,default: false},// 是否有操作按钮isHasButtons: {type: Boolean,default: true},// 表头名称title: {type: String},// 表格数据tableData: {type: Array,required: true},// 表格配置信息config: {type: Array,required: true},// loading提示框loadingText: {type: String,default: '加载中...'},// loading状态loadingStatus: {type: Boolean,default: false},// 表格查询列表参数listQueryParams: {type: Object},// 根据当前行的状态显示按钮的名称buttonsName: {type: Object},// 操作列表宽度optionColumnWidth: {type: Number,default: 100},// 分页数据pageSizeList: {type: Array,default: function() {return [10, 20, 30, 50, 100]}},// 显示的操作栏按钮个数,多余的显示在dropdown里buttonCount: {type: Number,default: 2}},computed: {// 看是否是多选表格ref: function() {return this.isSelection ? 'multipleTable' : undefined},// 第几页page: function() {return this.listQueryParams.page || 1},// 每页数据数limit: function() {return this.listQueryParams.limit || 10},// 数据总数total: function() {return this.listQueryParams.total || 0},// 获取当前loading的状态listLoading: function() {return this.loadingStatus}},methods: {// 根据按钮的名称,获取按钮的html样式,让按钮有个图标,这里使用的是font-awesome,要使用的话先安装getButtonHtml(name) {let classNameswitch (name) {case '查看':className = 'eye'breakcase '编辑':className = 'pencil'breakcase '审核':className = 'check-circle'breakcase '置顶':className = 'arrow-circle-o-up'breakcase '取消置顶':className = 'times-circle'breakcase '推荐':className = 'thumbs-o-up'breakcase '上线':className = 'space-shuttle'breakcase '下线':className = 'space-shuttle'breakcase '删除':className = 'times-circle-o'breakcase '分析':className = 'bar-chart'breakcase '排序':className = 'sort'break}if (className) {return `<span><i class="fa fa-${className}"></i> ${name}</span>`} else {return name}},// 获取当前操作的按钮组getOptionsName(key) {return this.buttonsName[key] || []},// 点击按钮传递给父组件handleClickOption(index, row, option) {this.$emit('subOpitonButton', index, row, option)},// 表格选择分发事件handleSelectionChange(val) {this.$emit('subSelected', val)},// 改变翻页组件中每页数据总数handleSizeChange(val) {this.listQueryParams.limit = val// 改变翻页数目,将页面=1this.listQueryParams.page = 1this.$emit('update:listQueryParams', this.listQueryParams)this.$emit('subClickPagination', this.listQueryParams)},// 跳到当前是第几页handleCurrentChange(val) {this.listQueryParams.page = valthis.$emit('update:listQueryParams', this.listQueryParams)this.$emit('subClickPagination', this.listQueryParams)},// 重写索引生成方法tableIndex(index) {const i = (this.page - 1) * this.limit + index + 1return i}}}</script><style lang="scss" scoped>.image-size {width: 30px;height: 30px;cursor: pointer;}.table-title {margin-top: 10px;font-size: 18px;}.el-dropdown {cursor: pointer;margin-left: 20px;.el-dropdown-link {user-select: none;cursor: pointer;}}.button-margin-left {margin-left: 8px;}.link {cursor: pointer;color: #4876ff;}</style><style lang="scss" >.el-table {.el-table__empty-block {height: unset;}}.custom-dropdown-menu {cursor: pointer;.custom-dropdown-menu-item {margin-top: 10px;text-align: center;}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover {background-color: #fff;color: #fff;}}</style>

2.使用

<template><div><el-row class="margin-top-10"><el-card><app-table :list-query-params.sync="listQueryParams" v-bind="tableAttrs" v-on="tableEvent" /></el-card></el-row></div></template><script>import AppTable from '@/components/Table'// 定义的接口根据自己项目更换import TalentServe from '@/api/talent'// 表格查询参数const DefaultTableQuery = {page: 1,limit: 10,total: 0}export default {name: 'UserList',components: {AppTable},data() {return {// 表格加载loadingloadingStatus: false,// 操作栏宽度optionWidth: 280,// 表头配置 prop字段和服务端数据给的字段一致tableConfig: [{label: '昵称',width: '120px',prop: 'nickname'},{label: '头像',width: '120px',prop: 'headImgUrl',// 显示图片format: 'img'},{label: '手机号',width: '120px',prop: 'mobile'},{label: '注册时间',width: '140px',prop: 'registrationDate',// 显示时间format: 'timestamp'},{label: '邀请人',width: '80px',prop: 'inviterUser'},{label: '收益金额',width: '120px',prop: 'integrals',format: 'money'},// 最后一个不给宽度让表格自适应{label: '类型',prop: 'customIsExpressive'}],// 参数listQueryParams: {...DefaultTableQuery },// 列表数据tableData: [],// url参数params: {pageInfo: {pageSize: 10,pageNo: 1}},// 操作栏按钮buttonsName: {normal: ['查看', '编辑', '设为可提现'],special: ['查看', '编辑', '取消可提现']},// 选择数据selectData: [],// 操作数据operationalData: {}}},computed: {// 表格属性tableAttrs() {return {// 表头配置config: this.tableConfig,// 表格数据tableData: this.tableData,// loadingloadingStatus: this.loadingStatus,// 按钮名称buttonsName: this.buttonsName,// 操作栏宽度optionColumnWidth: this.optionWidth,// 是否需要选择isSelection: true}},// 表格事件tableEvent() {return {// 按钮操作subOpitonButton: this.handleTableOption,// 分页subClickPagination: this.handleRefreshList,// 表格数据选择subSelected: this.handleSelectionChange}}},created() {this.getList()},methods: {// 获取列表async getList() {try {// 表格加载loadingthis.loadingStatus = true// 分页数据作为参数给服务端this.params.pageInfo.pageSize = this.listQueryParams.limitthis.params.pageInfo.pageNo = this.listQueryParams.page// 发送请求,请求到的数据格式见下文,const {data, cntData } = await TalentServe.getTalentList(this.params)const tableData = data || []tableData.forEach(item => {if (item.isExpressive === '1') {// 给每一行设置buttonKey对应于data里定义的buttonsName的key值// buttonsName: {// normal: ['查看', '编辑', '设为可提现'],// special: ['查看', '编辑', '取消可提现']// },//item.buttonKey = 'special'} else {item.buttonKey = 'normal'}// 修改显示的数据item.customIsExpressive =item.isExpressive === '1' ? '可提现' : '不可提现'})// 分页组件显示 this.listQueryParams.total 值大于0才会出现this.listQueryParams.total = cntData// 数据给表格this.tableData = datathis.loadingStatus = false} catch (error) {console.log(error)}},// 表格操作功能 index:表格索引, row:表格行数据, option:按钮名称handleTableOption(index, row, option) {this.operationalData = {...row }if (option === '查看') {console.log(index, row, option)} else if (option === '编辑') {console.log(index, row, option)} else if (option === '设为可提现') {console.log(index, row, option)} else if (option === '取消可提现') {console.log(index, row, option)}},// 选择的数据回调handleSelectionChange(data) {console.log(data)},// 分页操作handleRefreshList() {this.getList()}}}</script>

3.请求到的服务端数据

{result: true,message: null,data: [{headImgUrl:'/mmopen/vi_32/RYIWG1XDAOVbAXHWONRiab639VRyr7cKQcCibXz8s2m4xhuDmDYo8XxGde0NiaAJ5vy8SHznDIoQ7mBtLibg9sicia0w/132',nickname: '万马奔腾',mobile: '13892188637',registrationDate: 1556666683000,userId: '0172cf8bbda841dca100aa8b30b1d58e',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/DYAIOgq83eptKEXTYEu3Ne3pF7OcUvibUBY0hSibibH7SRTNxN9x7522mYQZ63ZEBF8nbjty1NN60ScPicsuGGrrtQ/132',nickname: '  水目菊  ',mobile: '15991695887',registrationDate: 1560258459000,userId: '021c02454ea64fab8640f1fa25e18637',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/Q0j4TwGTfTKLvV2y1XiaJJDfibB7zlqaTudCEsiapR8iaShFykZ2SgVD24zxYve5kPLvQooFy4ibePbpcribtZJVXlEQ/132',nickname: '老要',mobile: '',registrationDate: 1563934025000,userId: '024bc4c4f5db418499d3633621b2b834',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmhead/2yfPLY1YiaibeyxYwultf0Z7VNea1H1icXrV9pQcldEHTc/132',nickname: '林群梦',mobile: '',registrationDate: 1557438206000,userId: '035826db900d4b7a912664119189b6f1',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/DYAIOgq83eqF8zPxScdIGo0nK7so6bzFibRF1sEXrT404XUN2gcfFRTB1pcCaZPBUr9lGKGibbiaUWVTOw7HpaNNg/132',nickname: '贺励',mobile: '',registrationDate: 1563490853000,userId: '035b59b061454336953d47822c7b0406',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/Q0j4TwGTfTLsymhiblxYck4YOUxdtpZOib12KgJj6ciaJxV2ibtia92YODBhC05YL8rCNKQQjc09tZTP6xBxkT0qK5Q/132',nickname: '乾坤',mobile: '15091593977',registrationDate: 1557153760000,userId: '03a91cb5a60f4f02bf22b1e9e179258d',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/Q0j4TwGTfTJpTy32D4vRETGtricKwfhx3kiaTJcibRyMFg5KvSENibeWKE0Xq4gZ9ZyicZLvkUQ4RSVBpwwiaOhW5lLg/132',nickname: '鸿涛',mobile: '13909256676',registrationDate: 1556680061000,userId: '03d7811ea5cb4e1e851c5245128674c2',inviterUser: '三百千.刘震',inviterId: 'b33b3879531d41e4bc19b629cb7c7cb8',friendsNum: 0,friendsNumSum: 0,integrals: 408.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/Q0j4TwGTfTKLuf2cK1w7sN3qD0cM4XvbYWnJJa5hibyUKGv0oPzG0LT1UjFvTTRuibOCTvxDibQdU9icFxK1TZOSHQ/132',nickname: '格格',mobile: '',registrationDate: 1560569395000,userId: '04346cf9a9284d058f71a59de4b37e49',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/Q0j4TwGTfTJ9PZJVYXlalZyggdlVpCoPJcvIHrh1eN3SRRoTkdBgGjhQwrBQMibYma0xkdf6BlaKHLdv5YzM1AA/132',nickname: '水木清华',mobile: '13359265165',registrationDate: 1557146507000,userId: '05f3c11d67044e30a61abd79fc542c36',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''},{headImgUrl:'/mmopen/vi_32/PiajxSqBRaEJiaXZyZ6Tnv4z7YgvVXRvuONlTc9DNQVS0d52HnScISc77XGKawodayVib3fnLwV9trSDlUkRKwHRw/132',nickname: '王鸣@ODIN',mobile: '',registrationDate: 1560861936000,userId: '07087c0478ae43b18765272fbb4aa5e1',inviterUser: null,inviterId: null,friendsNum: 0,friendsNumSum: 0,integrals: 0.0,isExpressive: ''}],cntPage: 33,cntData: 323}

3.补充表格组件用的过滤器(自行注册,步骤略)

export function parseTime(time, cFormat) {if (arguments.length === 0) {return null}if ((time + '').length === 10) {time = +time * 1000}const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'let dateif (typeof time === 'object') {date = time} else {date = new Date(parseInt(time))}const formatObj = {y: date.getFullYear(),m: date.getMonth() + 1,d: date.getDate(),h: date.getHours(),i: date.getMinutes(),s: date.getSeconds(),a: date.getDay()}const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {let value = formatObj[key]if (key === 'a') {return ['一', '二', '三', '四', '五', '六', '日'][value - 1]}if (result.length > 0 && value < 10) {value = '0' + value}return value || 0})return time_str}

4.效果展示

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。