1. 前言
当我们的项目越来越大,我们会发现组件之间可能存在很多相似的功能,你在一遍又一遍的复制粘贴相同的代码段(data,method,watch、mounted等),如果我们在每个组件中去重复定义这些属性和方法会使得项目出现代码冗余并提高了维护难度,其中尤其是后台管理系统中table表格页面,都会有增删改查以及分页。如果我们每个页面都是独自引入,引入后就会发现每个页面的代码重复很大。因此针对这种情况官方提供了Mixins特性。
2. Mixins
Mixins即为混合引入,通俗的来说可以将多个页面中公共的data、methods、computed,等抽离出来,在需要的时候进行引入,有点和组件一样,但是也和组件不同。我们通过Mixins引入后会与自身的进行合并。下面就来进行展示
3. 效果展示
这个就是大家在开发过程中比较通用的一个后台管理系统的页面了吧。其中包含了较为基础的功能,例如添加,搜索,删除,编辑以及分页。那么我们接下来就针对其中的一个点来进行相关的操作。
3.1 抽离思路
由于我们前后端项目肯定会进行发送请求,那么由于Mixins时类似于公共的,因此我们首先就需要考虑的是我们的请求怎么封装。答案是肯定的,我们不能将对应的请求放在Mixins文件中,因为一旦放入了不同文件对应的请求会不同,因此我们的Mixins文件就会越来越大。会增加我们引入后的负担。因此我这里就将对应的请求放到了引入文件中。这样我们就实现了最重要的一步,请求和对应的Mixins进行了分开。
3.2 逻辑分离
这里我采取的封装思想是页面处理操作逻辑,Mixins处理请求逻辑的思想来进行分离。即我们页面进行用户的点击,点击完成后后将要与后段发送的请求交给Mixins来进行处理。处理完成后将数据返回给页面展示的思想。这里就拿删除来举例。
下面是用户点击删除按钮后触发的相关操作。其中的 deleteTableItem 为Mixins中封装的相关函数,当用户点击的时候将对应的url和删除的ID传入到Mixins中进行操作。然后就将对应的逻辑交给来我们定义的混入函数中。其实这里也可以不传入删除的接口地址。因为混合函数的执行肯定是混合到页面后才会在调用的时候执行,因此对应的页面的data也进行了创建。因此可以通过this.actionUrl来进行获取。
// 删除表单项
deleteItem(tableItem) {
this.deleteTableItem(tableItem, this.actionUrl.DELETE);
},
//删除表单中项
deleteTableItem(tableItem, deleteUrl) {
console.log(tableItem, deleteUrl)
console.log('我是删除表单项')
// 获取搜索列表
this.getTableList(this.searchForm,this.actionUrl.SEARCH)
},
4 全部代码
4.1 页面代码
/** * 系统管理 公司管理 */
<template>
<div>
<!-- 面包屑导航 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>公司管理</el-breadcrumb-item>
</el-breadcrumb>
<!-- 搜索筛选 -->
<el-form :inline="true" :model="formInline" class="user-search">
<el-form-item label="搜索:">
<el-input
size="small"
v-model="formInline.deptName"
placeholder="输入部门名称"
></el-input>
</el-form-item>
<el-form-item label="">
<el-input
size="small"
v-model="formInline.deptNo"
placeholder="输入部门代码"
></el-input>
</el-form-item>
<el-form-item>
<el-button
size="small"
type="primary"
icon="el-icon-search"
@click="search"
>搜索</el-button
>
<el-button
size="small"
type="primary"
icon="el-icon-plus"
@click="showAddDialog()"
>添加</el-button
>
</el-form-item>
</el-form>
<!--列表-->
<el-table
size="small"
:data="list"
highlight-current-row
v-loading="loading"
border
element-loading-text="拼命加载中"
style="width: 100%"
>
<el-table-column align="center" type="selection" width="60">
</el-table-column>
<el-table-column sortable prop="deptName" label="部门名称" width="300">
</el-table-column>
<el-table-column sortable prop="deptNo" label="部门代码" width="300">
</el-table-column>
<el-table-column sortable prop="editTime" label="修改时间" width="300">
<template slot-scope="scope">
<div>{
{ scope.row.editTime | timestampToTime }}</div>
</template>
</el-table-column>
<el-table-column sortable prop="editUser" label="修改人" width="300">
</el-table-column>
<el-table-column align="center" label="操作" min-width="300">
<template slot-scope="scope">
<el-button size="mini" @click="showEditDialog(scope.row)"
>编辑</el-button
>
<el-button size="mini" type="danger" @click="deleteItem(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
@size-change="pageSizeChange"
@current-change="pageCurrentChange"
:current-page="searchForm.currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="searchForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="400">
</el-pagination>
<!-- 编辑界面 -->
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="30%"
@click="closeDialog"
>
<el-form
label-width="120px"
:model="editForm"
:rules="rules"
ref="editForm"
>
<el-form-item label="部门名称" prop="deptName">
<el-input
size="small"
v-model="editForm.deptName"
auto-complete="off"
placeholder="请输入部门名称"
></el-input>
</el-form-item>
<el-form-item label="部门代码" prop="deptNo">
<el-input
size="small"
v-model="editForm.deptNo"
auto-complete="off"
placeholder="请输入部门代码"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="closeDialog">取消</el-button>
<el-button
size="small"
type="primary"
:loading="loading"
class="title"
@click="submitForm()"
>保存</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
import action from "./action";
export default {
data() {
return {
actionUrl: {
ADD: "我是添加的接口",
SEARCH: "我是搜索的接口",
DELETE: "我是删除的接口",
EDIT: "我是编辑的接口"
},
nshow: true, //switch开启
fshow: false, //switch关闭
loading: false, //是显示加载
dialogVisible: false, //控制编辑页面显示与隐藏
title: "添加",
editForm: {
// 其中的type为1时为编辑,为0表示新增
formType:0,
deptId: "",
deptName: "",
deptNo: "",
token: localStorage.getItem("logintoken")
},
// rules表单验证
rules: {
deptName: [
{ required: true, message: "请输入部门名称", trigger: "blur" }
],
deptNo: [{ required: true, message: "请输入部门代码", trigger: "blur" }]
},
formInline: {
page: 1,
limit: 10,
varLable: "",
varName: "",
token: localStorage.getItem("logintoken")
},
// 搜索的相关数据
searchForm: {
name:'123123',
pageSize: 10,
currentPage: 1
}
};
},
//从minix中引入的
mixins: [action],
mounted() {
this.init();
// this.getdata(this.formInline)
},
/**
* 里面的方法只有被调用才会执行
*/
methods: {
// 初始化项目
init() {
this.getTableList(this.searchForm,this.actionUrl.SEARCH);
},
// 打开新增的弹窗
showAddDialog(){
this.title = "新增";
this.editForm.formType = 0
this.dialogVisible = true;
},
// 打开编辑的弹窗
showEditDialog(tableItem) {
this.editForm.formType = 1
this.title = "编辑";
this.editForm = tableItem
this.dialogVisible = true;
},
// 关闭编辑的弹窗
closeDialog() {
this.dialogVisible = false;
},
// 删除表单项
deleteItem(tableItem) {
this.deleteTableItem(tableItem, this.actionUrl.DELETE);
},
// 搜索对应的条件
search(){
this.getTableList(this.searchForm,this.actionUrl.SEARCH);
},
// 提交表单
submitForm(){
if(this.editForm.formType === 1){
console.log('我是新增的表单',this.editForm)
this.addTableItem(this.editForm,this.actionUrl.ADD)
}else{
console.log('我是编辑的表单',this.editForm)
this.editTableItem(this.editForm,this.actionUrl.EDIT)
}
}
}
};
</script>
<style scoped>
.user-search {
margin-top: 20px;
}
.userRole {
width: 100%;
}
</style>
4.2引入代码
// 该函数为所有页面的操作函数,用来处理对应的操作情况
// 这里的res并没有实际作用,只是用来模仿返回的数据类型
let res = {
code: 0,
msg: null,
count: 5,
pageSize: 8,
current: 1,
data: [
{
id:'131231',
addUser: '123123123123',
editUser: null,
addTime: 1521062371000,
editTime: 1526700200000,
deptId: 2,
deptName: '上海分公司',
deptNo: '1',
parentId: 1
},
{
id:'131231',
addUser: null,
editUser: null,
addTime: 1521063247000,
editTime: 1526652291000,
deptId: 3,
deptName: '上海测试',
deptNo: '02',
parentId: 1
},
{
id:'131231',
addUser: null,
editUser: null,
addTime: 1526349555000,
editTime: 1526349565000,
deptId: 12,
deptName: '1',
deptNo: '11',
parentId: 1
},
{
id:'131231',
addUser: null,
editUser: null,
addTime: 1526373178000,
editTime: 1526373178000,
deptId: 13,
deptName: '5',
deptNo: '5',
parentId: 1
},
{
id:'131231',
addUser: null,
editUser: null,
addTime: 1526453107000,
editTime: 1526453107000,
deptId: 17,
deptName: 'v',
deptNo: 'v',
parentId: 1
}
]
}
//其中调用这个minix所对应的各个变了如果修改了记得统一修改
// 用来保存搜索的URL,用于后续的操作
export default {
data() {
return {
// 返回的数据的列表
list: [],
}
},
methods: {
// 获取tables数据
getTableList(search,searchUrl) {
console.log(search,searchUrl)
console.log(res)
// 这里模拟返回的相关数据
if (res.code === 0) {
this.list = res.data
this.pageSize.current = res.current
this.pageSize.pageSize = res.pageSize
}
},
//删除表单中项
deleteTableItem(tableItem, deleteUrl) {
console.log(tableItem, deleteUrl)
console.log('我是删除表单项')
// 获取搜索列表
this.getTableList(this.searchForm,this.actionUrl.SEARCH)
},
//添加表单项
addTableItem(tableItem,addUrl) {
console.log(tableItem, addUrl)
console.log('我是添加表单项')
this.getTableList(SEARCHDATA,SEARCHURL)
},
// 保存编辑
editTableItem(tableItem,editUrl) {
console.log(tableItem,editUrl)
console.log('我是保存表单项')
this.getTableList(SEARCHDATA,SEARCHURL)
},
// 修改分页的每页的条数时处罚
pageSizeChange(v){
this.searchForm.pageSize = v
this.getTableList(this.searchForm,this.actionUrl.SEARCH)
},
// 修改分页的当前页数
pageCurrentChange(v){
this.searchForm.pageSize = v
console.log(v)
this.getTableList(this.searchForm,this.actionUrl.SEARCH)
}
},
}
5. 总结
虽然Mixins可以抽离出页面中公共方法,但是不太建议过度抽离,因为太过度抽离后就会影响对应的代码的可读性。会操作浏览页面到处去寻找Mixins中的方法。反而得不偿失