Vue进阶 | 在Vue中使用装饰器

2,927 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

在进行 Vue 项目开发时,看到了这样的写法,感觉打开了新大陆,上图中的 @Watch 是一个 Watch 属性的装饰器,它有自己的声明规则,写法与 Python 和 Java 中的语法非常类似:

image.png

装饰器 (Decorator)的特点:

  • 可以对类、对象、方法、属性进行修饰(使用类语法)
  • 可以实现逻辑的封装,减少不必要的重复
  • 代码变得更简洁,增加代码的可读性

安装

vue-property-decorator 是在 vue-class-component 的基础上做了进一步的封装,可以使用 npm 或是 yarn 进行安装

npm i -S vue-property-decorator

Vue中常用的装饰器

格式: @+ 装饰器名称

image.png

按需引入,使用哪种装饰器,就在页面中引入哪种装饰器名称,比如:

import { Component, Prop, Emit, Mutation } from 'vue-property-decorator'

@Component

原始写法: image.png

装饰器写法:

@Component
export default class LoginComponent extends Vue {
  message = null
  data() {
    return {
      name: '俺'
    }
  }
}

注:上面的 message 如果没有初始值,赋值的时候要为 null ,而非 undefined ,因为如果初始值为 undefined ,属性不会变成响应式,属性值变化的时候不会检测到属性的更改

也可以在 @Component 中传递参数:

image.png

@Prop

基于上面的组件装饰器,我们可以在其中使用其他的装饰器语法:

age 用来接收父组件传递的值,一个 @Prop 表示一个属性的声明,存在多个的时候需要写多个 @Prop

@Prop({ default: '俺是默认值' }) readonly age: number | undefined

相当于原来的:

image.png

@Emit

@Emit() 
updateData(n: number) { return n }

相当于:

image.png

如果声明为带参数的@Emit('sendNumber') ,则表示this.$emit('sendNumber',n)

自定义装饰器

常见场景:

  1. 防抖节流函数的封装

以防抖为例:

import { debounce } from 'lodash'

export const debounce = function(wait, options = {}) {
  return function(target, name, descriptor) {
    descriptor.value = debounce(descriptor.value, wait, options)
  }
}

使用:

import {debounce} from '@/decorator'

@debounce(100)
// 进行防抖的函数