vue-property-decorator分享

vue-property-decorator分享

关于vue-property-decorator的疑问

vue-property-decorator是什么

  • 'vue-property-decorator' 是vue社区推出的用于拓展 'vue-class-component' 的 装饰器集合库

vue-class-component是什么

  • 'vue-class-component' 是vue官方推出的一个库,可让您使用类样式的语法来制作Vue组件,使vue组件可以使用继承(Extend)、混入(Mixins)等高级特性

装饰器是什么

  • 装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法,许多面向对象的语言都有这项功能。
  • 装饰器是一种函数,写成@ + 函数名。它可以放在类和类方法的定义前面。

vue-property-decorator的用法

vue-property-decorator有哪些内容

  • @Component
  • @Prop
  • @PropSync
  • @Model
  • @Watch
  • @Emit
  • @Ref
  • @Provide
  • @Inject
  • @ProvideReactive
  • @InjectReactive

@Component

  • 继承自vue-class-component
  • 其中可以声明props,watch,components,template
  • 采用vue-property-decorator后尽量将components,template以外的内容用装饰器声明
  • 例:
@Component({
  template: '<button @click="onClick">Click!</button>',
  components: {
    helloworld,
  }
})

@Prop

  • 组件的props值之一
  • 例:
@Prop([String, Boolean]) readonly propA: string | boolean | undefined
@Prop() title?: string;

相当于
props: {
  propC: {
    type: [String, Boolean],
  },
  title: {

  }
}

@PropSync

  • 组件的props值之一,并给此prop添加一个<kbd>.sync</kbd>修饰符
  • 例:
@PropSync('name', { type: String }) syncedName!: string

相当于
props: {
  name: {
    type: String
  }
},
computed: {
  syncedName: {
    get() {
      return this.name
    },
    set(value) {
      this.$emit('update:name', value)
    }
  }
}

@Model

  • 组件的v-model, 用于给自定义组件添加v-model
  • 例:
@Model('change', { type: Boolean }) readonly checked!: boolean

相当于
model: {
  prop: 'checked',
  event: 'change'
},
props: {
  checked: {
    type: Boolean
  }
}

@Watch

  • vue的侦听属性
  • 例:
@Watch('child', {immediate: true, deep: true})
onChildChanged(val: string, oldVal: string) {}

相当于
watch: {
  child: [{
    handler: 'onChildChanged',
    immediate: true,
    deep: true
  }]
},
methods: {
  onChildChanged(val, oldVal) {}
}

@Emit

  • 在函数的最后使用emit将返回值传给父组件, 第一个参数是emit事件名
  • 例:
count = 0
@Emit()
addToCount(n: number) {
  this.count += n
},
@Emit('reset')
resetCount() {
  this.count = 0
}

相当于
data() {
  return {
    count: 0
  }
},
methods: {
  addToCount(n) {
    this.count += n
    this.$emit('add-to-count', n)
  },
  resetCount() {
    this.count = 0
    this.$emit('reset')
  },
}

@Ref

  • refs值之一,第一个参数是ref值,此装饰器会将ref映射到计算属性中
  • 例:
@Ref() readonly anotherComponent!: AnotherComponent
@Ref('aButton') readonly button!: HTMLButtonElement

相当于
computed() {
  anotherComponent: {
    cache: false,
    get() {
      return this.$refs.anotherComponent as AnotherComponent
    }
  },
  button: {
    cache: false,
    get() {
      return this.$refs.aButton as HTMLButtonElement
    }
  }
}

@Provide

  • 等同于provide,用于祖孙组件的传输值,需要与inject配合使用
  • 例:
@Provide() foo = 'foo'
@Provide('bar') baz = 'bar'

相当于
provide() { // 当前组件传入子孙组件的值
  return {
    foo: this.foo,
    bar: this.baz
  }
}

@Inject

  • 等同于inject,用于祖孙组件的接收值,需要与provide配合使用
  • 例:
@Inject('bar') readonly bar!: string
@Inject({ from: 'optional', default: 'default' }) readonly optional!: string


相当于
inject: { // 接收父、祖组件的 provide
  bar: 'bar',
  optional: { from: 'optional', default: 'default' },
},

@ProvideReactive 与 @InjectReactive

  • 等同于provide/inject,用于祖孙组件的传输接收
  • 与@Provide/inject不同的是,@ProvideReactive/@InjectReactive是响应式的, 使用后者的情况下,祖父组件进行修改时孙子组件会相应的变更
  • 例:
@Component
class ParentComponent extends Vue {
  @ProvideReactive() one = 'value'
}

@Component
class ChildComponent extends Vue {
  @InjectReactive() one!: string
}

相当于
inject: { // 接收父、祖组件的 provide
  one: 'foo',
},
data() {
  return {
    one: 'foo',
  }
},
provide() { // 当前组件传入子孙组件的值
  return {
    one: this.one,
  }
}


vue-property-decorator的其他用法

Component.registerHooks

  • 此方法可用于vue生态下的其他钩子,例如vue-router
  • 这些钩子不会被视为vue methods下的方法
  • 用法:
Component.registerHooks([
  'beforeRouteEnter',
  'beforeRouteLeave',
  'beforeRouteUpdate'
])

@Component
export default class HelloWorld extends Vue {
  beforeRouteEnter(to, from, next) {...}
}

createDecorator

  • 用此方法可以创建自定义的装饰器, 自定义装饰器的用法与es6中规定的装饰器一致。
  • 用法:
import Vue from 'vue'
import Component,{ createDecorator } from 'vue-class-component'

const Log = createDecorator((options, key) => {
  const originalMethod = options.methods[key]
  options.methods[key] = function wrapperMethod(...args) {
    console.log(`Invoked: ${key}(`, ...args, ')')
    originalMethod.apply(this, args)
  }
})

@Component
class MyComp extends Vue {
  @Log
  hello(value) {
    // ...
  }
}

与vue-property-decorator相关的一些内容

vuex-class

import { Component, Inject, Provide, Vue } from 'vue-property-decorator'
import {
  State,
  Getter,
  Action,
  Mutation,
  namespace
} from 'vuex-class'

const someModule = namespace('path/to/module')

@Component
export class MyComp extends Vue {
  @State('foo') stateFoo
  @State(state => state.bar) stateBar
  @Getter('foo') getterFoo
  @Action('foo') actionFoo
  @Mutation('foo') mutationFoo
  @someModule.Getter('foo') moduleGetterFoo

  // If the argument is omitted, use the property name 如果省略了参数,则使用属性名
  // for each state/getter/action/mutation type
  @State foo
  @Getter bar
  @Action baz
  @Mutation qux

  created () {
    this.stateFoo // -> store.state.foo
    this.stateBar // -> store.state.bar
    this.getterFoo // -> store.getters.foo
    this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
    this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
    this.moduleGetterFoo // -> store.getters['path/to/module/foo']
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容