Vue学习(四)之TypeScript重构

参考资料

typescript文档

TypeScript基础

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript

  • 概念:TypeScript 是 JavaScript 的一个超集;设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上;TypeScript 通过类型注解提供编译时的静态类型检查
    TypeScript集

  • 主要优点

    • 静态检查:静态类型检查可以避免很多不必要的错误, 不用在调试的时候才发现问题;IDE 智能提示;类型推断;非空判断
    • 面向对象编程增强:接口;泛型;
    • 模块系统增强:命名空间
    • 代码可维护性:有了强类型约束和静态检查,以及智能IDE的帮助下,可以降低软件腐化的速度,提升可维护性,且在重构时提高效率
    • 运行时稳定性
  • 语法基础
    • 基本类型:
      • boolean
      • number
      • string
      • 数组:eg. number[] or Array<元素类型>
      • 元组:元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同 eg. [string, number]
      • 枚举:eg.enum Color {Red, Green, Blue}
      • any:在编程阶段还不清楚类型的变量指定一个类型
      • void:它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void
      • Null 和 Undefined
      • object
      • never
    • 类型断言:假设我们能确保某值是哪个类型,“尖括号”语法/as语法
    • 装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入

项目重构

项目环境:Vue 2.0 + node 10.13.0
目标:配置Vue2.0环境下支持ts和tsx语法

  • vue-cli安装vue
  • 添加包
    yarn add ts-loader tslint tslint-config-standard tslint-loader typescript
    yarn add vue-tsx-support
    yarn add vue-class-component vue-property-decorator
    yarn add babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx  babel-helper-vue-jsx-merge-props
    
  • 将src项目下的js文件改成ts文件
  • 在项目根目录下的tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项,我自定义配置如下:(更多)
    // tsconfig.json
    {
    "include": [
      "src/**/*"
    ],
    "exclude": [
      "node_modules"
    ],
    "compilerOptions": {
      // 允许从没有设置默认导出的模块中默认导入
      "allowSyntheticDefaultImports": true,
      // 启用装饰器
      "experimentalDecorators": true,
      // 允许js和jsx
      "allowJs": true,
      "jsx": "preserve",
      // 与 Vue 的浏览器支持保持一致
      "target": "es2017",
      // 这可以对 `this` 上的数据属性进行更严格的推断
      "strict": true,
      "noImplicitThis": false,
      "noImplicitReturns": true,
      "noImplicitAny":true,
      // 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake:
      "module": "esnext",
      "moduleResolution": "node",
      "baseUrl": "src",
      "lib": [
        "dom",
        "es5",
        "es6",
        "es7",
        "es2015.promise",
        "scripthost"
      ]
    }
    }
    
  • 在项目根目录下的tslint.json配置tslint语法检测
    {
    "extends": "tslint-config-standard",
    "globals": {
      "require": true
    },
    "rules": {
      "no-consecutive-blank-lines": false,
      "space-before-function-paren": false
    }
    }
    
  • 配置项目根目录下的.babelrc
    {
    "presets": [
      ["env", {
        "modules": false,
        "targets": {
          "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
        }
      }],
      "stage-2"
    ],
    "plugins": [
      "transform-vue-jsx",
      "transform-runtime"
    ]
    }
    
  • 配置ts支持识别*.vue模块导入,在src文件夹下添加文件vue-shim.d.ts
    declare module "*.vue" {
    import Vue from "vue";
    export default Vue;
    }
    
  • 配置支持tsx语法,在react中有@type/react@type/react-dom,在vue中需要导入vue-tsx-support,解决JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.问题
    //可以在单个文件引入,也可以在全局main.ts引入
    import 'vue-tsx-support/enable-check'
    
  • 配置build/webpack.base.conf.js
    // 修改rewsolve
    resolve: {
    extensions: ['.js', '.vue', '.json','.ts','.tsx', 'jsx'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'assets': resolve('src/assets'),
      'components': resolve('src/components'),
      'router': resolve('src/router'),
    }
    },
    // 修改webpack解析规则,支持ts/tsx
    {
    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|\.jsx$/,
    loader: 'babel-loader',
    include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
    },
    
  • 在单个组件中,需要显示定义script语言类型,比如:
    
    
    

    简单的组件示例

  • 示例1
    <script lang="tsx">
    import { CreateElement } from 'vue'
    import { Vue, Component } from 'vue-property-decorator'
    @Component
    export default class TestJSX extends Vue {
    render (h: CreateElement) {
      return (
        <div>tsx语法测试</div>
      )
    }
    }
    </script>
    
  • 示例2((更多语法)
    <script lang='ts'>
    import { CreateElement } from 'vue'
    import { Vue, Component, Prop } from 'vue-property-decorator'
    let getChildrenTextContent = function (children: any): String {
    return children
      .map(function (node: any) {
        return node.children ? getChildrenTextContent(node.children) : node.text
      })
      .join('')
    }
    @Component
    export default class AdvanceHead extends Vue {
    @Prop(Number) level!: number
    render (h: CreateElement) {
      let headingId = getChildrenTextContent(this.$slots.default)
        .toLowerCase()
        .replace(/\W+/g, '-')
        .replace(/(^-|-$)/g, '')
      return h('h' + this.level, [
        h(
          'a',
          {
            attrs: {
              name: headingId,
              href: 'javascript: void'
            }
          },
          this.$slots.default
        )
      ])
    }
    }
    </script>
    

 上一篇
知识图谱-从构建到呈现 知识图谱-从构建到呈现
参考资料 Apache Jena 基于 REfO 的 KBQA 实现及示例 知识图谱-给AI装个大脑 技术路线 构建实体概念 工具:Protégé 构建三元组数据库TDB 数据采集:爬虫基础(百度百科,去哪儿网,etc) Apach
2018-11-05
下一篇 
手动实现Vue的MVVM框架 手动实现Vue的MVVM框架
Vue源码是用TypeScript写的,本文采用ES6写法逐步实现MVVM框架,以理清双向绑定的过程。代码参考姜文老师的公开课 分析数据双向绑定的过程可以分成两个过程:① 数据变化渲染到页面;② 页面操作(input/textarea等
2018-10-25
  目录