Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vue with typescript #73

Open
hsipeng opened this issue Nov 4, 2018 · 0 comments
Open

vue with typescript #73

hsipeng opened this issue Nov 4, 2018 · 0 comments

Comments

@hsipeng
Copy link
Owner

hsipeng commented Nov 4, 2018

开始

下面的内容默认你已经具备了vue相关项目知识,而且现在想加入typescript来优化项目的实现。源码仓库

加入typescript

yarn add ts-loader typescript -D #or npm i ts-loader typescript -D
  • tsconfig.json配置
{
    "compilerOptions": {
        "outDir": "./built/",
        "sourceMap": true,
        "strict": true,
        "module": "esnext",//module support
        "moduleResolution": "node",
        "target": "es5",// build target
        "experimentalDecorators": true,
        "lib": [
          "dom",
          "es5",
          "es6",
          "es7",
          "es2015.promise" // promise support
        ],
        "pretty": true// pretty error msg
    },
    "include": [
        "./src/**/*"
    ],
    "exclude": [
      "node_modules"
    ],
    "paths": {
        "@/*": [
            "src/*"
        ]
    }
}
  • webpack 配置
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/]
        }
      },


...

resolve: {
    extensions: ["*",".ts", ".js", ".vue", ".json"],
    alias: {
      vue$: "vue/dist/vue.esm.js",
      "@": path.join(__dirname, '../src')
    }
  },

...

plugins: [
    new vueLoaderPlugin(), // var vueLoaderPlugin = require("vue-loader/lib/plugin");
    
  ]

我这边默认识别所有后缀,特别注意这边需要引入vueLoaderPlugin插件来让webpack 解析 vue 文件,分别template 用string, script 设置 lang='ts' 来让ts-loader 解析, style 默认 css-loader 解析。

配置基础结构

将所有js 文件改成ts 文件,该加类型加interface就行了一般。

单文件组件的两种写法

  • Vue.extend
    使用基础 Vue 构造器,创建一个“子类”。此种写法与 Vue 单文件组件标准形式最为接近,唯一不同仅是组件选项需要被包裹在 Vue.extend() 中。
import Vue from 'vue';
export default Vue.extend({
  name: '',
  computed: {
    ...
  },
  methods: {
    ...
  },
  components: {
    ...
  },
});

大概像上面这样,如果你使用了vuex 的 modules并且制定了命名空间的话,需要用到 vuex 中的辅助函数createNamespacedHelpers

import Vue from 'vue';
import {createNamespacedHelpers} from 'vuex';
import Counter from '@/components/Counter.vue';
import {IState} from '../store/modules/counter';

const {
  mapState,
  mapGetters,
  mapActions,
} = createNamespacedHelpers('counter');

export default Vue.extend({
  name: 'app',
  computed: {
    ...mapState({count: (state: IState) => state.count}),
    ...mapGetters(['isEvenOrOdd']),
  },
  methods: {
    ...mapActions([
      'incrementIfAsync',
      'decrementIfAsync',
      'increment',
      'decrement',
    ]),
  },
  components: {
    Counter,
  },
});
  • vue-class-component
    通常与 vue-property-decorator 一起使用,提供一系列装饰器,能让我们书写类风格的 Vue 组件。
import { Component, Vue,} from 'vue-property-decorator';
export default class CounterContainer extends Vue {
  ...
}

大概像上面这样,如果你使用了vuex 的 modules并且制定了命名空间的话,需要用到vuex-class 来辅助命名空间的定位。

import { Component, Vue,} from 'vue-property-decorator';
import Counter from "@/components/Counter.vue";
import { Getter, Action,State, namespace} from 'vuex-class'
// 命名空间
const counterModule = namespace('counter')
@Component({
  components: {
    Counter
  },
})
export default class CounterContainer extends Vue {
  @counterModule.State('count') public count?: number;
  @counterModule.Getter('isEvenOrOdd') public isEvenOrOdd?: string;
  @counterModule.Action('increment') public increment: any;
  @counterModule.Action('decrement') public decrement: any;
  @counterModule.Action('incrementIfAsync') public incrementIfAsync: any;
  @counterModule.Action('decrementIfAsync') public decrementIfAsync: any;
}

vuex 重写

  • action写法
    action 中用到commit 需要从 vuex中引入,下面是一个具体写法。
import {Commit} from 'vuex';

export interface IAction {
  commit: Commit;
}

const actions = {
  increment: ({commit}: IAction) => commit(types.INCREMENT),
  decrement: ({commit}: IAction) => commit(types.DECREMENT),
  async incrementIfAsync({commit}: IAction) {
    commit(types.INCREMENT, await getData(1000));
  },
  async decrementIfAsync({commit}: IAction) {
    commit(types.DECREMENT, await getData(1000));
  },
};
  • 引入 promise
    如果项目中需要用到promise 或者 async/await 方法需要在tsconfig.json 中引入 es2015.promise 来让typescript 断言。不让会通不过编译。上面我默认配置了。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant