核心AOP函数
const AOP = (oldFn, before, after) => {
return async function () {
let args = [].slice.call(arguments);
if (Object.prototype.toString.call(before) === "[object Function]") {
try {
// await保证异步操作的平滑
await before.apply(this, args);
} catch (e) {
// 阻止往下执行
return false;
}
}
await oldFn.apply(this, args);
try {
after.apply(this, args)
} catch (e) {
}
}
}
很明显,AOP就是把一个函数切成多个函数,它们之间没有耦合,但是却能顺序执行 。
在VUE中的使用思路:将methods
的方法作为切片函数转换为组合函数,这样配合mixin
,大大节省弹药
// 工具方法: 转化mehods所有方法
export default function AOPSwitch(obj) {
let keys = Object.keys(obj).sort(), // 排序保证before和after函数在后面
result = {}
while (keys.length > 0) {
let curKey = keys.shift(),
beforeKey = "",
afterKey = ""
let beforeIndex = keys.indexOf(curKey + "Before");
if (beforeIndex > -1) {
beforeKey = keys.splice(beforeIndex, 1)[0]
}
let afterIndex = keys.indexOf(curKey + "After");
if (afterIndex > -1) {
afterKey = keys.splice(afterIndex, 1)[0]
}
result[curKey] = AOP(obj[curKey], obj[beforeKey], obj[afterKey])
}
return result
}
实践应用:
写一个公用方法
export default commonMehods = {
// 删除之前的确认删除弹窗
delBefore() {
// 使用Promise来阻断后面的执行
return new Promise((resolve, reject) => {
this.$confirm({
title: "确认要删除吗?",
content: "",
cancelText: "取消",
okText: "确认",
onOk() {
resolve()
},
onCancel() {
reject()
},
});
})
},
}
具体页面中使用
import cloneDeep from "lodash/cloneDeep";
// 此处使用的是mixin的思想
const mehods = {
// 此处需要深拷贝,不然多个页面会共享mehods
...cloneDeep(commonMehods),
async del() {
// 执行删除操作
}
}
export default {
methods: {
...AOPSwitch(methods),
},
};
总结
通过AOP+MIXIN思想,页面的代码会大大精简,而且方法之间的耦合也更低,现在某个函数之前/之后执行操作,直接声明一个xxxBefore/xxxAfter
函数即可,还有更复杂要求,可在本页面重写方法覆盖mixin
中的方法即可。
同步函数需要阻断,可以使用
throw new Error()
切片三个函数不满足? 直接弄个函数列表进去,遍历
apply