资讯专栏INFORMATION COLUMN

vue + typescript 进阶篇

lemanli / 359人阅读

摘要:进阶篇本文是继新项目起手式之后的进阶踩坑配置,所以推荐先行阅读前文完整阅读完之后,基本可以顺利在新项目中使用了另外特别注意不推荐在已有项目上强加,因写法的组件跟之前的组件不兼容,若上的话需要修改之前写的组件配置完整版可参考,若没配置出来

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单文件中的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

  // 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-uImeesage,用法如下图:

  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

相关文章

  • 前端进阶资源整理

    摘要:前端进阶进阶构建项目一配置最佳实践状态管理之痛点分析与改良开发中所谓状态浅析从时间旅行的乌托邦,看状态管理的设计误区使用更好地处理数据爱彼迎房源详情页中的性能优化从零开始,在中构建时间旅行式调试用轻松管理复杂状态如何把业务逻辑这个故事讲好和 前端进阶 webpack webpack进阶构建项目(一) Webpack 4 配置最佳实践 react Redux状态管理之痛点、分析与...

    BlackMass 评论0 收藏0
  • vue + typescript 项目起手式

    摘要:新项目起手式最后更新于,技术文具有时效性,请知悉我知道你们早就想用上强类型了还有后续进阶篇安装安装依赖配置添加添加让识别改造文件什么是是的强类型版本。是的超集,这意味着他支持所有的语法。与此同时,也是的超集,的也宣布采用进行开发。 vue + typescript 新项目起手式 最后更新于2018-06-30,技术文具有时效性,请知悉 我知道你们早就想用上 vue + ts 强类型...

    zhisheng 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    jsbintask 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    ?xiaoxiao, 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    muddyway 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<