vue 中使用 TS 的 class-style代碼風格


前言:

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 裝飾器接收一個可選參數,用來指向元素或子組件的引用信息。如果沒有提供這個參數,會使用裝飾器后面的屬性名充當參數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM