本文是继 Vue + TypeScript 新项目起手式 以后的进阶 + 踩坑配置,因此推荐先阅读前文 javascript
完整阅读完以后,基本能够顺利在新项目中使用
vue
+typescript
了 html另外特别注意!!! vue
不推荐在已有项目上强加
typescript
, 因ts写法的组件跟以前的组件不兼容,若上的话须要修改以前写的组件 java
配置完整版可参考 vue-typescript-starter,若没配置出来,也能够对照修改配置node
直接进入正题:jquery
ts
支持 render jsx
写法ts
支持 es6 / es67
vuex
vue
识别全局方法/变量mixin
ProvidePlugin
的全局变量,好比 lodash
的_
这里一共分两步webpack
vue
支持 jsx
写法vue
中的 ts
支持 jsx
写法按照官方作法,安装Babel 插件git
安装依赖es6
npm install\
babel-plugin-syntax-jsx\
babel-plugin-transform-vue-jsx\
babel-helper-vue-jsx-merge-props\
babel-preset-es2015\
--save-dev复制代码
在.babelrc
中添加:github
{
"plugins": ["transform-vue-jsx"]
}复制代码
以后就能够这些写render
,以下图:
首先配置 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
代码了,以下图所示:
敲黑板,这里又有重点,使用
jsx
写法的话, 必定要使用.tsx
,不要用.ts
了,切记!!!
在 tsconfig.json
中,添加对es6 / es7
的支持,更多的配置请见tsconfig - 编译选项
"lib": [
"dom",
"es5",
"es6",
"es7",
"es2015.promise"
]复制代码
否则的话,连Object.assign
这种最基本的函数也会在ts
中报错,真的使人难过
这里就比较简单了
# 安装依赖
npm i vuex vuex-class --save复制代码
vue
中集中管理应用状态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']
}
}复制代码
在项目中使用 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()的话就不会报错了
我在vue-property-decorator
里里外外找了好几圈,缺没有找到mixin
这个修饰器
// 若是全局mixin,那也太蠢了
Vue.mixin( mixin )复制代码
找很是多的 ts + vue
项目,可是没有找到我理想的mixin
的方式,
那么就本身进行探索咯,下图是我本身使用的目前最佳mixin
方式:
声明了一个mixin组件,以下图:
其实就是我在mixin
中声明了声明属性 / 方法,那么我就在vue
实例中声明这个属性 / 方法
使用方式以下图:
若是咱们在项目中有使用 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强类型带给我最大的亮点