(翻譯)vue-class-component

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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,365評(píng)論 0 6
  • 深入響應(yīng)式 追蹤變化: 把普通js對(duì)象傳給Vue實(shí)例的data選項(xiàng),Vue將使用Object.defineProp...
    冥冥2017閱讀 4,953評(píng)論 6 16
  • 主要還是自己看的,所有內(nèi)容來(lái)自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,536評(píng)論 0 25
  • 喜歡心理學(xué)不久就知道,在心理學(xué)界有本書(shū),名為秘密。 據(jù)說(shuō),讀懂了,能翻轉(zhuǎn)世界。能真正做到心想事成。 這么神奇?夸張...
    清晨的玉蘭閱讀 507評(píng)論 2 6
  • 天翊興宇 腰椎間盤突出患者,問(wèn)下患者,是否腿部有酸、麻、痛、發(fā)涼、僵硬等,這些都是腰突引起的坐骨神經(jīng)痛 *椎間盤退...
    佳源影視解說(shuō)閱讀 264評(píng)論 0 0

友情鏈接更多精彩內(nèi)容