使用typescript构建Vue应用
<h2 id="articleHeader1">一、vue项目初始化-引入typescript</h2><p>使用typescript构建vue应用和使用js一样,都是通过vue-cli去初始化并创建一个vue项目,只不过使用typescript构建的时候<strong>要在脚手架问卷操作的时候勾选上typescript选项</strong>。 </p>
<p> </p>
<h2 id="articleHeader2">二、typescript Vue项目比较</h2>
<p>使用typescript构建的Vue项目发生了一些变化:<br><strong>①</strong> main.js变成了main.ts,但是<strong>main.ts中的内容和main.js的内容是一模一样的</strong>。<br><strong>②</strong> router.js变成了router.ts,但是<strong>router.ts中的内容和router.js中的内容也是一模一样的</strong>。<br><strong>③</strong> store.js变成了store.ts,但是<strong>store.ts中的内容和store.ts中的内容也是一模一样的</strong>。</p>
<blockquote>因为typescript是JavaScript的超集,所以<strong>ts完全兼容js</strong>。</blockquote>
<p><strong>④</strong> 新增了一个<strong>shims-vue.d.ts</strong>声明文件,这个文件的作用就是<strong>让typescript能够识别.vue文件,在引入"*.vue"文件的时候,会将其标识为一个Vue组件,才能对.vue文件进行类型校验</strong>,其具体内容如下:</p>
<pre><code class="hljs javascript">declare <span class="hljs-built_in">module <span class="hljs-string">'*.vue' {
<span class="hljs-keyword">import Vue <span class="hljs-keyword">from <span class="hljs-string">'vue'
<span class="hljs-keyword">export <span class="hljs-keyword">default Vue
}</span></span></span></span></span></span></span></code></pre>
<p><strong>⑤</strong> 新增了一个<strong>shims-tsx.d.ts</strong>文件,其作用就是<strong>为了能够解析.tsx文件,对.tsx文件进行类型校验</strong>,其具体内容如下:</p>
<pre><code class="hljs php">import Vue, { VNode } from <span class="hljs-string">'vue'
<span class="hljs-keyword">declare <span class="hljs-keyword">global {
<span class="hljs-keyword">namespace <span class="hljs-title">JSX {
<span class="hljs-title">interface <span class="hljs-title">Element <span class="hljs-title">extends <span class="hljs-title">VNode {}
<span class="hljs-title">interface <span class="hljs-title">ElementClass <span class="hljs-title">extends <span class="hljs-title">Vue {}
<span class="hljs-title">interface <span class="hljs-title">IntrinsicElements {
[<span class="hljs-title">elem: <span class="hljs-title">string]: <span class="hljs-title">any
}
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><strong>⑥</strong> 当然还会新增一个<strong>ts.config</strong>文件,这个是typescript的配置文件,具体内容这里不作解释,请参考tsconfig文件详解</p>
<p> </p>
<h2 id="articleHeader3">三、.vue文件内容格式与写法</h2>
<blockquote>使用typescript来写Vue应用,最主要的就是.vue文件,.vue文件写法上与js有些不同并且<strong>新增了一些装饰器</strong>,接着一步一步分析。</blockquote>
<p><strong>①</strong> 虽然.vue文件的格式和写法上有了不同,但这不同<strong>只是<script></script>部分发生了变化</strong>,<template></template>和<style></style>和原来是一样的,一个最简单.vue文件仍然可以使用如下写法:<br>// HelloWorld.vue</p>
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">template>
<span class="hljs-tag"><<span class="hljs-tag"><span class="hljs-name">div</span></span><span class="hljs-tag">>
hello world
<span class="hljs-tag"></<span class="hljs-tag"><span class="hljs-name">div</span></span><span class="hljs-tag">>
<span class="hljs-tag"></<span class="hljs-name">template></span></span></span></span></span></span></span></span></code></pre>
<p><strong>②</strong> 在写<script></script>部分,第一点不同就是,<strong><script>标签上要加上lang语言属性</strong>,表示其中的内容为ts,如:</p>
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">script <span class="hljs-attr">lang=<span class="hljs-string">"ts"><span class="undefined">
<span class="hljs-tag"></<span class="hljs-name">script></span></span></span></span></span></span></span></code></pre>
<p><strong>③</strong> 默认export上的不同,使用js的时候,我们是直接通过export default {}导出一个Vue组件对象即可,但是使用ts的时候,我们<strong>必须导出一个类class,类名为组件名,同时这个类必须继承Vue</strong>,如:</p>
<pre><code class="hljs javascript"><span class="hljs-comment">// import Vue from "vue";
<span class="hljs-keyword">import { Component, Vue } <span class="hljs-keyword">from <span class="hljs-string">'vue-property-decorator'; <span class="hljs-comment">// 引入Vue及一些装饰器
@Component
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue { <span class="hljs-comment">// 继承Vue并导出Vue组件
}</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<blockquote>以上就是<sciprt>内容最基本的写法,上面继承的Vue不是直接从"vue"模块中引入,而是从"vue-property-decorator"即vue属性装饰器模块中引入,当然<strong>也可以通过vue模块引入import Vue from "vue"</strong>,但是我们写.vue文件的时候<strong>通常要引入一些装饰器</strong>,同时<strong>这个装饰器类vue-property-decorator也提供了Vue</strong>,故可以直接从vue-property-decorator装饰器类上直接引入</blockquote>
<p><strong>④</strong> 组件中data属性的写法,由于我们在.vue文件中声明了一个class,这个class就是Vue组件,我们可以<strong>直接在这个class中声明属性</strong>即可,这些声明的属性就是之前使用js写时的data属性中的数据,如:</p>
<pre><code class="hljs php">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue {
<span class="hljs-keyword">public lists = [ <span class="hljs-comment">// 这里就是之前Vue组件的data属性
<span class="hljs-string">"Vue.js", <span class="hljs-string">"<span class="hljs-string">react</span><span class="hljs-string">.js", <span class="hljs-string">"Angular.js"
]
}</span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><strong>⑤</strong> 组件中的computed计算属性的写法,同样我们可以<strong>在class中声明get和set方法即可变成对应的computed属性</strong>,如:</p>
<pre><code class="hljs php">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue {
<span class="hljs-keyword">public lists = [ <span class="hljs-comment">// 这里就是之前Vue组件的data属性
<span class="hljs-string">"Vue.js", <span class="hljs-string">"<span class="hljs-string">react</span><span class="hljs-string">.js", <span class="hljs-string">"Angular.js"
]
<span class="hljs-keyword">public get count() { <span class="hljs-comment">// 通过get和set实现计算属性
<span class="hljs-keyword">return this.lists.length;
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><strong>⑥</strong> 组件中方法的声明更简单,直接在class中声明方法即可,如:</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue {
public say() {
<span class="hljs-built_in">console.log(<span class="hljs-string">"say");
}
}</span></span></span></span></span></span></span></span></span></code></pre>
<p><strong>⑦</strong> @Component装饰器的使用,@Component装饰器就是用来<strong>标识当前这个类是一个Vue组件</strong>,@Component装饰器还可以<strong>传递对象</strong>作为参数,这个传递的对象就是Vue组件实例,所以<strong>所有之前用js写法的时候,Vue组件支持的所有选项都可以传入</strong>,如:</p>
<pre><code class="hljs javascript">@Component({
<span class="hljs-comment">// 这里可以配置Vue组件支持的各种选项
components: {
HelloWorld
},
data() {
<span class="hljs-keyword">return {
<span class="hljs-attr">a:<span class="hljs-number">1
}
},
<span class="hljs-attr">methods: {
say(){
<span class="hljs-built_in">console.log(<span class="hljs-string">"say");
}
}
})
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue {
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<blockquote>@Component内容使用的是<strong>Vue.extend()</strong>方法,用于扩展Vue Component并生成Vue组件,这里需要注意的就是,<strong>Vue最终会将class中定义的属性和@Component中定义的属性进行合并</strong>,如果二者中定义了同名的属性,那么<strong>class中的优先级更高</strong>,即class中定义的会覆盖掉@Component中定义的同名属性,但是<strong>data除外</strong>,<strong>@Component中定义的同名的data数据会覆盖掉class中定义的同名data属性</strong>,如:</blockquote>
<pre><code class="hljs javascript">@Component({
data() {
<span class="hljs-attr">bar: <span class="hljs-number">1
},
<span class="hljs-attr">methods: {
say(){
<span class="hljs-built_in">console.log(<span class="hljs-string">"say::@Component");
}
}
})
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue {
public bar: number = <span class="hljs-number">2; <span class="hljs-comment">// 这里的bar会被@Component中定义的bar覆盖掉
public say() { <span class="hljs-comment">// 这里的say()方法会覆盖掉@Component中定义的say方法
<span class="hljs-built_in">console.log(<span class="hljs-string">"say::class");
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<blockquote>还有一点要注意的是,<strong>@Component装饰器千万不要漏写,必须在组件类class前修饰</strong></blockquote>
<p><strong>⑧</strong> props属性的写法,使用ts写Vue组件的时候,如果要在组件上定义props属性,那么<strong>必须通过@Prop()装饰器</strong>,其实就是在定义组件data属性的时候用@Prop()装饰器进行修饰,<strong>如果没有通过@Propp()进行修饰,那么定义的属性就是组件的data属性</strong>,<strong>可以给@Prop()传递一个配置对象</strong>,可以定义传递属性的default、required、type等属性,如:</p>
<pre><code class="hljs php">import { Component, Vue, Prop } from <span class="hljs-string">'vue-property-decorator';
@Component <span class="hljs-comment">// 不要忘了用@Component修饰组件class哟
export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">HelloWorld <span class="hljs-keyword">extends <span class="hljs-title">Vue {
@Prop() <span class="hljs-keyword">public bar!: string; <span class="hljs-comment">// 这里定义的是props属性
<span class="hljs-keyword">public foo = <span class="hljs-string">"foo"; <span class="hljs-comment">// 这里定义的是data属性
@Prop({type: String, <span class="hljs-keyword">default:<span class="hljs-string">"foo", required: <span class="hljs-keyword">true}) <span class="hljs-keyword">public foo!: string;
}
</script></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<blockquote>需要注意的是,public foo!: string,<strong>这里声明的string类型是不起作用的</strong>,要限定父组件传入的foo属性的数据类型,<strong>必须在@Prop()装饰器内限定数据类型</strong>,否则无效</blockquote>
<p><strong>⑨</strong> @Emit()装饰器的使用,在子组件发射自定义事件的时候通常会通过this.$emit("say")的方式,但是typescript提供了一个@Emit()装饰器,用于<strong>修饰一个方法</strong>,当这个方法被执行的时候,<strong>就会在方法执行完成后发射一个同方法名的事件出去</strong>,当然,这是在没有给@Emit()传递参数的情况下,如果给@Emit()传递了参数,那么就会发射指定参数的事件,如:</p>
<pre><code class="hljs php">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">HelloWorld <span class="hljs-keyword">extends <span class="hljs-title">Vue {
@Emit()<span class="hljs-comment">// 在say()方法执行完成后会发射一个同方法名的say事件
<span class="hljs-keyword">public say() {
}
@Emit(<span class="hljs-string">"speak")<span class="hljs-comment">// 这里给@Emit()传递了参数,则会发射speak事件
<span class="hljs-keyword">public say() {
}
}</span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><strong>⑩</strong> @Watch()装饰器的使用,其拥有监听组件中数据的变化,就相当于$watch,需要给其传递一个字符串参数,表示其监听的是哪个数据的变化,如:</p>
<pre><code class="hljs javascript">@Watch(<span class="hljs-string">"foo") <span class="hljs-comment">// 监听this.foo的变化
public add(newValue: number, <span class="hljs-attr">oldValue: number) {
<span class="hljs-built_in">console.log(<span class="hljs-string">`newValue is <span class="hljs-subst">${newValue}, oldValue is <span class="hljs-subst">${oldValue}`);
}</span></span></span></span></span></span></span></code></pre>
<p><span style="position: relative; left: -100000px">资源搜索网站大全 https://www.renrenfan.com.cn</span> <span style="position: relative; left: -100000px">广州VI设计公司https://www.houdianzi.com</span></p>
<h2 id="articleHeader4">四、vuex中的变化</h2>
<p>vuex中的数据是存放在state属性上的,如果要限定state中数据的属性和类型,那么我们<strong>必须在创建store对象的时候定义一个接口限定一下数据类型</strong>,如:</p>
<pre><code class="hljs css"><span class="hljs-selector-tag">interface <span class="hljs-selector-tag">IState {
<span class="hljs-attribute">lists: string[]
}
<span class="hljs-selector-tag">export <span class="hljs-selector-tag">default <span class="hljs-selector-tag">new <span class="hljs-selector-tag">Vuex<span class="hljs-selector-class">.Store<<span class="hljs-selector-tag">IState>({
<span class="hljs-attribute">state: {
lists: [<span class="hljs-string">"vue"] // 定义了state的数据结构,必须要有lists属性,并且属性值为string[]
}
});</span></span></span></span></span></span></span></span></span></span></span></code></pre>
<blockquote>获取vuex中的数据时候,<strong>还是可以通过this.$store.state.lists获取到</strong>,但是我们也可以通过装饰器获取到,要使用<strong>vuex的装饰器</strong>,我们需要安装<strong>vuex-class</strong>,如:</blockquote>
<pre><code class="hljs javascript"><span class="hljs-keyword">import {State, Mutation, Action} <span class="hljs-keyword">from <span class="hljs-string">"vuex-class";
<span class="hljs-keyword">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Vue {
<span class="hljs-comment">// 将从vuex中获取到的lists数据保存到组件的lists属性上
@State(<span class="hljs-string">"lists") public lists!: string[];
@Mutation(<span class="hljs-string">"say") <span class="hljs-comment">// 在say()方法前修饰,当say()方法执行的时候就会提交一个say mutation
public say() {
<span class="hljs-built_in">console.log(<span class="hljs-string">"say1");
}
@Action(<span class="hljs-string">"speak") <span class="hljs-comment">// 在speak()方法前修饰,当speak()方法执行的时候就会提交一个speak action
public speak(){
}
public mounted () {
<span class="hljs-keyword">this.say();
<span class="hljs-keyword">this.speak();
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre><br><br>
来源:https://www.cnblogs.com/xiaonian8/p/14102175.html
頁:
[1]