摘要:进阶篇本文是继新项目起手式之后的进阶踩坑配置,所以推荐先行阅读前文完整阅读完之后,基本可以顺利在新项目中使用了另外特别注意不推荐在已有项目上强加,因写法的组件跟之前的组件不兼容,若上的话需要修改之前写的组件配置完整版可参考,若没配置出来
vue + typescript 进阶篇
本文是继 Vue + TypeScript 新项目起手式 之后的进阶+踩坑配置,所以推荐先行阅读前文
完整阅读完之后,基本可以顺利在新项目中使用vue + typescript 了
另外特别注意!!!
不推荐在已有项目上强加 typescript, 因ts写法的组件跟之前的组件不兼容,若上的话需要修改之前写的组件
配置完整版可参考 vue-typescript-starter,若没配置出来,也可以对照修改配置
直接进入正题:
概览ts 支持 render jsx 写法
ts 支持 es6 / es67
配置 vuex
vue 识别全局方法/变量
支持 mixin
支持 ProvidePlugin 的全局变量,比如 lodash的_
支持 render jsx 写法这里一共分两步
首先得先让 vue 支持 jsx 写法
再让 vue 中的 ts 支持 jsx 写法
让 vue 支持 jsx按照官方做法,安装Babel 插件
安装依赖
npm install babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props babel-preset-es2015 --save-dev
在.babelrc中添加:
{ "plugins": ["transform-vue-jsx"] }
之后就可以这些写render,如下图:
让 ts 支持 jsx首先配置 webpack
找到./build/webpack.base.conf.js
找到resolve.extensions 里面加上.tsx 后缀
resolve: { extensions: [".js", ".vue", ".json", ".ts", ".tsx"] }
找到module.rules 修改webpack对.tsx .ts 的解析
module: { rules: [ { test: /.(js|vue)$/, loader: "eslint-loader", enforce: "pre", include: [resolve("src"), resolve("test")], options: { formatter: require("eslint-friendly-formatter") } }, // 从这里复制下面的代码就可以了 // 如果之前按照起手式配置的同学,请替换配置 { test: /.tsx?$/, exclude: /node_modules/, enforce: "pre", loader: "tslint-loader" }, { test: /.vue$/, loader: "vue-loader", options: Object.assign(vueLoaderConfig, { loaders: { ts: "ts-loader", tsx: "babel-loader!ts-loader" } }) }, { test: /.tsx?$/, exclude: /node_modules/, use: [ "babel-loader", { loader: "ts-loader", options: { appendTsxSuffixTo: [/.vue$/] } } ] }, // 复制截止 { test: /.js$/, loader: "babel-loader", include: [resolve("src"), resolve("test")] },
上面的配置,主要意思是 vue 文件识别ts/tsx代码的时候,先过一遍ts-loader,在过一遍babel-loader,我知道这听起来有点蠢,但是jsx不能不要对吧?
然后在 tsconfig.json中,添加对jsx的支持
"compilerOptions": { "jsx": "preserve" }
之后就可以顺利在.vue单文件中的ts写jsx代码了,如下图所示:
支持es6 / es7敲黑板,这里又有重点,使用 jsx 写法的话, 一定要使用 .tsx,不要用.ts了,切记!!!
在 tsconfig.json中,添加对es6 / es7的支持,更多的配置请见tsconfig - 编译选项
"lib": [ "dom", "es5", "es6", "es7", "es2015.promise" ]
不然的话,连Object.assign 这种最基本的函数也会在ts中报错,真的令人难过
配置 vuex这里就比较简单了
# 安装依赖 npm i vuex vuex-class --save
vuex:在 vue 中集中管理应用状态
vuex-class :在 vue-class-component 写法中 绑定 vuex
Store的配置跟原来一模一样,引用的时候有一点区别,下面的例子介绍了用法,应该一看便知,这里我不做赘述
import Vue from "vue" import Component from "vue-class-component" import { State, Getter, Action, Mutation, namespace } from "vuex-class" const ModuleGetter = namespace("path/to/module", Getter) @Component export class MyComp extends Vue { @State("foo") stateFoo @State(state => state.bar) stateBar @Getter("foo") getterFoo @Action("foo") actionFoo @Mutation("foo") mutationFoo @ModuleGetter("foo") moduleGetterFoo // If the argument is omitted, use the property name // for each state/getter/action/mutation type @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"] } }让 vue 识别全局方法/变量
在项目中使用 ui 组件是很正常的操作
比如使用 Element-uI 的 meesage,用法如下图:
this.$message({ message: "恭喜你,这是一条成功消息", type: "success" })
但是在配置了 typescript之后
那是因为 $message属性,并没有在 vue实例中声明
解决办法也非常简单,那我们就声明一下呗
在之前文章中创建的 src/vue-shim.d.ts文件中,增加如下代码:
// 声明全局方法 declare module "vue/types/vue" { interface Vue { $Message: any, $Modal: any } }
这样,之后再使用this.$message()的话就不会报错了
支持 mixin我在vue-property-decorator里里外外找了好几圈,缺没有找到mixin这个修饰器
// 如果全局mixin,那也太蠢了 Vue.mixin( mixin )
找非常多的 ts + vue 项目,但是没有找到我理想的mixin的方式,
那么就自己进行探索咯,下图是我自己使用的目前最佳mixin方式:
声明了一个mixin组件,如下图:
其实就是我在mixin中声明了声明属性 / 方法,那么我就在vue实例中声明这个属性 / 方法
使用方式如下图:
支持 ProvidePlugin 的全局变量,比如 lodash 的 _如果我们在项目中有使用 jquery,lodash 这样的工具库的时候,肯定不希望在所有用到的地方都import _ from ‘lodash’
@types/lodash
那我们就来配置一下:
首先还是在webpack.base.conf.js 中添加一个插件、并把这个 vendor拉出来
entry: { app: "./src/main.ts", vendor: [ "lodash" ] } plugins: [ new webpack.ProvidePlugin({ _: "lodash" }) ]
上面的意思是,当模块使用这些变量的时候wepback会自动加载
然后,你需要告诉eslint这个 _ 是全局的
在.eslintrc.js中添加
globals: { _: true },
接下来,你还需要告诉ts这个 _ 是全局的
在vue-shim.d.ts
declare global { const _: typeof lodash }
如果没有上面这段声明,但是在 ts 中使用的话,会报如下的错误:
这个问题Consider allowing access to UMD globals from modules · Issue #10178 · Microsoft/TypeScript · GitHub
有一个很简单的解释,就是害怕你全局声明的_ 跟 import _ from "lodash" 的行为不一致,这样的话,之后会留下隐患
到这里,本文的配置就到此结束
最后本文的这些配置都是在新项目开发中,一步步用血汗踩出来的
目测已经涵盖了大部分的使用问题,如果有其他的意见或建议的话,欢迎在本文下面评论~~
再发一次,配置完整版可参考 vue-typescript-starter,若没配置出来,也可以对照修改配置
在刚上typescript的时候,我是拒绝的,嫌弃每个地方都要声明类型,不然就走不下去,但是如果让你们做以下一个选择题:
在编译时发现问题
还是运行时发现问题
我会毫不犹豫选择前者,这是ts强类型带给我最大的亮点
参考链接/推荐阅读tsconfig配置
TypeScript体系调研报告 - 掘金
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/89548.html
摘要:新项目起手式最后更新于,技术文具有时效性,请知悉我知道你们早就想用上强类型了还有后续进阶篇安装安装依赖配置添加添加让识别改造文件什么是是的强类型版本。是的超集,这意味着他支持所有的语法。与此同时,也是的超集,的也宣布采用进行开发。 vue + typescript 新项目起手式 最后更新于2018-06-30,技术文具有时效性,请知悉 我知道你们早就想用上 vue + ts 强类型...
阅读 2312·2021-11-22 12:01
阅读 1987·2021-11-12 10:34
阅读 4510·2021-09-22 15:47
阅读 2829·2019-08-30 15:56
阅读 2862·2019-08-30 15:53
阅读 2401·2019-08-30 13:53
阅读 3376·2019-08-29 15:35
阅读 3123·2019-08-29 12:27