JS组件
我们以前在一个vue组件的script标签里是使用JS语法的。以Type组件为例:
<script>
export default {
name: 'Type',
data(){
return{
type:'-', //'-'表示支出,'+'表示收入
}
},
methods:{
selectType(type){
if(type!=='-' && type!=='+'){
throw new Error('type不存在')
}
this.type=type
}
}
};
</script>
内部数据放在data里,函数放在methods里,然后导出这个对象。
TS组件
npm info typescript version //查看最新版本
如果使用TS语法:
<script lang="ts">
import Vue from 'vue';
import {Component} from 'vue-property-decorator';
@Component
export default class Type extends Vue {
type = '-'; //data可以省略
selectType(type:string) { //methods可以省略
if (type !== '-' && type !== '+') {
throw new Error('type不存在');
}
this.type = type;
}
}
}
</script>
默认导出一个class,继承Vue。里边如果是内部数据data,可以直接写成赋值语句。如果是methods里的方法,也可以直接写该函数形式。
然后在外边使用@Component,它是从'vue-property-decorator'这个装饰器里导入的,它可以自动识别data,methods等。
与JS语法不同的:
1.数据类型
selectType函数的参数type,要注明是什么数据类型,而JS里就不需要。
2. props
vue-property-decorator里的外部数据的写法:
export default class Type extends Vue {
type = '-';
@Prop(Number) xxx: number | undefined;
}
@Prop表明后边是一个prop,而不是内部数据(Number)是告诉Vue,我这个数据是一个Number类型的。如果外边传进来的不是Number,就会报错。(运行时)xxx就是属性名number | undefined告诉TS这个数据的类型(编译时)
那么编译和运行有什么区别?
编译时,就是编译的时候。运行时,就是运行的时候。
如果外边传进来的不是Number,就是运行时的错误。会在浏览器报错。
如果我对这个xxx进行一些奇怪的操作,比如:console.log(this.xxx.yyy); 那么我在保存代码的时候会在终端报错,但是浏览器那边是没有报错的。这就是编译时发生了错误。因为写的是number | undefined,但是number和undefined都没有一个.yyy的方法或属性。
一般这两个位置写的一样就可以了。后边的|undefined是必须写的,表示有可能是undefined。如果不写,没有传值时候的xxx就是没有值的,它就是undefined。
并且,由于要写他可能是undefined,之后在使用这个属性的任何时候,都要判断它是不是undefined,如果是,就...。
比如:@Prop(String) xxx: string| undefined;,传一个字符串。外边传的也是字符串。
mounted(){
if(this.xxx !==undefined){
console.log(this.xxx.length);
}
}
如果不加判断,直接打印,在运行时,也就是终端,会报错:
如果不想判断undefined,就只能在定义的时候给一个初始值,
@Prop(Number) xxx=0;
TS的本质其实就是在JS后加:类型的语法,作用就是检查类型对错。
总结
写 Vue 组件的三种方式(单文件组件)
- 用 JS 对象
export default { data, props, methods, created, ...} - 用 TS 类
<script lang="ts">@Component export default class XXX extends Vue{ xxx: string = 'hi'; @Prop(Number) xxx: number|undefined; } - 用 JS 类
<script lang="js">@Component export default class XXX extends Vue{ xxx = 'hi' }