在vue中使用typescript - 使用篇

基本使用

// page頁面======================================================================
import { Component, Vue } from 'vue-property-decorator'
import NavBar from '@/components/NavBar.vue'
// 使用組件
@Component({
  components: {
    NavBar
  }
})
// 創(chuàng)建頁面組件
export default class App extends Vue {
  
}

// 接口interface 文件=============================================================
export interface MainButtonType {
  id: number;
  icon: string | any;
  name: string
}


// 組件===========================================================================
<template>
  <div class="home">
    <swiper :options="swiperOption" class="swiper-wrap">
      <swiper-slide v-for="(slide, index) in swiperData" :key="index">
        <img :src="slide.imgUrl" />
      </swiper-slide>
      <div class="swiper-pagination" slot="pagination"></div>
    </swiper>

    <div class="button-wrap">
      <main-button :ButtonData="ButtonData" @buttonClick="handleButtonClick"/>
    </div>

    <div class="exp">
      <filter-component/>
    </div>
  </div>
</template>

import 'swiper/dist/css/swiper.css'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import { Component, Prop, Vue } from 'vue-property-decorator'
import MainButton from '@/components/MainButton.vue'
import FilterComponent from '@/components/FilterComponent.vue'
import { MainButtonType } from '@/types'

@Component({
  components: {
    swiper,
    swiperSlide,
    MainButton,
    FilterComponent
  }
})
export default class Home extends Vue {
  // 定義data數(shù)據(jù)
  private swiperData: any[] = [
    {
      id: 0,
      imgUrl: require('../assets/banner.png')
    }
  ]
  private swiperOption: object = {}
  // 使用interface接口定義類型 => MainButtonType
  private ButtonData: MainButtonType[] = [
    {
      id: 0,
      icon: require('../assets/travel_application.png'),
      name: '出差申請'
    },
    {
      id: 1,
      icon: require('../assets/flight.png'),
      name: '機(jī)票'
    }
  ]
  // 接口子組件的emit的函數(shù)
  private handleButtonClick(id: number): void {
    console.log('id:', id)
  }
}

// MainButton 組件中(子組件)===============================================================
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator'
import { MainButtonType } from '@/types'

@Component
export default class MainButton extends Vue {
  // props
  @Prop({default: []}) ButtonData!: MainButtonType[]
  // 生命周期
  created(): void {
    console.log('created')
  }
  // watch
  @Watch('ButtonData', {deep: true, immediate: true})
  ButtonDataWatch(val: MainButtonType[]):void {
    console.log(123, val)
  }
  // emit
  @Emit('buttonClick')
  private handleItemClick(id: number): void {
    // 函數(shù)的參數(shù)值即是emit的payload
  }
}

// filterComponent組件:filters和computed示例 (子組件)==================================================================
<template>
  <div class="filter-wrap">
    <div>filters示例:{{exp | formatNum}}</div>
    <br/>
    <div>computed示例:{{computedNum}}</div>
  </div>
</template>

import { Component, Vue } from 'vue-property-decorator'

@Component({
  // filters
  filters: {
    formatNum(val: number): string {
      if (!val && val !== 0) return ''
      return val.toFixed(2)
    }
  }
})
export default class FilterComponent extends Vue {
  private exp: number = 12.346546754
  // computed
  get computedNum(): number {
    return this.exp * 1000
  }
}

在vuex中使用

  1. 注: typescript目前對vuex的支持還不完善,需要引入 vuex-class 包來支持
  2. vuex-class 提供了State, Getter, Action, Mutation, nam-espace 這幾個裝飾器
  3. 示例
// vuex中, 以state為例
// 1. 定義接口
export interface USERINFO {
  userId: number;
  userName: string;
  avatar: string
}

export default interface STATE {
  userInfo: USERINFO;
}

// 2. state.js使用接口
import STATE from './stateType.js';
const state: STATE = {
  userInfo: {
    userId: 0,
    userName: '',
    avatar: '',
  }
};
export default state;


// 組件中使用
import Vue from 'vue'
import Component from 'vue-class-component'
import {
  State,
  Getter,
  Action,
  Mutation,
  namespace
} from 'vuex-class'

const someModule = namespace('path/to/module')

@Component
export class MyComp extends Vue {
  @State('foo') stateFoo
  @State(state => state.bar) stateBar
  @Getter('foo') getterFoo
  @Action('foo') actionFoo
  @Mutation('foo') mutationFoo
  @someModule.Getter('foo') moduleGetterFoo

  @State foo
  @Getter bar
  @Action baz
  @Mutation qux

  created () {
    this.stateFoo // -> store.state.foo
    this.stateBar // -> store.state.bar
    this.getterFoo // -> store.getters.foo
    this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
    this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
    this.moduleGetterFoo // -> store.getters['path/to/module/foo']
  }
}

注意事項

  1. vue-property-decoratorvue-class-component 的區(qū)別
  • vue-class-component 是 vue 官方出的
  • vue-property-decorator 是社區(qū)出的
  • 其中vue-class-component 提供了 vue component 等等
  • vue-property-decorator 深度依賴了 vue-class-component 拓展出了很多操作符@Prop @Emit @Inject等等 可以說是vue-class-component的一個超集
  • 正常開發(fā)的時候 你只需要使用vue-property-decorator中提供的操作符即可 不用再從vue-class-componen引入vue component
  1. 引入第三方包報錯
  • 現(xiàn)象: Could not find a declaration file for module 'vue-awesome-swiper'
    e7e1f5f462d88e9d304441f1e1cb962.png
  • 原因: 插件文件可能不是.ts文件而是.js文件
  • 解決方案一: 安裝對應(yīng)的ts模塊
  • 解決方案二: 配置 shims-vue-d.ts 文件(推薦)
      import Vue from "vue"
      import VueRouter, { Route } from "vue-router"
    
      declare module '*.vue' {
        export default Vue
      }
    
      declare module "vue/types/vue" {
        interface Vue {
          $router: VueRouter; // 這表示this下有這個東西
          $route: Route;
          $https: any;
          $urls: any;
          $Message: any;
          $Modal: any;
        }
      }
      // 以swiper為例,在此添加聲明
      declare module 'vue-awesome-swiper'
    
  • 解決方案三: 配置 tsconfig.json 文件
      {
        "compilerOptions": {
          ...
          "noImplicitAny": false,   // 忽略引入類型檢查
          ......
        }
      }
    
  1. 聲明全局變量
  • 添加shime-global.d.ts文件,與main.ts同級
// 聲明全局的 window ,不然使用 window.XX 時會報錯
// declare var window: Window;
declare var document: Document;
declare var THREE: any;

// interface THREE extends Window {}

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

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

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