深入使用TS

支持 render jsx 写法

这里一共分两步

  1. 首先得先让 vue 支持 jsx 写法

  2. 再让 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单文件中的tsjsx代码了,如下图所示:

敲黑板,这里又有重点,使用 jsx 写法的话, 一定要使用 .tsx,不要用.ts了,切记!!!

支持es6 / es7

在 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 // 如果省略了参数,使用属性名
// 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' 的行为不一致,这样的话,之后会留下隐患

最新文章

  1. Git 冲突合并
  2. location
  3. [jQuery]我的封装笔记
  4. ADDED_TO_STAGE 多次被调用
  5. 获取select下拉列表选中的值
  6. VMware虚拟机中调整Linux分区大小——使用gparted
  7. html+css3实现网页时钟
  8. BZOJ 3112 Zjoi2013 防守战线 单纯形
  9. 数据结构(三) 用java实现七种排序算法。
  10. CSS动画属性性能详细介绍
  11. Swift初始化空字符串
  12. bzoj 2303: [Apio2011]方格染色
  13. Linux 系统调用过程详细分析
  14. 面试题之python基础
  15. Power Designer 转C#实体类方法
  16. Scala:First Steps in Scala
  17. conductor任务域
  18. Windows本地Linux虚拟机ping不通的解决办法
  19. 【DataStructure】Some useful methods about linkedList.
  20. de4dot 用法

热门文章

  1. windows上pip安装及使用详解
  2. SpringBoot整合MyBatis的分页插件PageHelper
  3. \ n是将输出换行符的javascript的转义符。
  4. python WordCloud 实现词云
  5. Java注解【四、自定义注解】
  6. mysql之使用json
  7. malloc/calloc/realloc/alloca内存分配函数
  8. MySQL授权远程用户登录权限
  9. CNN for NLP
  10. sql 实现取表中相同id时间最大的一行 利用distinct on