(翻译)vue-class-component

vue-class-component

本文翻译自 vue-class-component

给 class 类型的 Vue 组件的 ECMAScript / TypeScript 修饰器

用法:

要求:ECMAScript 一阶段的修饰器
如果你使用 Babel,需要使用 babel-plugin-transform-decorators-legacy
如果你使用 TypeScript,请启用 --experimentalDecorators 标识

目前不支持二阶段修饰器,因为主流的编译器仍然编译旧版本的修饰器

注意

1.methods 可以直接声明作为 class 的方法

2.computed 可以直接声明作为 class 上属性的访问器

3.初始化的 data 可以声明作为 class 上的属性(如果你使用 Babel,你得使用babel-plugin-transform-class-properties

4.datarender 以及 Vue 生命周期钩子也可以直接声明作为 class 上的方法,但是你不能够不能通过当前实例引用它们(???这句不懂),当你声明一个普通的方法,你也要避免使用这些保留字。

5.对于其它的选项(options),将它们传递给修饰器函数

以下是一个 Babel 下的例子,如果你需要 TypeScript 版本,请看这里

<template>
  <div>
    <input v-model="msg">
    <p>prop: {{propMessage}}</p>
    <p>msg: {{msg}}</p>
    <p>helloMsg: {{helloMsg}}</p>
    <p>computed msg: {{computedMsg}}</p>
    <button @click="greet">Greet</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  props: {
    propMessage: String
  }
})
export default class App extends Vue {
  // 初始化 data
  msg = 123

  // 使用 prop 数据初始化 data
  helloMsg = 'Hello, ' + this.propMessage

  // 生命周期
  mounted () {
    this.greet()
  }

  // 计算属性 computed
  get computedMsg () {
    return 'computed ' + this.msg
  }

  // method
  greet () {
    alert('greeting: ' + this.msg)
  }
}
</script>

你可以在 vue-property-decorator 查看 @prop@watch 修饰器

使用 Mixins

vue-class-component 提供 mixins 帮助函数,可以用来在 class 类型风格中使用 mixins
通过 mixins 帮助函数,Typescript 可以推断出 mixin 类型并且在组件类型中继承它们。

声明 mixin 的例子:

// mixin.js
import Vue from 'vue'
import Component from 'vue-class-component'

// 你可以想声明一个组件一样声明一个 mixin
@Component
export default class MyMixin extends Vue {
  mixinValue = 'Hello'
}

然后使用它:

import Component, { mixins } from 'vue-class-component'
import MyMixin from './mixin.js'

// 使用 `mixins` 帮助函数,而不是 `Vue`.
// `mixins` 可以获取任何数量的参数

@Component
export class MyComp extends mixins(MyMixin) {
  created () {
    console.log(this.mixinValue) // -> Hello
  }
}

自定义修饰器

你还可以创建你自己的修饰器并且继承这个库的功能,vue-class-component 提供 createDecorator 帮助函数用来创建自定义修饰器。

createDecorator 的第一个参数是一个回调函数,并且这个函数可以获取一下参数:

options: vue 组件选项组成的对象,改变这些选项会影响所提供的组件
key: 修饰器所作为的属性或方法的 key
parameterIndex: 修饰器作用于参数时,这个参数的索引

例子:创建一个 NoCache 修饰器

// decorators.js
import { createDecorator } from 'vue-class-component'

export const NoCache = createDecorator((options, key) => {
  // 组件的选项应该传给回调函数,同时会更新选项对象(options object)
  // 进而作用于组件
  options.computed[key].cache = false
})
import { NoCache } from './decorators'
@Component
class MyComp extends Vue {
  // 这个计算属性不会被缓存
  @NoCache
  get random () {
    return Math.random()
  }
}

添加自定义钩子

如果你使用了一些Vue 插件比如 Vue Router,你可能会希望 class 组件解析它们所提供的钩子,比如,下面的例子中 Component.registerHooks 就允许你注册这些钩子

// class-component-hooks.js
import Component from 'vue-class-component'

// 通过这些钩子的名称来注册它们
Component.registerHooks([
  'beforeRouteEnter',
  'beforeRouteLeave',
  'beforeRouteUpdate' // for vue-router 2.2+
])
// MyComp.js
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class MyComp extends Vue {
  // class 组件现在可以处理 beforeRouteEnter 钩子和 
  // beforeRouteLeave 钩子作为 Vue Router 钩子
  beforeRouteEnter (to, from, next) {
    console.log('beforeRouteEnter')
    next() // 需要调用这个来确认导航
  }

  beforeRouteLeave (to, from, next) {
    console.log('beforeRouteLeave')
    next() // 需要调用这个来确认导航
  }
}

值得注意的是,你必须在组件定义之前注册钩子

// main.js

// 确保在引入任何组件之前注册
import './class-component-hooks'

import Vue from 'vue'
import MyComp from './MyComp'

new Vue({
  el: '#app',
  components: {
    MyComp
  }
})

注意事项

vue-class-component 通过实例化 钩子下的初始构造函数来收集 class 属性作为 Vue 实例的 data(???这句不太懂)。然而我们也可以像本地 class 的方式定义实例 data,有时候我们需要知道它是如何工作的。

this

如果你定义一个 class 属性并且在里面访问 this,它不会起作用,因为 this 只是当我们实例化 class 属性时候 Vue 实例的一个拦截对象。

@Component
class MyComp extends Vue {
  foo = 123

  bar = () => {
    // 不会如预期中的更新
    // `this` 的值实际上不是 Vue 实例
    this.foo = 456
  }
}

你可以简单地定义一个方法而不是一个 class 属性因为 Vue 会自动绑定实例

@Component
class MyComp extends Vue {
  foo = 123

  bar () {
    // 如预期地更新数据
    this.foo = 456
  }
}
undefined 不会响应式

为了在 Babel 和 TypeScript 上表现稳定,如果一个属性的初始化值是 undefined,vue-class-components 不会对它触发响应式,你应该使用 null 作为 初始值货值使用 data 钩子来初始化值为 undefined 的属性

@Component
class MyComp extends Vue {
  // 没有响应式
  foo = undefined

  // 响应式
  bar = null

  data () {
    return {
      // 响应式
      baz: undefined
    }
  }
}
创建例子
$ npm install && npm run example
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容