本文的前提是您已经掌握了 Vue
和TS
,只是对两者结合还不太熟悉,使用jsx的方式会更友好
vue-property-decorator
提供了装饰器的能力
基本模板
<template>
<div class="hello">
<h1>{{ firstName }}</h1>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component<HelloWorld>({
name: 'HelloWorld',
})
export default class HelloWorld extends Vue {
public download() {}
firstName: string = 'xioadun';
private show: boolean = false;
private mounted() {}
}
</script>
export default class HelloWorld extends Vue
HelloWorld
也是对自身的类型定义
@Component<HelloWorld>({
name: 'HelloWorld',
})
把定义给到了@Component
装饰器,使它能像在类里面使用this
不然尽管代码运行正常,在TS里还是会报错的
例如 "Property 'firstName' does not exist on type 'Vue' "
template与修饰符
这时候你在mounted
方法中
已经可以得到提示了
想要在
tempale
的得到提示和约束,需要安装Vetur
,并在settings.json
中添加
"vetur.experimental.templateInterpolationService": true,
这需要class里属性的修饰符不是
private
,mounted
这种从开发的角度上不会给外面提供,用public
修饰的,则类似是this.$refs
这种访问
可惜的是,class里面实现不了这样的效果,只能看控制台了。
Vue语法
@prop
只负责提供默认值和是否必须这种语义化的东西,
@Prop({ default: () => [] }) list: string[];
计算属性
通过get
、set
的方式
get name() {
return this.firstName + this.lastName;
}
refs
<Master ref="master" />
export default class App extends Vue {
$refs: {
master: Master;
};
}
要比@ref
直观的多
如果是第三方组件您可能会遇见如下错误(2020/02/07)
Type 'typeof ***' is not assignable to type 'VueConstructor<Vue>
| AsyncComponentPromise<any, any, any, any>
| AsyncComponentFactory<any, any, any, any> | FunctionalComponentOptions<...> | ComponentOptions<...>'.
Type 'typeof ***' is not assignable to type 'VueConstructor<Vue>'.
Types of parameters 'options' and 'options' are incompatible.
自定义的接口要继承Vue
export interface IPreviewer extends Vue {
show: (index: number) => void;
}
看$refs的声明
readonly $refs: { [key: string]: Vue | Element | Vue[] | Element[] };
扩展Vue的原型
Vue自身设计的思路,想避免挂载到原型上这种操作,也不是很现实,你想这样访问的话
this.$route.push();
首先打开,shims-vue.d.ts 这个文件,默认是这样样子的
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
添加自定义的
import Vue from 'vue';
declare module '*.vue' {
export default Vue;
}
declare module 'vue/types/vue' {
interface Vue {
$logger: {
emit: (
data:
| { eventName: 'click'; data: { timestmp: string } }
| { eventName: 'scan'; data: { duration: number } },
) => void;
};
}
}
本文将持续更新
关注专题 前端便利店 https://www.jianshu.com/c/c3f77a86d9a5 ,帮您省时省力!