使用typescript构建Vue应用的实现


Posted in Javascript onAugust 26, 2019

一、Vue项目初始化-引入typescript

使用typescript构建Vue应用和使用js一样,都是通过vue-cli去初始化并创建一个vue项目,只不过使用typescript构建的时候要在脚手架问卷操作的时候勾选上typescript选项。

二、typescript Vue项目比较

使用typescript构建的Vue项目发生了一些变化:
① main.js变成了main.ts,但是main.ts中的内容和main.js的内容是一模一样的。
② router.js变成了router.ts,但是router.ts中的内容和router.js中的内容也是一模一样的。
③ store.js变成了store.ts,但是store.ts中的内容和store.ts中的内容也是一模一样的。

因为typescript是javascript的超集,所以ts完全兼容js。

④ 新增了一个shims-vue.d.ts声明文件,这个文件的作用就是让typescript能够识别.vue文件,在引入"*.vue"文件的时候,会将其标识为一个Vue组件,才能对.vue文件进行类型校验,其具体内容如下:

declare module '*.vue' {
 import Vue from 'vue'
 export default Vue
}

⑤ 新增了一个shims-tsx.d.ts文件,其作用就是为了能够解析.tsx文件,对.tsx文件进行类型校验,其具体内容如下:

import Vue, { VNode } from 'vue'
declare global {
 namespace JSX {
  interface Element extends VNode {}
  interface ElementClass extends Vue {}
  interface IntrinsicElements {
   [elem: string]: any
  }
 }
}

⑥ 当然还会新增一个ts.config文件,这个是typescript的配置文件,具体内容这里不作解释,请参考tsconfig文件详解

三、.vue文件内容格式与写法

使用typescript来写Vue应用,最主要的就是.vue文件,.vue文件写法上与js有些不同并且新增了一些装饰器,接着一步一步分析。

① 虽然.vue文件的格式和写法上有了不同,但这不同只是<script></script>部分发生了变化,<template></template>和<style></style>和原来是一样的,一个最简单.vue文件仍然可以使用如下写法:

// HelloWorld.vue

<template>
  <div>
    hello world
  </div>
</template>

② 在写<script></script>部分,第一点不同就是,<script>标签上要加上lang语言属性,表示其中的内容为ts,如:

<script lang="ts">
</script>

③ 默认export上的不同,使用js的时候,我们是直接通过export default {}导出一个Vue组件对象即可,但是使用ts的时候,我们必须导出一个类class,类名为组件名,同时这个类必须继承Vue,如:

// import Vue from "vue";
import { Component, Vue } from 'vue-property-decorator'; // 引入Vue及一些装饰器
@Component
export default class App extends Vue { // 继承Vue并导出Vue组件

}

以上就是<sciprt>内容最基本的写法,上面继承的Vue不是直接从"vue"模块中引入,而是从"vue-property-decorator"即vue属性装饰器模块中引入,当然也可以通过vue模块引入import Vue from "vue",但是我们写.vue文件的时候通常要引入一些装饰器,同时这个装饰器类vue-property-decorator也提供了Vue,故可以直接从vue-property-decorator装饰器类上直接引入

④ 组件中data属性的写法,由于我们在.vue文件中声明了一个class,这个class就是Vue组件,我们可以直接在这个class中声明属性即可,这些声明的属性就是之前使用js写时的data属性中的数据,如:

export default class App extends Vue {
 public lists = [ // 这里就是之前Vue组件的data属性
  "Vue.js", "React.js", "Angular.js"
 ]
}

⑤ 组件中的computed计算属性的写法,同样我们可以在class中声明get和set方法即可变成对应的computed属性,如:

export default class App extends Vue {
 public lists = [ // 这里就是之前Vue组件的data属性
  "Vue.js", "React.js", "Angular.js"
 ]
 public get count() { // 通过get和set实现计算属性
  return this.lists.length;
 }
}

⑥ 组件中方法的声明更简单,直接在class中声明方法即可,如:

export default class App extends Vue {
  public say() {
    console.log("say");
  }
}

⑦ @Component装饰器的使用,@Component装饰器就是用来标识当前这个类是一个Vue组件,@Component装饰器还可以传递对象作为参数,这个传递的对象就是Vue组件实例,所以所有之前用js写法的时候,Vue组件支持的所有选项都可以传入,如:

@Component({
  // 这里可以配置Vue组件支持的各种选项
  components: {
    HelloWorld
  },
  data() {
    return {
     a:1
    }
  },
  methods: {
    say(){
     console.log("say");
    }
  }
})
export default class App extends Vue {
}

@Component内容使用的是Vue.extend()方法,用于扩展Vue Component并生成Vue组件,这里需要注意的就是,Vue最终会将class中定义的属性和@Component中定义的属性进行合并,如果二者中定义了同名的属性,那么class中的优先级更高,即class中定义的会覆盖掉@Component中定义的同名属性,但是data除外,@Component中定义的同名的data数据会覆盖掉class中定义的同名data属性,如:

@Component({
  data() {
    bar: 1
  },
  methods: {
    say(){
     console.log("say::@Component");
    }
  }
})
export default class App extends Vue {
  public bar: number = 2; // 这里的bar会被@Component中定义的bar覆盖掉
  public say() { // 这里的say()方法会覆盖掉@Component中定义的say方法
    console.log("say::class");
  }
}

还有一点要注意的是,@Component装饰器千万不要漏写,必须在组件类class前修饰

⑧ props属性的写法,使用ts写Vue组件的时候,如果要在组件上定义props属性,那么必须通过@Prop()装饰器,其实就是在定义组件data属性的时候用@Prop()装饰器进行修饰,如果没有通过@Propp()进行修饰,那么定义的属性就是组件的data属性,可以给@Prop()传递一个配置对象,可以定义传递属性的default、required、type等属性,如:

import { Component, Vue, Prop } from 'vue-property-decorator';
@Component // 不要忘了用@Component修饰组件class哟
export default class HelloWorld extends Vue {
  @Prop() public bar!: string; // 这里定义的是props属性
  public foo = "foo"; // 这里定义的是data属性
  @Prop({type: String, default:"foo", required: true}) public foo!: string;
}
</script>

需要注意的是,public foo!: string,这里声明的string类型是不起作用的,要限定父组件传入的foo属性的数据类型,必须在@Prop()装饰器内限定数据类型,否则无效

⑨ @Emit()装饰器的使用,在子组件发射自定义事件的时候通常会通过this.$emit("say")的方式,但是typescript提供了一个@Emit()装饰器,用于修饰一个方法,当这个方法被执行的时候,就会在方法执行完成后发射一个同方法名的事件出去,当然,这是在没有给@Emit()传递参数的情况下,如果给@Emit()传递了参数,那么就会发射指定参数的事件,如:

export default class HelloWorld extends Vue {
  @Emit() // 在say()方法执行完成后会发射一个同方法名的say事件
  public say() {
  }
  @Emit("speak") // 这里给@Emit()传递了参数,则会发射speak事件
  public say() {
  }
}

⑩ @Watch()装饰器的使用,其拥有监听组件中数据的变化,就相当于$watch,需要给其传递一个字符串参数,表示其监听的是哪个数据的变化,如:

@Watch("foo") // 监听this.foo的变化
public add(newValue: number, oldValue: number) {
 console.log(`newValue is ${newValue}, oldValue is ${oldValue}`);
}

四、vuex中的变化

vuex中的数据是存放在state属性上的,如果要限定state中数据的属性和类型,那么我们必须在创建store对象的时候定义一个接口限定一下数据类型,如:

interface IState {
 lists: string[]
}
export default new Vuex.Store<IState>({
  state: {
    lists: ["vue"] // 定义了state的数据结构,必须要有lists属性,并且属性值为string[]
  }
});

获取vuex中的数据时候,还是可以通过this.$store.state.lists获取到,但是我们也可以通过装饰器获取到,要使用vuex的装饰器,我们需要安装vuex-class,如:

import {State, Mutation, Action} from "vuex-class";
export default class App extends Vue {
  // 将从vuex中获取到的lists数据保存到组件的lists属性上
  @State("lists") public lists!: string[];
  @Mutation("say") // 在say()方法前修饰,当say()方法执行的时候就会提交一个say mutation
  public say() {
   console.log("say1");
  }
  @Action("speak") // 在speak()方法前修饰,当speak()方法执行的时候就会提交一个speak action
  public speak(){
  }
  public mounted () {
   this.say();
   this.speak();
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
ie下动态加态js文件的方法
Sep 13 Javascript
node.js超时timeout详解
Nov 26 Javascript
JavaScript中的数值范围介绍
Dec 29 Javascript
让JavaScript中setTimeout支持链式操作的方法
Jun 19 Javascript
跟我学习javascript解决异步编程异常方案
Nov 23 Javascript
Node.js Express 框架 POST方法详解
Jan 23 Javascript
jQuery html表格排序插件tablesorter使用方法详解
Feb 10 Javascript
vue组件如何被其他项目引用
Apr 13 Javascript
js绑定事件和解绑事件
Apr 27 Javascript
JS获取今天是本月第几周、本月共几周、本月有多少天、是今年的第几周、是今年的第几天的示例代码
Dec 05 Javascript
vue设计一个倒计时秒杀的组件详解
Apr 06 Javascript
vue-loader中引入模板预处理器的实现
Sep 04 Javascript
微信小程序实现手势滑动卡片效果
Aug 26 #Javascript
微信小程序实现左侧滑栏过程解析
Aug 26 #Javascript
vue柱状进度条图像的完美实现方案
Aug 26 #Javascript
React传值 组件传值 之间的关系详解
Aug 26 #Javascript
js实现指定时间倒计时效果
Aug 26 #Javascript
Vue.use()在new Vue() 之前使用的原因浅析
Aug 26 #Javascript
微信小程序事件 bindtap bindinput代码实例
Aug 26 #Javascript
You might like
DOMXML函数笔记
2006/10/09 PHP
PHP循环语句笔记(foreach,list)
2011/11/29 PHP
TMDPHP 模板引擎使用教程
2012/03/13 PHP
PHP制作登录异常ip检测功能的实例代码
2016/11/16 PHP
详谈php ip2long 出现负数的原因及解决方法
2017/04/05 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
JS中图片缓冲loading技术的实例代码
2013/08/29 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
js预加载图片方法汇总
2015/06/15 Javascript
Jquery ui datepicker设置日期范围,如只能隔3天【实现代码】
2016/05/04 Javascript
EasyUI Pagination 分页的两种做法小结
2016/07/09 Javascript
React Native实现简单的登录功能(推荐)
2016/09/19 Javascript
JavaScript实现倒计时跳转页面功能【实用】
2016/12/13 Javascript
js正则表达式惰性匹配和贪婪匹配用法分析
2016/12/26 Javascript
利用jquery正则表达式在页面验证url网址输入是否正确
2017/04/04 jQuery
vue中动态设置meta标签和title标签的方法
2018/07/11 Javascript
Nuxt配合Node在实际生产中的应用详解
2018/08/07 Javascript
VUE DOM加载后执行自定义事件的方法
2018/09/07 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
2019/11/17 Javascript
python OpenCV学习笔记之绘制直方图的方法
2018/02/08 Python
Python简单实现的代理服务器端口映射功能示例
2018/04/08 Python
Python机器学习库scikit-learn安装与基本使用教程
2018/06/25 Python
Python在字符串中处理html和xml的方法
2020/07/31 Python
html5 css3实例教程 一款html5和css3实现的小机器人走路动画
2014/10/20 HTML / CSS
浅析border-radius如何兼容IE
2016/04/19 HTML / CSS
植村秀美国官网:Shu Uemura美国
2019/03/19 全球购物
英超联赛的首选足球:Mitre足球
2019/05/06 全球购物
后进生转化工作制度
2014/01/17 职场文书
计算机科学系职业生涯规划书
2014/03/08 职场文书
公司副总经理岗位职责
2014/10/01 职场文书
2014年班务工作总结
2014/12/02 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
2015年库房工作总结
2015/04/30 职场文书
公司员工辞职信范文
2015/05/12 职场文书
法律讲堂观后感
2015/06/11 职场文书
初中教务主任竞聘演讲稿(范文)
2019/08/20 职场文书