美文网首页
在vue中使用typescript - 使用篇

在vue中使用typescript - 使用篇

作者: 有田春雪 | 来源:发表于2019-11-15 17:26 被阅读0次

    基本使用

    // 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
    }
    
    
    // 组件===========================================================================
    <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数据
      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示例 (子组件)==================================================================
    <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 的区别
    • 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'
      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 - 使用篇

          本文链接:https://www.haomeiwen.com/subject/sfvsictx.html