在vue中使用typescript - 使用篇

基本使用

// page页面======================================================================
import { Component, Vue } from 'vue-property-decorator'
import NavBar from '@/components/NavBar.vue'
// 使用组件
@Component({
  components: {
    NavBar
  }
})
// 创建页面组件
export default class App extends Vue {
  
}

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


// 组件===========================================================================


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数据
  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: '机票'
    }
  ]
  // 接口子组件的emit的函数
  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 {
    // 函数的参数值即是emit的payload
  }
}

// filterComponent组件:filters和computed示例 (子组件)==================================================================


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 的区别
  • 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. 引入第三方包报错
  • 现象: Could not find a declaration file for module 'vue-awesome-swiper'
    在vue中使用typescript - 使用篇_第1张图片
    e7e1f5f462d88e9d304441f1e1cb962.png
  • 原因: 插件文件可能不是.ts文件而是.js文件
  • 解决方案一: 安装对应的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";

你可能感兴趣的:(在vue中使用typescript - 使用篇)