Vue框架TypeScript装饰器使用指南小结


Posted in Javascript onFebruary 18, 2019

前言

装饰器是一种特殊类型的声明,它能够被附加到 类声明,方法, 访问符,属性或参数 上。 装饰器使用 @expression这种形式, expression求值 后必须为一个函数,它会在 运行时被调用 ,被装饰的声明信息做为参数传入。

本篇先从项目的宏观角度来总结一下Decorator如何组织。

目录

  • 主要的Decorator依赖
    • vue-class-component
    • vuex-class
    • vue-property-decorator
    • core-decorators
  • 自定义Decorator示例
  • 哪些功能适合用Decorator实现
  • Decorator实现小Tips
  • See also

主要的Decorator依赖

vue-cli3 默认支持Decorator, 年初重写了一个design库主要依赖官方和社区提供的Decorator来实现的组件。 Decorator可以非侵入的装饰类、方法、属性,解耦业务逻辑和辅助功能逻辑。以下是主要的三方Decorator组件:

vue-class-component

  • @Component 如果您在声明组件时更喜欢基于类的 API,则可以使用官方维护的 vue-class-component 装饰器
  • 实时计算computed属性, get computedMsg () {return 'computed ' + this.msg}
  • 生命周期钩子 mounted () {this.greet()}

vuex-class

让Vuex和Vue之间的绑定更清晰和可拓展

  • @State
  • @Getter
  • @Action
  • @Mutation

vue-property-decorator

这个组件完全依赖于vue-class-component.它具备以下几个属性:

  • @Component (完全继承于vue-class-component)
  • @Prop:父子组件之间值的传递
  • @Emit:子组件向父组件传递
  • @Model:双向绑定
  • @Watch:观察的表达式变动
  • @Provice:在组件嵌套层级过深时。父组件不便于向子组件传递数据。就把数据通过Provide传递下去。
  • @Inject:然后子组件通过Inject来获取
  • Mixins (在vue-class-component中定义);

core-decorators

  • @readonly
  • @autobind : TSX 回调函数中的 this,类的方法默认是不会绑定 this 的,可以使用autobind装饰器
  • @override

总结一下主要就分成这三类:

  • 修饰类的:@Component、@autobind;
  • 修饰方法的:@Emit、@Watch、@readonly、@override;
  • 修饰属性的:@Prop、@readonly;

以上引用方法等详系内容可查看官方文档。下面自定义部分来实现一个记录日志功能的装饰器。

自定义Decorator示例

@Logger,Logger日志装饰器通常是修饰方法,Decorater则是在 运行时就被触发了 ,日志记录是在 方法被调用时触发 ,示例中通过自动发布事件实现调用时触发。为增加日志记录的灵活性,需要通过暴露钩子函数的方式来改变日志记录的内容。
期望的日志格式

{
  "logId":"", // 事件Id
  "input":"", // 方法输入的内容
  "output":"", // 方法输出的内容
  "custom":"" // 自定义的日志内容
}

实现

export function Logger(logId?: string, hander?: Function) {
  const loggerInfo =Object.seal({logId:logId, input:'',output:'', custom: ''});
  const channelName = '__logger';
  const msgChannel = postal.channel(channelName);
  msgChannel.subscribe(logId, logData => {
    // 根据业务逻辑来处理日志
    console.log(logData);
  });

  return function (target: any,
    key: string,
    descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> {
      const oldValue = descriptor.value
      descriptor.value = function () {
        const args: Array<any> = [];
        for (let index in arguments) {
        args.push(arguments[index]);
        }
        loggerInfo.input = `${key}(${args.join(',')})`;
        // 执行原方法
        const value = oldValue.apply(this, arguments);
        loggerInfo.output = value;
        hander && (loggerInfo.custom = hander(loggerInfo.input, loggerInfo.output) || '');
        // 被调用时,会自动发出一个事件
        msgChannel.publish(logId, loggerInfo);
      }
      return descriptor
  }
}

使用

@Logger('event_get_detial1')
getDetial(id?: string, category?: string) {
  return "详细内容";
}
// 或者
@Logger('event_get_detial2', (input, output) => {
    return '我是自定义内容';
})
getDetial2(id?: string, category?: string) {
  return "详细内容";
}
...
<button @click="getDetial2('1000', 'a')">获取详情</button>

效果: {logId: "event_get_detial2", input: "getDetial(1000,a)", output: "详细内容", custom: "我是自定义内容"} , 每次点击按钮都会触发一次。

TODO: 这里还需要对输入参数和输出参数中的引用数据类型做处理。

同时还需要掌握: 装饰器工厂、装饰器组合、装饰器求值、参数装饰器、元数据

哪些功能适合用Decorator实现

官网和社区提供的这些Decorator, 可以作为自己框架的底层设计。

日志功能全局都得用,调用方法基本一致,是最适合使用装饰器来实现,并且每个项目的日志记录各有差异,最适合自定义这部分。

Decorator实现小Tips

  • 考虑下各类Decorator叠加和共存的问题,可以参考官网关于装饰器组合描述
  • Decorator 的目标是在原有功能基础上,添加功能,切忌覆盖原有功能
  • 类装饰器不能用在声明文件中( .d.ts),也不能用在任何外部上下文中(比如declare的类)
  • 装饰器只能用于类和类的方法,不能用于函数,因为存在函数提升。类是不会提升的,所以就没有这方面的问题。
  • 注意迁移速度、避免一口吃成胖子的做法
  • 不要另起炉灶对主流库创建Decorator库,主流库维护成本很高还是得有官方来维护,为保证质量不使用个人编写的Decorator库。自己在创建Decorator库时也要有这个意识,仅做一些有必要自定义的。
  • Decorator 不是管道模式,decorator之间不存在交互,所以必须注意保持decorator独立性、透明性
  • Decorator 更适用于非业务功能需求
  • 确定 decorator 的用途后,切记执行判断参数类型
  • decorator 针对每个装饰目标,仅执行一次

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
Apr 12 Javascript
来自chinaz的ajax获取评论代码
May 03 Javascript
javascript 面向对象编程基础:继承
Aug 21 Javascript
微信小程序 textarea 详解及简单使用方法
Dec 05 Javascript
JavaScript实现翻页功能(附效果图)
Feb 16 Javascript
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
Jun 02 jQuery
Vue.js 利用v-for中的index值实现隔行变色
Aug 01 Javascript
解决vue打包css文件中背景图片的路径问题
Sep 03 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
Oct 24 Javascript
Vue项目中使用better-scroll实现一个轮播图自动播放功能
Dec 03 Javascript
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
微信小程序实现录音Record功能
May 09 Javascript
深入理解vue-class-component源码阅读
Feb 18 #Javascript
详解TypeScript+Vue 插件 vue-class-component的使用总结
Feb 18 #Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
Feb 18 #jQuery
详解ES7 Decorator 入门解析
Feb 18 #Javascript
jQuery插件实现非常实用的tab栏切换功能【案例】
Feb 18 #jQuery
详解关于微信setData回调函数中的坑
Feb 18 #Javascript
jQuery实现的五星点评功能【案例】
Feb 18 #jQuery
You might like
一周让你学会PHP 不错的学习资料
2009/02/06 PHP
解析PHP中数组元素升序、降序以及重新排序的函数
2013/06/20 PHP
php进行ip地址掩码运算处理的方法
2016/07/11 PHP
用CSS+JS实现的进度条效果效果
2007/06/05 Javascript
跟我一起学写jQuery插件开发方法(附完整实例及下载)
2010/04/01 Javascript
javascript学习(二)javascript常见问题总结
2013/01/02 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
原生js和jquery中有关透明度设置的相关问题
2014/01/08 Javascript
JavaScript数组前面插入元素的方法
2015/04/06 Javascript
使用RequireJS优化JavaScript引用代码的方法
2015/07/01 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
prototype框架中美元符号$用法分析
2016/01/22 Javascript
Node.js程序中的本地文件操作用法小结
2016/03/06 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
微信小程序 开发经验整理
2017/02/15 Javascript
vue中使用localstorage来存储页面信息
2017/11/04 Javascript
详解Vue微信授权登录前后端分离较为优雅的解决方案
2018/06/29 Javascript
Vue创建头部组件示例代码详解
2018/10/23 Javascript
JQuery获取可视区尺寸和文档尺寸及制作悬浮菜单示例
2019/05/14 jQuery
在JavaScript中如何访问暂未存在的嵌套对象
2019/06/18 Javascript
微信小程序点击view动态添加样式过程解析
2020/01/21 Javascript
python 自动提交和抓取网页
2009/07/13 Python
Python Queue模块详解
2014/11/30 Python
Python中使用pprint函数进行格式化输出的教程
2015/04/07 Python
Python for Informatics 第11章之正则表达式(四)
2016/04/21 Python
Python hashlib常见摘要算法详解
2020/01/13 Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
2020/09/29 Python
英国最大的奢侈珠宝和手表网站:C W Sellors
2017/02/10 全球购物
个人自我鉴定怎么写
2013/10/28 职场文书
后勤工作职责
2013/12/22 职场文书
机械专业求职信范文
2014/07/15 职场文书
离婚答辩状怎么写
2015/05/22 职场文书
校运会广播稿
2015/08/19 职场文书
python内置进制转换函数的操作
2021/06/02 Python
javascript代码简写的几种常用方式汇总
2021/08/23 Javascript
德劲DE1102数字调谐收音机机评
2022/04/07 无线电