自尤大去年9月推出vue对typescript的支持后,一直想开箱尝试,对于前端sr来说,vue的顺滑加上ts的面向对象,想着就非常美好~ 终于在两个月前,找到了个机会尝试了一把vue+ts的组合。 开文记录下vue和ts整合之旅和遇到的一些坑。

vue

应该大部分人都知道vue,毕竟如今vue是与react肩并肩的存在,所以就不过多介绍啦。

vue中文官网 官网上的教程就是最好的入门教程

typescript

我在前几篇文章就一直有在宣传typescript,简单列举下ts的优点

  1. 始于JavaScript,归于JavaScript,typescript是JavaScript的超集,所以它可以重用JavaScriptd代码,使用JavaScript的库

  2. JavaScript用的优点它都有,跨浏览器、跨操作系统等

  3. 面向对象的编程思想,强大的类型检查

  4. 开源大法好

要说缺点的话,那就是不太适合太小的项目。

就凭这些优点,足够我们愉快的玩耍~

ts安装

先将node安装,然后在通过npm安装ts的包

npm install -g typescript

tsc -v 查看ts的版本号

创建项目

我们将通过官方提供的脚手架 vue-cli 来创建项目

安装脚手架与创建项目

  1. 执行安装命令

npm install -g @vue/cli

安装完成后,可以通过 vue create 快速创建一个新项目的脚手架,或者直接通过 vue serve 构建新想法的原型。

  1. 创建项目 vue create vue-ts vue-ts是我们的项目名称,执行后如下

可看到有这么几个选项,xiaoli这个选项是我之前创建的,稍后会介绍;default这个后面写着 babel eslint ,表示若选择这个,那么只会引入babel和 ealint;manually select features顾名思义,选择我们想要的。那么我们选择第三个

可看到列表里有很多选项,我们以vue+ts为主,所以我们选择 babel typescript router vuex 这几个,选择完后,如下

接下来会有好几个yes or no 的选项,大家根据自己项目的需要来选择就可以,最后一步,Save this as a preset for future projects? 若选择yes,就会将我们之前的选择存储起来,作为一个预设选项,方便后续一键创建新项目。所有步骤选完,回车,便开始创建项目文件结构和拉取npm包

项目结构

项目结构如下

public: 用于存放静态文件,index.html入口文件就放在里面,这个文件夹下的文件不会纳入webpack的打包中;

src:存放vue项目工程文件,其中已经帮我们关联好router和vuex,文件结构非常简洁

其他:webpack、babel等配置文件

与typescript服用

项目在构建中,已经引入 vue-class-component ,用于对ts的支持,或者使用 vue-property-decorator,这个库是在之前那个的基础上扩展。

以下列举tsvue写法的各种变化

组件声明

创建组件的方式变成如下

import { Component, Prop, Vue, Watch } from 'vue-property-decorator';

@Component
export default class Test extends Vue { }
复制代码

data对象

通过构造函数创建data里的数据

import { Component, Prop, Vue, Watch } from 'vue-property-decorator';

@Component
export default class Test extends Vue {
private name: string;
constructor() {
super();
this.name = 'xiaoli';
}
}
复制代码

data里的数据使用方式如下

public getName(){
return this.name
}
复制代码

Prop声明

@Prop() public msg: string;
@Prop({ default: 'default value' }) propB: string
@Prop([String, Boolean]) propC: string | boolean
复制代码

生命周期函数使用

public created(): void {
console.log('created');
} public mounted():void{
console.log('mounted')
}
复制代码

自定义方法

js下是需要在method对象中声明方法,现变成如下

public clickFunc(): void {
console.log(this.name)
console.log(this.msg)
}
复制代码

Watch监听属性

@Watch('name',{ immediate: true, deep: true })
public onChildChanged(val: string, oldVal: string) {
console.log('watch new name=' + val);
}
复制代码

computed计算属性

public get allname() {
return 'computed ' + this.name;
}
复制代码

allname是计算后的值,name是被监听的值

emit事件

@Emit()
addToCount(n: number) {
this.count += n
} @Emit('reset')
resetCount() {
this.count = 0
}
复制代码

第一个的事件名称为 add-to-count,n为传过去的参数;第二个事件名为reset-count,参数为空

指令和过滤器

----------小小更新一下---------------

有小伙伴问指令和过滤器在ts下的写法,之前给遗漏了,现在补充一下。

我尝试了下,发现之前在入口文件直接引入指令或者过滤器的方式不管用了,因为用了ts后,组件的作用域跟之前的不一样了,然后我找了官方的issue,截图如下

在作者在4月11号回复里,承认了这个问题,但具体什么时候将指令和过滤器的声明加上就未知了,不过作者在issue中给出了解决方案。我写个简单的小栗子

一个自定义指令

// ./directive/index.ts
export const focus = {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el:HTMLElement) {
// 聚焦元素
el.focus()
}
}
复制代码

一个过滤器

// ./filter/index.ts
export const capitalize = function (value:string) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
复制代码

组件中使用

import { capitalize }from '@/filter/index'
import { focus } from '@/directive/index'
@Component({
filters:{capitalize},
directives:{focus}
})
export default class Test extends Vue {}
复制代码
<div>
<input v-focus v-model="modelData">
<div>{{modelData | capitalize}}</div>
</div>
复制代码

可看出这是局部引用,全局引用目前还没找到办法,欢迎有解决办法的小伙伴指教~

vuex与ts的糅合

因为vuex是个可选的,所以单独列出来。首先需要引用 vuex-class 库,该库有如下几个模块

import {
namespace,
Action,
Getter,
Mutation,
State
} from 'vuex-class';
复制代码

分别对应vuex中的 action、getter、mutation等,使用ts对vuex的影响主要在组件对vuex的调用上,vuex的定义还是按照之前的写法即可

@State('foo') stateFoo
@State(state => state.bar) stateBar
@Getter('foo') getterFoo
@Action('foo') actionFoo
@Mutation('foo') mutationFoo
@someModule.Getter('foo') moduleGetterFoo // If the argument is omitted, use the property name
// for each state/getter/action/mutation type
@State foo
@Getter bar
@Action baz
@Mutation qux
复制代码

若不想使用vuex定义的方法名,可以自定义属性名,因为都是定义在当前this上,所以直接使用this调用即可

this.getterFoo // -> store.getters.foo
this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
复制代码

小结

搭建完成后,就可以像后端一样撸前端啦~

作者:小黎也
链接:https://juejin.im/post/5ba75b355188255c5e66e4d3
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

教你搭建基于typescript的vue项目的更多相关文章

  1. 基于Typescript的Vue项目配置国际化

    基于Typescript的Vue项目配置国际化 简介 使用vue-i18n插件对基于Typescript的vue项目配置国际化,切换多种语言, 配合element-ui或者其他UI库 本文以配置中英文 ...

  2. 如何在ASP.NET 5上搭建基于TypeScript的Angular2项目

    一.前言 就在上月,公司的一个同事建议当前的前端全面改用AngularJs进行开发,而我们采用的就是ASP.NET 5项目,原本我的计划是采用TypeScript直接进行Angular2开发.所以借用 ...

  3. 手把手教你搭建规范的团队vue项目,包含commitlint,eslint,prettier,husky,commitizen等等

    目录 1,前言 2,创建项目 2,安装vue全家桶 3,配置prettier 4,配置eslint 5,配置husky + git钩子 6,配置commitlint 6.1,配置commitlint格 ...

  4. 解决基于TypeScript 的 RN项目相对路径引入组件的问题

    一.前言 在开发RN项目时,经常会要使用这样的方式(../../../)来引入组件,感觉非常繁琐,如果项目结构层级比较多,引入的头部更加分不清. 那有没有一种方案和vue项目一样,经过配置后简写路径, ...

  5. 庐山真面目之十一微服务架构手把手教你搭建基于Jenkins的企业级CI/CD环境

    庐山真面目之十一微服务架构手把手教你搭建基于Jenkins的企业级CI/CD环境 一.介绍 说起微服务架构来,有一个环节是少不了的,那就是CI/CD持续集成的环境.当然,搭建CI/CD环境的工具很多, ...

  6. 从零搭建基于webpack的Electron-Vue3项目(1)——基于webpack的Vue3项目搭建

    从零搭建基于webpack的Electron-Vue3项目(1)--基于webpack的Vue3项目搭建 前言 本篇文章内容,主要是基于webpack的Vue3项目开发环境进行搭建,暂时还不涉及到El ...

  7. TypeScript编写Vue项目结构解析

    使用TypeScript编写Vue项目也已经有了一段时间,笔者在刚刚使用TypeScript时候也是很茫然,不知道从何下手,感觉使用TypeScript写项目感觉很累赘并不像JavaScript那么灵 ...

  8. vue cli4构建基于typescript的vue组件并发布到npm

    基于vue cli创建一个vue项目 首先安装最新的vue cli脚手架, npm install --global @vue/cli npm WARN optional SKIPPING OPTIO ...

  9. Vue-cli安装步骤,搭建一个完整的 Vue 项目

    安装node环境下载 node.js 官网地址:https://nodejs.org/en/ 下载完成后打开然后一路next安装完成后打开 dos 窗口输入命令:node -v 回车会输出node的版 ...

随机推荐

  1. LocalDateTime自动转化格式

    开发中,遇到这样的问题.一个LocalDateTime类型的属性返回给前端是中间带T的格式,前端说转不了. 可以引入jackson包转换一下 <properties> <jackso ...

  2. leetcode-easy-listnode-206 reverse linked list

    mycode   98.87 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x ...

  3. UVA 1025 -- A Spy in the Metro (DP)

     UVA 1025 -- A Spy in the Metro  题意:  一个间谍要从第一个车站到第n个车站去会见另一个,在是期间有n个车站,有来回的车站,让你在时间T内时到达n,并且等车时间最短, ...

  4. electron-Menu创建原生应用菜单和上下文菜单。

    当在MacOS.Windows.Linux中使用menu设置程序菜单时,会设置在各个程序窗体的顶层. Note: 如果没有在app中设置一个菜单,系统会自动生成一个默认菜单, 默认生成的菜单中包含了一 ...

  5. LDA(Latent Dirichlet Allocation)主题模型算法

    原文 LDA整体流程 先定义一些字母的含义: 文档集合D,topic集合T D中每个文档d看作一个单词序列< w1,w2,...,wn >,wi表示第i个单词,设d有n个单词.(LDA里面 ...

  6. hibernate必须的包下载以及各个包的作用

    hibernate必须的包(点击下载) 对应的入门级代码例子(点击下载) hibernate3.jar  hibernate核心包 commons-collections-2.1.1.jar  集合包 ...

  7. Activity 怎么和 Service 绑定,怎么在 Activity 中启动自己对应的 Service?

    Activity 通过 bindService(Intent service, ServiceConnection conn, int flags)跟 Service 进行绑定,当绑定成功的时候 Se ...

  8. 谈谈 Android 的优点和不足之处?

    优点:1.开放性,开源,免费,可定制2.挣脱运营商束缚3.丰富的硬件选择4.不受任何限制的开发商5.无缝结合的 Google 应用缺点:1.安全问题.隐私问题2.同质化严重3.运营商对 Android ...

  9. pandas分组运算(groupby)

    1. groupby() import pandas as pd df = pd.DataFrame([[1, 1, 2], [1, 2, 3], [2, 3, 4]], columns=[" ...

  10. 阶段3 2.Spring_03.Spring的 IOC 和 DI_7 spring中bean的细节之作用范围

    bean的作用范围调整. 我们的bean通常情况下都是一个单例的模式 Spring是否也知道这些都是单例 构造函数只走了一次.也就是spring这个对象默认情况就是单例的 scope属性 定义bean ...