Talk is cheap. Show me the code:
<template>
<span>{{ count }}</span>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component({})
export default class TsComp extends Vue {
count: any = undefined;
mgs = 123;
mounted() {
setTimeout(() => {
this.count = 10;
}, 1000);
}
}
</script>
上面的代码在我们运行中会出现
而我们期望的结果是页面显示10,但是却不会显示任何内容。经过排查发现:
data中并没有我们定义的变量,经过翻查vue的代码终于在vue-class-component中找到了答案
vue在处理ts组件的时候会使用@component这个装饰器,这个装饰器对代码进行了处理,下面来分析下component这个装饰器:
如何处理methods,hooks以及computed这里不做分析,有兴趣可以直接看源码,源码很清晰。我们主要分析如何把ts class中的成员变量处理成vue中的data的。
我们在代码中看到有个collectDataFromConstructor方法,这个方法中手动初始化要包装的类,目的是拿到初始化后的实例,我们在类中定义的成员属性可以通过实例获取到,循环遍历实例中的属性,但是有个重点是值为undefined的不会保留下来,也就是说值为undefined的属性不会添加到data中,故vue遍历data处理响应性的时候,就不会有值为undefined的属性,所以我们页面定义的属性不是响应式的。