Vue与Typescript开发

语法

具体的语法请参考, vue-class-component, vue-property-decorator。下面是Vue中常见功能的class版本的语法规则。

Element—UI

Element—UI以及Muse-UI官方提供了d.ts文件, iview官方尚未提供ts的支持

import * as element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(element);
复制代码

class组件

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

@Component
export default class TodoList extends Vue {
}
复制代码

// 引入其他组件
import Vue from 'vue';
import { Component } from 'vue-property-decorator';
import DemoData from '@/components/DemoData.vue';

@Component({
  components: {
    DemoData,
  },
})
export default class Demos extends Vue {
}
复制代码

组件生命周期


private created(): void {
  this.init();
}

private mounted(): void {
  this.init();
}
复制代码

data

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

interface Girl {
  name: string;
  age: number;
  hobbys: string[];
}

@Component
export default class DemoData extends Vue {
  private name: string = 'fangfang';
  private lover: Girl = {
    name: 'fangfang',
    age: 23,
    hobbys: ['旅行', '看书'],
  };
  private hobbys: string[] = ['旅行', '看书'];
}
复制代码

props


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

@Component
export default class DemoProps extends Vue {
  @Prop({ default: 'fangfang', required: true }) private name!: string;
  @Prop({ default: 'loveFangFang', required: false }) private oath!: string;
}
复制代码

computed


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

@Component
export default class DemoComputed extends Vue {
  @Prop({ default: 'yueyue' }) private boyname!: string;

  get confession() {
    return `${this.boyname}, love, fangfang`;
  }
}
复制代码

watch


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

@Component
export default class DemoWatch extends Vue {
  private girlName: string = 'fangfang';
  private bodyName: string = 'zhangyue';

  private created(): void {
    setTimeout(() => {
      this.bodyName = `love ${this.bodyName}`;
    }, 3000);
  }

  @Watch('bodyName')
  private onNameChange(val: string, oldVal: string): void {
    this.girlName = `${this.girlName}${val}`;
  }
}
复制代码

// 添加deep的选项
import Vue from 'vue';
import { Component, Watch } from 'vue-property-decorator';

interface GrilInfo {
  name: string;
  age: number;
}

interface Gril {
  info: GrilInfo;
}

@Component
export default class DemoWatch extends Vue {
  private girlName: string = 'fangfang';
  private bodyName: string = 'zhangyue';
  private girlInfo: Gril = {
    info: {
      name: 'fangfang',
      age: 23,
    },
  };

  private created(): void {
    setTimeout(() => {
      this.bodyName = `love ${this.bodyName}`;
    }, 3000);
    setTimeout(() => {
      this.girlInfo = Object.assign({}, this.girlInfo, {
        info: {
          name: 'fangfang love yueyue',
        },
      });
    }, 5000);
  }

  @Watch('bodyName')
  private onNameChange(val: string, oldVal: string): void {
    this.girlName = `${this.girlName}${val}`;
  }

  @Watch('girlInfo', { deep: true })
  private onGirlInfoChange(val: Gril, oldVal: Gril): void {
    // alert('love');
  }
}
复制代码

directives


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

@Component({
  directives: {
    focus: {
      inserted(el): void {
        el.focus();
      },
    },
  },
})
export default class DemoDirectives extends Vue {
}
复制代码

filters

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

@Component({
  filters: {
    gril(value: string): string {
      return `${value}, love, yueyue`;
    },
  },
})
export default class DemoFilter extends Vue {
  private name: string = 'fangfang';
}
复制代码

emit


@Emit('change')
handleChange(n) {
}

// 等同于
this.$emit('change', n)
复制代码

// 完整的示例
// 接受事件
import Vue from 'vue';
import { Component, Emit } from 'vue-property-decorator';
import DemoEmit from './DemoEmit.vue';

@Component({
  components: {
    DemoEmit,
  },
})
export default class DemoOnEmit extends Vue {
  private content: string = '空白';

  private onChangeName(content: string): void {
    this.content = content;
  }
}

// 发送事件
import Vue from 'vue';
import { Component, Emit } from 'vue-property-decorator';

@Component
export default class DemoEmit extends Vue {
  private created(): void {
    setTimeout(() => {
      this.handleChangeName('yueyue love fangfang');
    }, 3000);
  }

  @Emit('chang-name')
  private handleChangeName(n: string): void {
    return undefined;
  }
}
复制代码

methods

  private init(): void {
    alert('init');
  }
}
复制代码

Vuex

Vuex是Vue与TypeScript结合的痛点, 我使用的解决方案是通过vuex-class, 但是vuex-class有一个缺陷,vuex-class中定义的类型, 没有办法在.vue中推导出来, 我曾经给vuex-class作者提出了一个lssues, 作者给出的建议如下, 在.vue文件中再一次声明类型。


// store
import Vue from 'vue';
import Vuex from 'vuex';
import ModuleA from './modules/moduleA';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    ModuleA,
  },
  state: {
    name: 'test',
  },
});
复制代码
// moduleA
import { Commit } from 'vuex';

interface ModuleA {
  name: string;
  hobby: string[];
}

const ModuleAState: ModuleA = {
  name: 'fangfang',
  hobby: ['看书'],
};

const getters = {
  oath(state: ModuleA): string {
    return `${state.name} love yueyue`;
  },
};

const actions = {
  addHobby({ commit }: { commit: Commit }, hobby: string) {
    commit('ADD_HOBBY', hobby);
  },
};

const mutations = {
  ADD_HOBBY(state: ModuleA, hobby: string): void {
    state.hobby = [...state.hobby, hobby];
  },
};

export default {
  namespaced: true,
  state: ModuleAState,
  getters,
  actions,
  mutations,
};
复制代码
// xxx.vue
// Vuex中类型是丢失的, 需要自己在手动写一遍
import Vue from 'vue';
import { Component } from 'vue-property-decorator';
import DemoData from '@/components/DemoData.vue';
import DemoProps from '@/components/DemoProps.vue';
import DemoComputed from '@/components/DemoComputed.vue';
import DemoWatch from '@/components/DemoWatch.vue';
import DemoDirectives from '@/components/DemoDirectives.vue';
import DemoFilter from '@/components/DemoFilter.vue';
import DemoOnEmit from '@/components/DemoOnEmit.vue';
import {
  State,
  Getter,
  Action,
  Mutation,
  namespace,
} from 'vuex-class';

const ModuleA = namespace('ModuleA/');

@Component({
  components: {
    DemoData,
    DemoProps,
    DemoComputed,
    DemoWatch,
    DemoDirectives,
    DemoFilter,
    DemoOnEmit,
  },
})
export default class Demos extends Vue {

  @State('name') public stateName!: string;
  @ModuleA.State('name') public ModuleAStateName!: string;
  @ModuleA.Getter('oath') public ModuleAGetterOath!: string;
  @ModuleA.Action('addHobby') public ModuleAActionAddHobby!: (hobby: string) => void;
  @ModuleA.State('hobby') public ModuleAStateHobby!: string[];
  @ModuleA.Mutation('ADD_HOBBY') public ModuleAMutationAddHobby!: (hobby: string) => void;

  private created(): void {
    this.init();
  }

  private init(): void {
    // 全局的state状态
    // console.log(this.stateName);

    // 命名空间的state状态
    // console.log(this.ModuleAStateName);

    // 命名空间的getter
    // console.log(this.ModuleAGetterOath);

    // 使用dispath
    this.ModuleAActionAddHobby('456');
    // console.log(this.ModuleAStateHobby);

    // 使用commit
    this.ModuleAMutationAddHobby('1243');
    // console.log(this.ModuleAStateHobby);
  }
}
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值