前言

  恕我直言,用 Typescript 写 Vue 真的很难受,Vue 对 ts 的支持一般,如非万不得已还是别在 Vue 里边用吧,不过听说 Vue3 会增强对 ts 的支持,正式登场之前还是期待一下吧嘻嘻。

  本篇不会过多讲述 ts 语法,着重记录下 在 Vue 中使用 ts 的方法以及踩坑经过。

  如果是使用 Vue Cli2 搭建的项目,要注意 webpack 版本可能与 ts-loader 版本不匹配,可以降低 ts-loader 版本到 3.0+ 或者 将 webpack升级到 4.0+ (本篇所用版本 webpack@3.6.0 + ts-loader@3.5.0)

主要步骤

  1. 先要让 vue 项目可以识别 .ts 文件。安装关键依赖 npm i typescript ts-loader -D

  2. 在 webpack.base.config.js 中添加 ts-loader

//resolve.extensions 里面加上.ts 后缀 之后引入.ts的时候可以不写后缀
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/], //关键
}
}

  3. 在根目录建tsconfig.json文件 下面的配置仅供参考

{
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
],
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"allowJs": true,
"module": "esnext",
"target": "es5",
"moduleResolution": "node",
"isolatedModules": true,
"lib": [
"dom",
"es5",
"es2015.promise"
],
"sourceMap": true,
"pretty": true
}
}

  4. 接着需要确保在 vue 中可以正常使用 ts 。安装 vue-class-component(为vue组件提供修饰器) vue-property-decorator(更多的结合vue特性的修饰器) [ tslint tslint-loader tslint-config-standard(可选 约束.ts/.tsx代码格式)],这样就可以在 vue 文件中使用诸如 @Component、@Prop等装饰器了。注意:.vue 文件中的 script 标签要加上 lang="ts"。关于 装饰器的使用可以参看下这位大哥的文章:https://segmentfault.com/a/1190000019906321

<template>
<div class="count-down" v-html="countDown(endDate)">
</div>
</template> <script lang="ts">
import { Component, Prop, Vue, Emit } from "vue-property-decorator"
import moment from 'moment' @Component
export default class CountDown extends Vue {
@Prop() endDate!: string
// 变量后加!是非空断言 now: any = moment()
mounted() {
setInterval((): void =>{
this.now = moment()
},1000)
}
destroyed() { }
get countDown(): object{
return function(endDate: any): string {
let m1: any = this.now
let m2: any = moment(endDate)
let du: any = moment.duration(m2 - m1, 'ms')
let hours: number = du.get('hours')
let mins: number = du.get('minutes')
let ss: number = du.get('seconds')
if(hours <= 0 && mins <= 0 && ss <= 0) {
// this.$emit('timeout')
this.timeout()
return "今日已结束"
}else {
return `${this.PrefixInteger(hours,2)} <span style="font-size: 16px;">小时</span> ${this.PrefixInteger(mins,2)} <span style="font-size: 16px;">分钟</span><span style="color: #F56C6C;"> ${this.PrefixInteger(ss,2)} </span><span style="font-size: 16px;">秒</span>`
}
}
} @Emit()
timeout(){} //数字前补 0
// num传入的数字,n需要的字符长度
PrefixInteger(num: number, n: number): string {
return (Array(n).join('0') + num).slice(-n)
}
}
</script> <style lang="less" scoped>
//...
</style>

  5. 将main.js 变成 main.ts 并且在 webpack.base.conf.js 修改入口为main.ts,这一步至关重要。

  6. 在 src 目录下新建文件 shims-vue.d.ts ,告诉 TypeScript *.vue 后缀的文件可以交给 vue 模块来处理,注意 在代码中导入 *.vue 文件的时候,需要写上 .vue 后缀,这里可以参考官网说明:增强类型以配合插件使用

declare module "*.vue" {
import Vue from "vue";
export default Vue;
}

踩坑记录

  1. 报错如下,报错原因一是没有将入口文件改成 ts,二是 webpack.base.conf.js 中引入 ts-loader 错误,没有加上 options: { appendTsSuffixTo: [/\.vue$/], }

Module build failed: Error: Could not find source file: 'XXX/src/App.vue'.

  2. 全局属性报错 如 Vue.prototype.$msg = XXX,需要将全局属性在 .d.ts 文件中声明

import Vue from "vue";
import { AxiosInstance } from "axios";
import { ElMessage } from "element-ui/types/message"; declare module "*.vue" {
export default Vue;
} declare module 'vue/types/vue' {
interface Vue {
$http: AxiosInstance,
$message: ElMessage
}
}

  3. 使用上面这种声明全局属性的方式又会带来新的问题,报错 import App from './App.vue'处,找不到 App.vue 这个模块,虽然不影响编译,但是这红色的波浪线就像老鼠屎,看着那叫一个难受呀。解决方法:将 shims-vue.d.ts 文件一分为二,将全局属性声明和 Vue 的声明分离;在 shims-vue.d.ts 文件同级目录下新建 vue.d.ts(名字不一定叫 vue,如 xxx.d.ts 也可以);关键是要将以下代码放在单独的 .d.ts 文件中

declare module '*.vue' {
import Vue from 'vue'
export default Vue
}

在 Vue 中使用 Typescript的更多相关文章

  1. 在Vue 中使用Typescript

    Vue 中使用 typescript 什么是typescript typescript 为 javaScript的超集,这意味着它支持所有都JavaScript都语法.它很像JavaScript都强类 ...

  2. Vue 中使用 typescript

    Vue 中使用 typescript 什么是typescript typescript 为 javaScript的超集,这意味着它支持所有都JavaScript都语法.它很像JavaScript都强类 ...

  3. Vue 中使用 TypeScript axios 使用方式

    Vue 中使用 TypeScript axios 使用方式 方式一 import axios from 'axios'; Vue.prototype.$axios = axios; // 在 .vue ...

  4. Vue 中使用 TypeScript 详细总结

    VUE 项目中使用 Typescript 第一节:项目起步 Vue 中使用 TypeScript 项目中主要使用到的第三方依赖 vue2 vue-class-component vue-propert ...

  5. 在Vue中使用TypeScript

    TypeScript基础学习 初始化TS项目 Vue装饰器 vue-typescript-admin框架 1.TypeScript基础学习 2.初始化TS项目 3.Vue装饰器 Vue装饰器常用的有下 ...

  6. TypeScript基础以及在Vue中的应用

    TypeScript推出已经很长时间了,在Angular项目中开发比较普遍,随着Vue 3.0的即将推出,TypeScript在Vue项目中使用也即将成为很大的趋势,笔者也是最近才开始研究如何在Vue ...

  7. 如何在Vue项目中使用Typescript

    0.前言 本快速入门指南将会教你如何在Vue项目中使用TypeScript进行开发.本指南非常灵活,它可以将TypeScript集成到现有的Vue项目中任何一个阶段. 1.初始化项目 首先,创建一个新 ...

  8. Vue项目中应用TypeScript

    一.前言 与如何在React项目中应用TypeScript类似 在VUE项目中应用typescript,我们需要引入一个库vue-property-decorator, 其是基于vue-class-c ...

  9. 原有vue项目接入typescript

    原有vue项目接入typescript 为什么要接入typescript javascript由于自身的弱类型,使用起来非常灵活. 这也就为大型项目.多人协作开发埋下了很多隐患.如果是自己的私有业务倒 ...

随机推荐

  1. 用diiv实现多个方块居中嵌套--padding

    文章地址 https://www.cnblogs.com/sandraryan/ 案例:用diiv嵌套多个正方形,配合盒模型相关知识,使每个div在他的父元素上居中.(每个div中心点对齐) 涉及到m ...

  2. Array.from()类数组转化为数组的用法

    类数组对象转化为数组 let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }; let arr = Array.from(arrayLi ...

  3. Spring Data JPA查询指定列,并返回实体(改)

    现有PostEntiy实力,包含各种属性,如: /** * @Auther: DingShuo * @Date: 2018/7/18 11:09 * @Description: */ @Entity ...

  4. [转]vue - 前置工作 - 目录功能介绍

    一个DEMOS的完整目录(由于GWF问题,我就不一一打开网站一个个去搜索并且解释了)可以去关注:https://www.cnblogs.com/ye-hcj build build.js(本文来自ht ...

  5. P1105 数列

    题目描述 给定一个正整数 \(k(2 \le k \le 15)\) ,把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当 \(k = 3\) 时,这个序列是: 1,3,4, ...

  6. Mysql怎样控制replace替换的次数?

    我想把“ABC是ABC”替换成“123是ABC”,也就是找出第一个ABC替换成123,MYSQL命令应该怎么写? UPDATE data SET body=REPLACE(body, 'ABC', ' ...

  7. There is no PasswordEncoder mapped for the id "null"的解决办法

    今日在SpringBoot项目中使用 Spring Security ,登录时发现报500错,报错信息如下: There is no PasswordEncoder mapped for the id ...

  8. H3C DHCP服务器基本配置

  9. H3C VLAN配置示例

  10. I/O 寄存器和常规内存

    不管硬件寄存器和内存之间的强相似性, 存取 I/O 寄存器的程序员必须小心避免被 CPU(或者编译器)优化所戏弄, 它可能修改希望的 I/O 行为. I/O 寄存器和 RAM 的主要不同是 I/O 操 ...