完整的混入为我们提供了逻辑思路,也带给组件构建过程中的引导。与此同时,可能那些我们并不需要的逻辑和数据片段也随这个过程带了过来。而选项式API的出现好像解决了这些冗余,它更像是对混入的思想迭代。
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue组件中的可复用功能。
一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
官网示例:
// 定义一个混入对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
如何梳理一套通用且抽象的业务逻辑,是一段业务mixin(混入)能否复用的关键。
业务中的逻辑流就好比一套标准作业流程(SOP)。
以常见的B端业务为例,工单系统中列表作为出现率最高的页面,如果存在一套列表页的混入逻辑那将是提效的一条重要途径。
在列表中可能会涵盖增删改查操作,查询往往是一个列表页的基础也是核心部分。
以查询为例,上图示以getList为查询单元,其核心逻辑用code代替。
预设查询前置和后置方法:beforeGetList、afterGetList。
获取list代码示例:
// vue 生命周期
created() {
this.getList()
},
// 获取list数据
// 由混入定义loading、tableData、queryData、url.list等数据
async getList() {
if (this.beforeGetList()) return
this.loading = true
this.tableData = await this.url.list(this.queryData)
this.loading = false
this.afterGetList()
},
// 查询前置钩子
beforeGetList() {
// 默认返回
return false
},
// 查询后置钩子
afterGetList() {
// 默认无操作
},
页面引入示例:
import MixinTable from '@/mixins/mixin-table'
export default {
mixins: [MixinTable],
name: 'list'
data(){
url: {
//此处赋值一个function类型、获取list函数的接口
list:getAppList
}
}
}
其他单元操作:
// 删除单条数据
detele(json) {
//删除前置
if (this.beforeDelete()) return
this.$confirm('您确认执行删除操作?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async() => {
await this.url.delete(json)
this.$message.success('删除成功!')
this.queryData.pageNo = 1
//更新页面数据
this.getList()
//删除后置
this.afterDelete()
})
},
// 删除前
beforeDelete() {
// 默认返回
return false
},
// 删除后
afterDelete() {
},
// 导出
async exportFile() {
if (this.beforeExport()) return
this.exportLoading = true
const res = await this.url.export(this.queryData)
const {
blob,
filename
} = res;
exportFile(blob, filename)
this.exportLoading = false
this.$message.success('导出成功!')
this.afterExport()
},
// 导出前
beforeExport() {
// 默认返回
return false
},
// 导出后
afterExport() {
},
以上单元操作在组件引入混入后,传入删除接口、导出接口即可在template标签内直接引用预设的delete()、exportFile()方法。
抛出的前置和后置方法相当于单元操作的生命周期钩子,可忽略,也可在组件内重写,以此提供混入内对单元操作的校验和关联操作。
- 属性和方法:组件>混入。 组件的属性会覆盖混入的属性,比如上述案例中,url.list默认指代一个空字符串,组件中赋值一个获取列表的list,则会优先组件覆盖混入。
- 生命周期函数:混入>组件。如created等生命周期函数,在组件中我们也不可避免的对组件的钩子函数预设方法,而两者冲突的时候,并不会产生覆盖,而是顺序执行,优先执行混入的方法。
- 多组件共用一段混入:不存在优先级的概念。逻辑独立且解耦。
随着vue3的到来,mixin也慢慢淡出了历史舞台,但是其内在复用逻辑的思路和现在的组合式API又有什么不同呢。
mixin作为vue2中主要的复用逻辑手段,采取了与通用逻辑流取并集的思考模式。
当我们梳理出一套业务向或开发向的SOP的时候,我们只需要稍作改动就可以重构出一个新的页面,其中包含我们对通用逻辑的重写。
组合式API更为灵活,可以梳理整套流程后做拆解,也可以将单元拼装成各式自定义的逻辑,可以说是完美替代了取并集的模式。
新的组合式API可以像积木一样组装成一套新的SOP,而不会在引入过程中增加冗余的损耗,可用性和复用性也一定程度上随着灵活度大大增强。编写过程中将选项式分离的data、method等都可聚合在同一区域进行拆解,也提供了提炼共性的前提。