前端组件化设计——布局、逻辑、视图
一、拆分页面:将一个页面拆分成几个部分,如:父子包裹、左右或上下布局
<!-- 上下布局 --> <template> <el-card style="background: #fff;min-height: 800px" shadow="never"> <div slot="header" style="height: 28px"> <!-- 标题 --> <span>xxxx列表<span/> </div> <!--内容--> <div> <featureTable :parameters="parameters"/> </div> </el-card> </template>
二、表格操作部分,属于中间件——处理复杂逻辑、数据转换
1.纯展示的表格
<template> <el-card id="activityManage"> <div slot="header"> <el-button type="primary" @click="addRowDialog" >新建</el-button> </div> <el-row > <el-col> <CommonTable :table-data="tableData" :table-column="tableColumn" height="680" :loading="listLoading" > <el-table-column type="index" label="序号" align="center" width="60" slot="header"> <template slot-scope="scope"> {{ (currentPage-1)*pageSize+scope.$index+1 }} </template> </el-table-column> <el-table-column label="操作" align="center" width="150" slot="footer"> <template slot-scope="scope"> <el-button-group> <el-button type="primary" @click="editRowDialog(scope.$index, scope.row)">编辑</el-button> <el-button type="danger" @click="deleteRowDialog(scope.$index, scope.row)">删除</el-button> </el-button-group> </template> </el-table-column> </CommonTable> <!-- 分页 --> <Pagination style="margin-top:20px" :table-begin="tableBeigin" @changTable="getTablePage"/> <!-- 2.对话框 --> <el-dialog top='60px' :title="dialogTitle" :visible.sync="dialogVisible" :width="dialogWidth" :close-on-click-modal="false" :show-close="!showCancelButton" > <component :is='componentType' :show-btn='showCancelButton' :form-info='formInfo' @form-change='hanldeFormChange' /> </el-dialog> </el-row> </el-card> </template>
2.复杂的内容需要自定义
<template> <div> <!-- 新建+搜索 --> <el-row> <el-col :span="4"> <el-button type="primary" @click="featureNew" >新建xxx</el-button> </el-col> <el-col :span="4" :offset="parameters.privatePage==='个人'?16:20"> <el-input v-model="searchInfo" placeholder="关键字搜索" clearable @clear="searchInfoMatch" @keyup.enter.native="searchInfoMatch(searchInfo)"> <el-button slot="append" icon="el-icon-search" @click="searchInfoMatch(searchInfo)"/> </el-input> </el-col> </el-row> <!-- 自定义表格合并 --> <el-table style='margin-top:20px' v-loading="parameters.loading" :data="tableData" border :span-method="colspanMethod" > <el-table-column show-overflow-tooltip width="120" align="center" prop="type" label="xx分类" /> <!--操作--> <el-table-column align="center" label="操作" width="200"> <template slot-scope="scope"> <el-button-group> <el-button @click="tableRowChange(scope, 'edit')" type="primary" :disabled="scope.row.app_id===''">查看编辑</el-button> </el-button-group> <el-dropdown trigger="click"> <el-button type="primary"> 更多<i class="el-icon-arrow-down el-icon--right"/> </el-button> <el-dropdown-menu slot="dropdown"> <el-dropdown-item style="padding:0" v-for="(item,index) in tableRowMore" :key='index'> <el-button style="padding: 7px 15px;width:100%" @click="tableRowChange(scope, item.action)" type="text" :disabled="scope.row.app_id===''">{{ item.name }}</el-button> </el-dropdown-item> </el-dropdown-menu> </el-dropdown> </template> </el-table-column> </el-table> <!-- 分页组件 --> <el-pagination style="margin-top: 15px" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="pageSizes" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="pageTotal"/> <!-- 2.对话框 --> <el-dialog top='60px' :title="dialogTitle" :visible.sync="dialogVisible" :width="dialogWidth" :close-on-click-modal="false" :show-close="!showCancelButton" > xxx表单内容xxx <span slot="footer"> <el-button @click="handleClose('ruleForm')">取消</el-button> <el-button type="primary" @click="submitNewActivity('ruleForm')">确定</el-button> </span> </el-dialog> </template>
三、展示组件:
比如通用表格组件、搜索框组件、分页组件、表单校验组件(如果大于1个使用component组件动态切换)、按钮弹框(放大编辑)、通用的编辑器组件、可视化图形组件等,当然通用的函数、数据配置等也可以抽离出来,或者使用第三方库实现:
import CommonTable from 'module-comp/table/CommonTable'
import _ from 'lodash' // 第三方库 import {getSpanArr} from '@/utils/xxxManage'// 公共的方法或数据配置 import canvasInstanceStatus from 'mixins/xxxStatus'// 插入实现方法,比较隐晦不好维护mixins:[xxx] import Pagination from './Pagination'// 通用的分页组件或自定义需要的内容
化繁为简:
比如上面的表格操作比较繁琐,使用数组遍历输出菜单,设置通用的方法调用(设置一个type区分);
又如:表格输出列自适应时,标题也可以设置成一个数组格式,通过遍历的形式进行输出,示例在下面;
<el-table :max-height="height" ref="commonTable" :data="tableData" :size="size" :stripe="stripe" border highlight-current-row v-loading="loading" :row-class-name="tableRowClassName" @filter-change="filterChange" @selection-change="handleSelectionChange" :row-key="rowKey" > <!--自定义插入--> <slot name="header"/> <el-table-column v-for="(item, index) in tableColumn" :key="`key_${index}`" :prop="item.prop" :label="item.label" show-overflow-tooltip :sortable='sortable' align="center" > <template slot-scope="scope"> <div v-if="tableColumn[index].prop === 'field_key'"> <span>{{ keyOptionsObj[scope.row.field_key] }}</span> </div> <div v-else> <span>{{ scope.row[tableColumn[index].prop] }}</span> </div> </template> </el-table-column> <!--自定义插入--> <slot name="footer"/> </el-table>
需要注意的问题:组件的通讯问题,通常组件需要进行联动效果,这需要注意传值的技巧(只传一个对象)、以及回调方法尽量设置到中间件(连续回调2次以上就不利于维护了)......