Vue學習(二十五)TS支持


如何在vue中使用TS

參考:vue+TypeScript需要注意的點(介紹了總體,先看一下這篇!)

            vue官網教程:TypeScript支持

改造 .vue 文件

要讓 TypeScript 正確推斷 Vue 組件選項中的類型,您需要使用 Vue.component 或 Vue.extend 定義組件,或者聲明組件時你更喜歡基於類的 API,則可以使用官方維護的 vue-class-component 裝飾器或者vue-property-decorator

1.基本用法

需要使用 Vue.component 或 Vue.extend 定義組件:

// import { Vue } from 'vue-property-decorator'; 這種寫法也可以
import Vue from 'vue';
export default Vue.extend({
    components: {
      TitleBar,
    },
 data() { return { data:'old-main' }; }, mixins:[mixinA,mixinB], extends: oldA, props: { propC: { type: String, required: true } }, computed: { aDouble: function () { return this.a * 2 } }, watch: { // 該回調會在任何被偵聽的對象的 property 改變時被調用,不論其被嵌套多深
 c: { handler: function (val, oldVal) { /* ... */ }, deep: true } }, onShow() { console.log("===old-main--onshow") }, created(){ console.log("===old-main--created") }, methods: { print(){ console.log("===old-main-print:",this.data) } } });

優點:與非ts編碼分格保持一致,上手成本低,可讀性強,官方dome使用

缺點:存在冗余,ts結合稍弱

2.基於類的vue組件

1)、采用vue-class-component

vue-class-component 對 Vue 組件進行了一層封裝,讓 Vue 組件語法在結合了 TypeScript 語法之后更加扁平化

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

<script lang="ts"> import Vue from 'vue' import Component from 'vue-class-component' @Component export default class App extends Vue {   // 初始化數據
       msg = 123

      // 聲明周期鈎子
    mounted () {   this.greet()   }   // 計算屬性
      get computedMsg () {   return 'computed ' + this.msg    }   // 方法
   greet () {   alert('greeting: ' + this.msg) } } </script>

2)、采用 vue-property-decorator

import { Component, Vue, Watch, } from 'vue-property-decorator'; import gamedownload from '@/components/download.vue'; // @Component 修飾符注明了此類為一個 Vue 組件
@Component({   components: { gamedownload, } }) // export default class extends Vue {} 這樣寫也可以
export default class App extends Vue { // 初始數據可以直接聲明為實例的 property
     data1: string = 'main-extends'

        // prop
       @Prop({ default: null }) curLevel!: number; // watch
       @Watch('styleObj',{immediate:true}) getIcons() { } // computed
        get isObjectNotEmpty(){ return (obj:any) => { return isObjectNotEmpty(obj); }; } // 生命周期
 created() { console.log("===main-extends--created") }; // 組件方法也可以直接聲明為實例的方法
         onClick (): void { window.alert(this.data1) } }

優點:代碼精簡,擴展性強,ts結合較好

缺點:要求較高,上手成本較高

vue-property-decorator中裝飾器用法

vue+ts項目vue-property-decorator(裝飾器)用法

Vue+TypeScript中如何處理computed

vue + ts 項目中watch的用法

vue + ts 項目中Prop的用法

// 接口
export interface IgameInfo {
    gameId: string,
    iosJumpScheme: string,
    downloadUrl: string,
    gameBundleId?: string,
    downloadName?: string,
    iosScheme?: string,
    packageVersion?: number
    downloadRealSize?: number,
    signature?: string
    icon?: string;
    gameName?: string;
    current?: number;
}

// 【處理data】
btnText: string = '下載';
gameBtnWidth: number = 0;
defaultFlag: boolean = true;
gameUpdateStatus: boolean = false;
toastFunc: (data:ItoastFunc) => void = () => {};
couList: Array<number> = [];
gameInfoCopy: any = [];

// 【prop用法】!: 表示一定存在,?: 表示可能不存在。這兩種在語法上叫賦值斷言
// 類型是對象,默認值是空對象
@Prop({ type: Object, default: () => {} })
gameInfo!: IgameInfo;

// 類型是對象,默認值是包含action和params的變量
@Prop({type: Object, default: () => { 
        return { action: '', params: {} };
}})
logParams?: any;

// 類型是布爾值,默認值是false
@Prop({ type: Boolean, default: false })
needAuto?: boolean;

// 類型是函數,默認值是空對象
@Prop({ type: Function, default: () => {} })
checkInstalledCb?: Function;

// 類型是函數,默認值是null
@Prop({ type: Function, default: null })
noPauseCb?: Function;

// 類型是字符串,默認值是下載中
@Prop({ type: String, default: '下載中' })
downloading0text?: string;

// 類型是字符串,默認值是空字符串
@Prop({ type: String, default: '' })
openSchema?: string;

// 類型是數值,默認值是1
@Prop({ type: Number, default: 1})
fromGameCenter?: number;

// 類型是數值,沒有默認值
@Prop({ type: Number})
sceneId!: number;

// 類型是數值,默認值是0
@Prop({ type: Number, default: () => 0 })
uId!: number;

// 類型是數組,默認值是空數組
@Prop({ type: Array, default: () => [] })
gameInfo!: IgameInfo[];

// 可以直接寫在一行
@Prop({ default: {} }) styleObj!: any;
@Prop({ default: {} }) header!: IHeader;

// 【watch用法】
@Watch('logParams')
onLogParamsChanged(newVal:any, oldVal:any) {
      this.logParams = newVal;
}

// 【處理計算屬性】
get showDownloadStyle () {
      return this.gameStatus === 'downloading' || this.gameStatus === 'pause';
}

實戰

實戰一:

<script lang="ts"> import { Component, Vue, Watch, } from 'vue-property-decorator'; import gamedownload from '@/common/components/download.vue'; @Component({ components: { gamedownload, }, }) export default class App extends Vue { giftList: any = {}; unAcquireCount: number = 0; showMask: Boolean = false; cdkey: string = ''; gameName: String = ''; gameIcon: String = ''; // 復制
 copy() { const that = this; }; // 初始化列表
          async initList() { const gameId = getUrlKey('gameId'); const response = await this.$requestApi.getGameGiftList(gameId); if (response.result == 1) { this.giftList = response.giftList; this.unAcquireCount = response.unAcquireCount; this.gameName = response.gameName.length > 6 ? response.gameName.substring(0, 6) + '..' : response.gameName; this.gameIcon = response.gameIcon; if (response.gameName) { ksBridge.setPageTitle({ title: `${response.gameName}福利禮包`, }); } } }; mounted() { this.initList(); ksBridge.on({ type: 'native_foreground', handler: this.initList, }); ksBridge.on({ type: 'native_reentry', handler: this.initList, }); } } </script>
<style lang="less"> @import "./index.less"; </style>

實戰二:

<script lang="ts"> require('./index.less') import { Component, Vue, Emit } from 'vue-property-decorator'; interface ruleItem{ title: string, desc: Array<string>, hasOpen?: boolean } @Component({}) export default class App extends Vue { ruleList: Array<ruleItem> = [ ]; triggerDesc(idx:number){ this.ruleList[idx]['hasOpen'] =  !this.ruleList[idx]['hasOpen']; this.$forceUpdate(); } } </script>

注意:組件的屬性不必放在data中,方法不必放在methods

問題集錦

解決vue+ts 裝飾器mounted/created等鈎子不執行的問題

 


免責聲明!

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



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