vue-class-component
本文翻譯自 vue-class-component
給 class 類型的 Vue 組件的 ECMAScript / TypeScript 修飾器
用法:
要求:ECMAScript 一階段的修飾器。
如果你使用 Babel,需要使用 babel-plugin-transform-decorators-legacy
如果你使用 TypeScript,請(qǐng)啟用 --experimentalDecorators 標(biāo)識(shí)
目前不支持二階段修飾器,因?yàn)橹髁鞯木幾g器仍然編譯舊版本的修飾器
注意
1.methods 可以直接聲明作為 class 的方法
2.computed 可以直接聲明作為 class 上屬性的訪問(wèn)器
3.初始化的 data 可以聲明作為 class 上的屬性(如果你使用 Babel,你得使用babel-plugin-transform-class-properties)
4.data、render 以及 Vue 生命周期鉤子也可以直接聲明作為 class 上的方法,但是你不能夠不能通過(guò)當(dāng)前實(shí)例引用它們(???這句不懂),當(dāng)你聲明一個(gè)普通的方法,你也要避免使用這些保留字。
5.對(duì)于其它的選項(xiàng)(options),將它們傳遞給修飾器函數(shù)
以下是一個(gè) Babel 下的例子,如果你需要 TypeScript 版本,請(qǐng)看這里
<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 數(shù)據(jù)初始化 data
helloMsg = 'Hello, ' + this.propMessage
// 生命周期
mounted () {
this.greet()
}
// 計(jì)算屬性 computed
get computedMsg () {
return 'computed ' + this.msg
}
// method
greet () {
alert('greeting: ' + this.msg)
}
}
</script>
你可以在 vue-property-decorator 查看 @prop、@watch 修飾器
使用 Mixins
vue-class-component 提供 mixins 幫助函數(shù),可以用來(lái)在 class 類型風(fēng)格中使用 mixins
通過(guò) mixins 幫助函數(shù),Typescript 可以推斷出 mixin 類型并且在組件類型中繼承它們。
聲明 mixin 的例子:
// mixin.js
import Vue from 'vue'
import Component from 'vue-class-component'
// 你可以想聲明一個(gè)組件一樣聲明一個(gè) mixin
@Component
export default class MyMixin extends Vue {
mixinValue = 'Hello'
}
然后使用它:
import Component, { mixins } from 'vue-class-component'
import MyMixin from './mixin.js'
// 使用 `mixins` 幫助函數(shù),而不是 `Vue`.
// `mixins` 可以獲取任何數(shù)量的參數(shù)
@Component
export class MyComp extends mixins(MyMixin) {
created () {
console.log(this.mixinValue) // -> Hello
}
}
自定義修飾器
你還可以創(chuàng)建你自己的修飾器并且繼承這個(gè)庫(kù)的功能,vue-class-component 提供 createDecorator 幫助函數(shù)用來(lái)創(chuàng)建自定義修飾器。
createDecorator 的第一個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),并且這個(gè)函數(shù)可以獲取一下參數(shù):
options: vue 組件選項(xiàng)組成的對(duì)象,改變這些選項(xiàng)會(huì)影響所提供的組件
key: 修飾器所作為的屬性或方法的 key
parameterIndex: 修飾器作用于參數(shù)時(shí),這個(gè)參數(shù)的索引
例子:創(chuàng)建一個(gè) NoCache 修飾器
// decorators.js
import { createDecorator } from 'vue-class-component'
export const NoCache = createDecorator((options, key) => {
// 組件的選項(xiàng)應(yīng)該傳給回調(diào)函數(shù),同時(shí)會(huì)更新選項(xiàng)對(duì)象(options object)
// 進(jìn)而作用于組件
options.computed[key].cache = false
})
import { NoCache } from './decorators'
@Component
class MyComp extends Vue {
// 這個(gè)計(jì)算屬性不會(huì)被緩存
@NoCache
get random () {
return Math.random()
}
}
添加自定義鉤子
如果你使用了一些Vue 插件比如 Vue Router,你可能會(huì)希望 class 組件解析它們所提供的鉤子,比如,下面的例子中 Component.registerHooks 就允許你注冊(cè)這些鉤子
// class-component-hooks.js
import Component from 'vue-class-component'
// 通過(guò)這些鉤子的名稱來(lái)注冊(cè)它們
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 組件現(xiàn)在可以處理 beforeRouteEnter 鉤子和
// beforeRouteLeave 鉤子作為 Vue Router 鉤子
beforeRouteEnter (to, from, next) {
console.log('beforeRouteEnter')
next() // 需要調(diào)用這個(gè)來(lái)確認(rèn)導(dǎo)航
}
beforeRouteLeave (to, from, next) {
console.log('beforeRouteLeave')
next() // 需要調(diào)用這個(gè)來(lái)確認(rèn)導(dǎo)航
}
}
值得注意的是,你必須在組件定義之前注冊(cè)鉤子
// main.js
// 確保在引入任何組件之前注冊(cè)
import './class-component-hooks'
import Vue from 'vue'
import MyComp from './MyComp'
new Vue({
el: '#app',
components: {
MyComp
}
})
注意事項(xiàng)
vue-class-component 通過(guò)實(shí)例化 鉤子下的初始構(gòu)造函數(shù)來(lái)收集 class 屬性作為 Vue 實(shí)例的 data(???這句不太懂)。然而我們也可以像本地 class 的方式定義實(shí)例 data,有時(shí)候我們需要知道它是如何工作的。
this
如果你定義一個(gè) class 屬性并且在里面訪問(wèn) this,它不會(huì)起作用,因?yàn)?this 只是當(dāng)我們實(shí)例化 class 屬性時(shí)候 Vue 實(shí)例的一個(gè)攔截對(duì)象。
@Component
class MyComp extends Vue {
foo = 123
bar = () => {
// 不會(huì)如預(yù)期中的更新
// `this` 的值實(shí)際上不是 Vue 實(shí)例
this.foo = 456
}
}
你可以簡(jiǎn)單地定義一個(gè)方法而不是一個(gè) class 屬性因?yàn)?Vue 會(huì)自動(dòng)綁定實(shí)例
@Component
class MyComp extends Vue {
foo = 123
bar () {
// 如預(yù)期地更新數(shù)據(jù)
this.foo = 456
}
}
undefined 不會(huì)響應(yīng)式
為了在 Babel 和 TypeScript 上表現(xiàn)穩(wěn)定,如果一個(gè)屬性的初始化值是 undefined,vue-class-components 不會(huì)對(duì)它觸發(fā)響應(yīng)式,你應(yīng)該使用 null 作為 初始值貨值使用 data 鉤子來(lái)初始化值為 undefined 的屬性
@Component
class MyComp extends Vue {
// 沒(méi)有響應(yīng)式
foo = undefined
// 響應(yīng)式
bar = null
data () {
return {
// 響應(yīng)式
baz: undefined
}
}
}
創(chuàng)建例子
$ npm install && npm run example