Vue+TypeScript 入门小问题汇总

Vue + TypeScript

*.d.ts

*.d.ts类型文件不须要手动引入,TypeScript会自动加载。TypeScript 默认只识别 *.ts 文件,不识别 *.vue 文件,所以须要告诉TypeScript*.vue文件交给vue编辑器来处理。
解决方案就是在建立一个vue-shims.d.ts文件:vue

declare module '*.vue' {
  import Vue from 'vue'
  export default Vue
}
复制代码

vue装饰器

vue-class-component

强化 Vue 组件,使用 TypeScript/装饰器 加强 Vue 组件 node

vue-property-decorator

vue-class-component 上加强更多的结合 Vue 特性的装饰器。git

  • @Emit
  • @Inject
  • @Model
  • @Prop
  • @Provide
  • @Watch
  • @Component (从 vue-class-component 继承)

vuex-class

基于vue-class-component对Vuex提供的装饰器。它的做者同时也是vue-class-component的主要贡献者,质量仍是有保证的。
ts对vuex的支持不是很好。在TypeScript里面使用不了mapState、mapGetters等方法,只能一个变量一个变量的去引用,这个要麻烦很多。不过使用vuex-class库以后,写法上也还算简洁美观github

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"vuex

  • /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"会如下面的查找顺序解析:typescript

  • /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文件,声明这个模块便可json

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";
复制代码

后来排查问题,发现是由于我使用了两个装饰器的“合并写法”(即错误写法)
编辑器

image.png





正确的写法:
ide

image.png

image.png

3. prop的默认值是空对象为何始终不起效?

大括号在js中是块做用域,所以会产生歧义,是块做用域呢仍是返回空对象呢。所以,须要包一层小括号。像数组之类的就不会有歧义了,所以能够直接返回。

// 错误
@Prop({
    default: () => {}
  })
  private value!: any;

// 正确
@Prop({
    default: () => ({})
  })
  private value!: any;
复制代码

4. 为何import vue组件时,一切都对的,就是cannot find module?

必须带上后缀.vue!由于ts只认识.ts。

5. 为何申明了一个接口类型,可是仍是报错Cannot find name?

即便声明文件不须要导出任何东西,仍然须要导出一个空对象,用来告诉编译器这是一个模块的声明文件,而不是一个全局变量的声明文件。

相关文章
相关标签/搜索