Vue + TypeScript
*.d.ts
*.d.ts类型文件不需要手动引入,TypeScript会自动加载。TypeScript 默认只识别 *.ts 文件,不识别 *.vue 文件,因此需要告诉TypeScript*.vue文件交给vue编辑器来处理。
解决方案就是在创建一个vue-shims.d.ts文件:
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
vue装饰器
vue-class-component
强化 Vue 组件,使用 TypeScript/装饰器 增强 Vue 组件
vue-property-decorator
在 vue-class-component 上增强更多的结合 Vue 特性的装饰器。
vuex-class
基于vue-class-component对Vuex提供的装饰器。它的作者同时也是vue-class-component的主要贡献者,质量还是有保证的。
ts对vuex的支持不是很好。在TypeScript里面使用不了mapState、mapGetters等方法,只能一个变量一个变量的去引用,这个要麻烦不少。不过使用vuex-class库之后,写法上也还算简洁美观
export default class modules extends Vue {
@State login: boolean; // 对应this.$store.state.login
@State headline: StoreState.headline[]; // 对应this.$store.state.headline
private swiperOption: Object = {
autoplay: true,
loop: true,
direction: "vertical"
};
logoClick(): void {
alert("点我干嘛");
}
}
十万个为什么?
1. 引入/下载第三方库,为什么仍然提醒找不到?
TypeScript是模仿Node.js运行时的解析策略来在编译阶段定位模块定义文件。 因此,TypeScript在Node解析逻辑基础上增加了TypeScript源文件的扩展名( .ts,.tsx和.d.ts)。 同时,TypeScript在 package.json里使用字段"types"来表示类似"main"的意义 - 编译器会使用它来找到要使用的"main"定义文件。 ("typings"与"types"具有相同的意义,也可以使用它。同样要注意的是如果主声明文件名是index.d.ts并且位置在包的根目录里(与index.js并列),就不需要使用"types"属性指定了。)
比如,有一个导入语句import { b } from "./moduleB"在/root/src/moduleA.ts里,会以下面的流程来定位"./moduleB":
/root/src/moduleB.ts/root/src/moduleB.tsx/root/src/moduleB.d.ts/root/src/moduleB/package.json(如果指定了"types"属性)/root/src/moduleB/index.ts/root/src/moduleB/index.tsx/root/src/moduleB/index.d.ts
回想一下Node.js先查找moduleB.js文件,然后是合适的package.json,再之后是index.js。
类似地,非相对的导入会遵循Node.js的解析逻辑,首先查找文件,然后是合适的文件夹。 因此 /root/src/moduleA.ts文件里的import { b } from "moduleB"会以下面的查找顺序解析:
/root/src/node_modules/moduleB.ts/root/src/node_modules/moduleB.tsx/root/src/node_modules/moduleB.d.ts/root/src/node_modules/moduleB/package.json(如果指定了"types"属性)/root/src/node_modules/moduleB/index.ts/root/src/node_modules/moduleB/index.tsx/root/src/node_modules/moduleB/index.d.ts/root/node_modules/moduleB.ts/root/node_modules/moduleB.tsx/root/node_modules/moduleB.d.ts/root/node_modules/moduleB/package.json(如果指定了"types"属性)/root/node_modules/moduleB/index.ts/root/node_modules/moduleB/index.tsx/root/node_modules/moduleB/index.d.ts/node_modules/moduleB.ts/node_modules/moduleB.tsx/node_modules/moduleB.d.ts/node_modules/moduleB/package.json(如果指定了"types"属性)/node_modules/moduleB/index.ts/node_modules/moduleB/index.tsx/node_modules/moduleB/index.d.ts
因此,若是有些库没有提供typescript的声明,需要使用者手动去添加。
即在src/typings目前下建一个tools.d.ts文件,声明这个模块即可
declare module 'vue-lazyload'
2. prop为什么一直都是undefined?
必须要使用vue-class-component而不是vue-property-decorator的Component。
import Component from "vue-class-component";
import { Prop, Vue, Watch } from "vue-property-decorator";
后来排查问题,发现是因为我使用了两个装饰器的“合并写法”(即错误写法)

正确的写法:


3. prop的默认值是空对象为什么始终不起效?
大括号在js中是块作用域,因此会产生歧义,是块作用域呢还是返回空对象呢。因此,需要包一层小括号。像数组之类的就不会有歧义了,因此可以直接返回。
// 错误
@Prop({
default: () => {}
})
private value!: any;
// 正确
@Prop({
default: () => ({})
})
private value!: any;
4. 为什么import vue组件时,一切都对的,就是cannot find module?
5. 为什么申明了一个接口类型,但是还是报错Cannot find name?
即使声明文件不需要导出任何东西,仍然需要导出一个空对象,用来告诉编译器这是一个模块的声明文件,而不是一个全局变量的声明文件。