在 Vue 中使用装饰器 Decorator

·  阅读 475
在 Vue 中使用装饰器 Decorator

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Decorator 的语法还没有通过提案,所以项目中很少用。不过最近刚好有一个需求用到了。

什么是装饰器

装饰器是一种函数,写成@ + 函数名。它可以放在类和类方法的定义前面。

我理解装饰器就是一个函数生成器,是一种高阶函数。

装饰器可以用来修饰类、方法,装饰器可以嵌套使用,也可以传入参数。具体语法可以参考 ECMAScript 6 入门-装饰器

具体需求

在写业务需求时,有很多操作都需要二次确认,比如删除一个文件之前,需要加入一个确认窗口。

因为用到的是 Vue2.x + Element UI,所以具体的函数代码大概是这个样子:

deleteFile(data) {
    this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        type: 'warning'
    }).then(() => {
        // 删除文件操作
    }).catch(() => {});
}
复制代码

二次确认在很多危险操作都需要,所以每个函数都加一遍确认部分的代码,感觉有点冗余,于是想到了使用注释器将 confirm 部分提出去。代码如下:

import { MessageBox } from 'element-ui';

function confirmation(target, name, descriptor) {
    let oldValue = descriptor.value;
    descriptor.value = function(...args) {
        MessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示')
            .then(oldValue.bind(this, ...args))
            .catch(() => {});
    };

    return descriptor;
}
复制代码

这样只需要在需要二次确认的函数上加一个  @confirmation 即可:

@confirmation
deleteFile(data) {
    // 删除文件操作
}
复制代码

不过不同的操作需要的提示往往不一样,那就在注释器上加一个参数。

import { MessageBox } from 'element-ui';

export function confirmation(message) {
    return function(target, name, descriptor) {
        let oldValue = descriptor.value;
        descriptor.value = function(...args) {
            MessageBox.confirm(message, '提示')
                .then(oldValue.bind(this, ...args))
                .catch(() => {});
        };

        return descriptor;
    }
}
复制代码

使用代码

@confirmation('此操作将永久删除该文件, 是否继续?')
deleteFile(data) {
    // 删除文件操作
}
复制代码

相关配置

我的项目是通过 Vue Cli 创建,需要添加 ESlint 配置。

"parserOptions": {
    // ...
    "ecmaFeatures": {
        "legacyDecorators": true
    }
}
复制代码
分类:
前端
分类:
前端