前言:
vue 中使用 typescript的 class-style 風格代碼,除了用到ts的語法,還用到了 vue-property-decorator語法 vue-class-component語法
vue-property-decorator 與 vue-class-component 的關系
vue class component 是vue 官方出的
vue property decorator 是社區出的
其中vue class component 提供了 vue component 等等
vue property decorator 深度依賴了 vue class component 拓展出了很多操作符 @Prop @Emit @Inject 等等 可以說是 vue class component 的一個超集
正常開發的時候 你只需要使用 vue property decorator 中提供的操作符即可 不用再從vue class componen 引入vue component
一、如何使用(官網介紹)
1、導入npm 包
npm i -S vue-property-decorator
主要有以下一些裝飾器和一個方法
@Prop
@PropSync
@Model
@ModelSync
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
@VModel
@Component (provided by vue-class-component)
Mixins (the helper function named mixins provided by vue-class-component)
@Component
注: 該屬性完全繼承於vue-class-component
屬性參數:@Component(options: ComponentOptions = {})
參數說明:@Component 裝飾器可以接收一個對象作為參數,可以在對象中聲明 components ,filters,directives, beforeRouteLeave等未提供裝飾器的選項,也可以聲明computed,watch等
<template>
<div class="parent">
parent組件--{{title}}
<hr>
<Home v-model="title"></Home>
<About v-model="title"></About>
</div>
</template>
1、js 寫法
<script>
import Home from './Home.vue'
import About from './About.vue'
export default {
data() {
return {
title: '父組件中的值'
}
},
components: {
Home,
About
}
}
</script>
2、ts 寫法
<script lang='ts'>
import Home from './Home.vue'
import About from './About.vue'
import { Component, Vue } from 'vue-property-decorator';
@Component({
components: {
Home,
About
}
})
export default class extends Vue {
private title: string = '父組件中的值'
}
</script>
@Emit
屬性參數:@Emit(event?: string)
參數說明:
@Emit 裝飾器接收一個可選參數,充當事件名。如果沒有提供這個參數,@Emit會將回調函數名的camelCase轉為kebab-case,並將其作為事件名;
@Emit的回調函數的參數,會在回調函數沒有返回值的情況下,被$emit當做第二個參數使用。
@Emit會將回調函數的返回值作為第二個參數,如果返回值是一個Promise對象,$emit會在Promise對象被標記為resolved之后觸發;
<template>
<div class="home">
vue+ts項目vue-property-decorator用法
<hr>
<button @click="triggerEmit('qqq')">觸發emit</button>
</div>
</template>
1、js寫法
export default {
data() {
return {}
},
mounted() {
this.$on('trigger-emit', data => {
alert(data)
})
},
methods: {
triggerEmit(val) {
this.$emit('trigger-emit', val)
}
}
}
2、ts寫法
<script lang="ts">
import { Component, Vue, Emit } from 'vue-property-decorator';
@Component({})
export default class Home extends Vue {
private mounted() {
this.$on('demo-log', (data: any): void => {
alert(data)
})
}
@Emit('demo-log')
triggerEmit(n: any) {
console.log('hhh')
}
}
</script>
另一種寫法,$on位置使用 - 鏈接,@Emit位置直接使用駝峰命名,則可以省略括號中的名稱:”
export default class Home extends Vue {
private mounted() {
this.$on('trigger-emit', (data: any): void => {
alert(data)
})
}
@Emit()
triggerEmit(n: any) {
console.log('hhh')
}
}
案例二、
ts
<script lang="ts">
import {Vue, Component, Emit} from 'vue-property-decorator';
@Component
export default class "組件名" extends Vue{
mounted(){
this.$on('emit-todo', function(n) {
console.log(n)
})
this.emitTodo('world');
}
@Emit()
emitTodo(n: string){
console.log('hello');
}
}
</script>
以上代碼會輸出 hello world,js寫法如下
<script>
import Vue from 'vue';
export default {
mounted(){
this.$on('emit-todo', function(n) {
console.log(n)
})
this.emitTodo('world');
},
methods: {
emitTodo(n){
console.log('hello');
this.$emit('emit-todo', n);
}
}
}
</script>
在@Emit裝飾器的函數會在運行之后觸發等同於其函數名(駝峰式會轉為橫杠式寫法)的事件, 並將其參數傳遞給$emit.
如果我們想觸發特定的事件呢,比如在emitTodo下觸發reset事件:
<script lang="ts">
import {Vue, Component, Emit} from 'vue-property-decorator';
@Component
export default class "組件名" extends Vue{
@Emit('reset')
emitTodo(n: string){
}
}
</script>
我們只需要給裝飾器@Emit傳遞一個事件名參數reset,這樣函數emitTodo運行之后就會觸發reset事件.
@Prop
屬性參數:@Prop(options: (PropOptions | Constructor[] | Constructor) = {})
參數說明:@Prop裝飾器接收一個參數,這個參數可以有三種寫法:
PropOptions,可以使用以下選項:type,default,required,validator;
Constructor[],指定 prop 的可選類型;
Constructor,例如String,Number,Boolean等,指定 prop 的類型;
注意:
屬性的ts類型后面需要加上undefined類型;或者在屬性名后面加上!,表示非null 和 非undefined的斷言,告訴TypeScript我這里一定有值,否則編譯器會給出錯誤提示;
!: 表示一定存在,?: 表示可能不存在。這兩種在語法上叫賦值斷言
比如子組件從父組件接收三個屬性propA,propB,propC
propA類型為Number
propB默認值為default value
propC類型為String或者Boolean
export default {
props: {
propA: {
type: Number
},
propB: {
default: 'default value'
},
propC: {
type: [String, Boolean]
},
}
}
使用vue-property-decorator提供的@Prop可以將上面的代碼改造為如下:
<script lang="ts">
import {Vue, Component, Prop} from 'vue-property-decorator';
@Component
export default class "組件名" extends Vue{
@Prop(Number) propA!: number;
@Prop({default: 'default value'}) propB!: string;
@prop([String, Boolean]) propC: string | boolean;
}
</script>
@Prop接受一個參數可以是類型變量或者對象或者數組.@Prop接受的類型比如Number是JavaScript的類型,之后定義的屬性類型則是TypeScript的類型.
@Ref
屬性參數:@Ref(refKey?: string)
參數說明:@Ref 裝飾器接收一個可選參數,用來指向元素或子組件的引用信息。如果沒有提供這個參數,會使用裝飾器后面的屬性名充當參數