Giter VIP home page Giter VIP logo

vue-typescript-dpapp-demo's Introduction

功能

  • 轮播
  • 搜索
  • 列表
  • 懒加载
  • 简单动画
  • loading
  • vue-router.ts
  • vuex.ts
  • vue-class-component使用
  • vuex-class使用
  • xxx.d.ts声明文件
  • 基于类的编写方式
  • mock数据
  • tsconfig.json
  • webpack配置
  • vue-typescript-cli

完成后的简单例子

基于类的写法加上静态类型检查,简直不能再嗨

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { State } from "vuex-class";

@Component
export default class Shops extends Vue {
  @State shops: StoreState.shop[];
  @State searchVal: string;

  get shopList(): StoreState.shop[] {
    const shops = this.shops;
    const searchVal = this.searchVal;
    return shops.filter(
      (el: StoreState.shop) => el.shopName.indexOf(searchVal) > -1
    );
  }
}
</script>

为什么使用TypeScript

1. JavaScript的超集

支持所有原生JavaScript的语法

2. 强类型语言

现在很多主流语言都是强类型的,而这点也一直是JavaScript所被人诟病的地方。使用TypeScript之后,将会在代码调试、重构等步骤节省很多时间。

比如说:函数在返回值的时候可能经过复杂的操作,那我们如果想要知道这个值的结构就需要去仔细阅读这段代码。那如果有了TypeScript之后,直接就可以看到函数的返回值结构,将会非常的方便

3. 强大的IDE支持

现在的主流编辑器如VSCodeWebStormAtomSublime等都对TypeScript有着非常友好的支持,主要体现在智能提示上,非常的方便

4. 可运行于任何浏览器、计算机、操作系统

强大的编译引擎

5. 迭代更新快

不断更新,提供更加方便友好的Api

6. 微软和Google爸爸

TypeScript是微软开发的语言,而Google的Angular使用的就是TypeScript,所以不用担心会停止维护,至少在近几年内TypeScript都会一门主流开发语言

7. npm下载量非常高

截止2017.12.17, TypeScript在全球范围内的npm日均下载量在30w左右,这个数字将近是vue下载量的10倍,可见TypeScript还是非常受欢迎的

Vue-TypeScript-Cli

官方虽然明确提出对TypeScript的支持,但是并没有明确的配置文档,自己在配置的时候还是需要查阅很多资料以及踩很多坑的(这个过程真的很蓝瘦-_-)

但是现在可以不用踩这个坑啦,我基于官方的vue-cli写了一个vue-typescript-cli,可以一键构建TypeScript模板

用法

vue init SimonZhangITer/vue-typescript-template <project-name>

比如

vue init SimonZhangITer/vue-typescript-template my-project

然后配置好的TypeScript模板就下载到./my-project文件夹了,npm run dev即可运行

TypeScript配置

这里记录一下当时的踩坑过程,所有配置已经在vue-typescript-template配置完毕

1. Webpack

安装ts-loader

首先需要安装ts-loader,这是TypeScript为Webpack提供的编译器,类似于babel-loader

npm i ts-loader -D

配置rules

接着在Webpack的module.rules里面添加对ts的支持(我这里的webpack版本是2.x):

{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: vueLoaderConfig
},
{
    test: /\.ts$/,
    loader: 'ts-loader',
    options: {
      appendTsSuffixTo: [/\.vue$/],
    }
}

配置extensions

添加可识别文件后缀对ts的支持,如:

extensions: ['.js', '.vue', '.json', '.ts']

2. tsconfig.json

创建tsconfig.json文件,放在根目录下,和package.json同级

配置内容主要也看个人需求,具体可以去typescript的官网查看,但是有一点需要注意:

在Vue中,你需要引入 strict: true (或者至少 noImplicitThis: true,这是 strict 模式的一部分) 以利用组件方法中 this 的类型检查,否则它会始终被看作 any 类型。

这里列出我的配置,功能在注释中给出

{
  "include": [
    "src/*",
    "src/**/*"
  ],
  "exclude": [
    "node_modules"
  ],
  "compilerOptions": {
    // types option has been previously configured
    "types": [
      // add node as an option
      "node"
    ],
    // typeRoots option has been previously configured
    "typeRoots": [
      // add path to @types
      "node_modules/@types"
    ],
    // 以严格模式解析
    "strict": true,
    // 在.tsx文件里支持JSX
    "jsx": "preserve",
    // 使用的JSX工厂函数
    "jsxFactory": "h",
    // 允许从没有设置默认导出的模块中默认导入
    "allowSyntheticDefaultImports": true,
    // 启用装饰器
    "experimentalDecorators": true,
    "strictFunctionTypes": false,
    // 允许编译javascript文件
    "allowJs": true,
    // 采用的模块系统
    "module": "esnext",
    // 编译输出目标 ES 版本
    "target": "es5",
    // 如何处理模块
    "moduleResolution": "node",
    // 在表达式和声明上有隐含的any类型时报错
    "noImplicitAny": true,
    "lib": [
      "dom",
      "es5",
      "es6",
      "es7",
      "es2015.promise"
    ],
    "sourceMap": true,
    "pretty": true
  }
}

3. 修改main.js

  1. 把项目主文件main.js修改成main.ts,里面的写法基本不变,但是有一点需要注意: 引入Vue文件的时候需要加上.vue后缀,否则编辑器识别不到

  2. 把webpack的entry文件也修改成main.ts

4. vue-shims.d.ts

TypeScript并不支持Vue文件,所以需要告诉TypeScript*.vue文件交给vue编辑器来处理。解决方案就是在创建一个vue-shims.d.ts文件,建议放在src目录下再创建一个typings文件夹,把这个声明文件放进去,如:src/typings/vue-shims.d.ts,文件内容:

*.d.ts类型文件不需要手动引入,TypeScript会自动加载

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

到这里TypeScript在Vue中配置就完成了,可以愉快的撸代码了~

第三方插件库

现在Vue官方已经明确提出支持TypeScript,并考虑出一个对应的vue-cli,在这之前,Vue开发团队已经开发出了一些插件库来支持TypeScript,这里简单和大家介绍一下。

Vue-Class-Component

vue-class-component是官方维护的TypeScript装饰器,写法比较扁平化。Vue对其做到完美兼容,如果你在声明组件时更喜欢基于类的 API,这个库一定不要错过

ps:用了这个装饰器之后写方法不需要额外加逗号,贼嗨~~~

import Vue from "vue";
import Component from "vue-class-component";

@Component
export default class App extends Vue {
  name:string = 'Simon Zhang'

  // computed
  get MyName():string {
    return `My name is ${this.name}`
  }

  // methods
  sayHello():void {
    alert(`Hello ${this.name}`)
  }

  mounted() {
    this.sayHello();
  }
}

这个代码如果用原生Vue语法来写的话就是这样:

export default {
  data () {
    return {
      name: 'Simon Zhang'
    }
  },

  mounted () {
    this.sayHello()
  },

  computed: {
    MyName() {
      return `My name is ${this.name}`
    }
  },

  methods: {
    sayHello() {
      alert(`Hello ${this.name}`)
    },
  }
}

Vuex-Class

vuex-class是基于基于vue-class-component对Vuex提供的装饰器。它的作者同时也是vue-class-component的主要贡献者,质量还是有保证的。

import Vue from "vue";
import Component from "vue-class-component";
import { State, Action, Getter } from "vuex-class";

@Component
export default class App extends Vue {
  name:string = 'Simon Zhang'
  @State login: boolean;
  @Action initAjax: () => void;
  @Getter load: boolean;

  get isLogin(): boolean {
    return this.login;
  }

  mounted() {
    this.initAjax();
  }
}

上面的代码就相当于:

export default {
  data() {
    return {
      name: 'Simon Zhang'
    }
  },

  mounted() {
    this.initAjax()
  },

  computed: {
    login() {
      return this.$store.state.login
    },
    load() {
      return this.$store.getters.load
    }
  },

  methods: {
    initAjax() {
      this.$store.dispatch('initAjax')
    }
  }
}

Vue-Property-Decorator

vue-property-decorator 是在 vue-class-component 上增强了更多的结合 Vue 特性的装饰器,新增了这 7 个装饰器

  • @Emit
  • @Inject
  • @Model
  • @Prop
  • @Provide
  • @Watch
  • @Component (从 vue-class-component 继承)

引入部分第三方库的时候需要额外声明文件

比如说我想引入vue-lazyload,虽然已经在本地安装,但是typescript还是提示找不到模块。原因是typescript是从node_modules/@types目录下去找模块声明,有些库并没有提供typescript的声明文件,所以就需要自己去添加

解决办法:在src/typings目前下建一个tools.d.ts文件,声明这个模块即可

declare module 'vue-awesome-swiper' {
  export const swiper: any
  export const swiperSlide: any
}

declare module 'vue-lazyload'

对vuex的支持不是很好

在TypeScript里面使用不了mapState、mapGetters等方法,只能一个变量一个变量的去引用,这个要麻烦不少。不过使用vuex-class库之后,写法上也还算简洁美观

export default class modules extends Vue {
  @State login: boolean; // 对应this.$store.state.login
  @State headline: StoreState.headline[]; // 对应this.$store.state.headline

  private swiperOption: Object = {
    autoplay: true,
    loop: true,
    direction: "vertical"
  };

  logoClick(): void {
    alert("点我干嘛");
  }
}

项目截图

总结

TypeScript还是非常值得学习和使用一个语言,还是有很多优点的

欢迎大家对我的项目提建议,欢迎Star~

QQ交流群:323743292

Build Setup

# 安装依赖
npm install

# 启动项目
npm run dev

# 打包项目
npm run build

vue-typescript-dpapp-demo's People

Contributors

dengshenkk avatar simonzhangiter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-typescript-dpapp-demo's Issues

单元测试

用 TS 重写以后,发现不能正常写单元测试了,官网上的那几个 demo 也跑不起来了。
不知 dalao 有什么想法?

npm run dev 报错

  • swiper/dist/css/swiper.css in ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!./src/components/modules.vue, ./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!./src/components/headline.vue

兼容ie9+

项目运行起来无法兼容ie9+ 自己搭建的项目一样无法兼容, 最近很困扰 请问有解决方案吗?

您好,启动就报错

TS1084: Invalid 'reference' directive syntax.

具体见截图:
image

是typescript版本问题吗?

请问引入组件的时候是怎么写alias的

import header from "@/components/header.vue";
import modules from "@/components/modules.vue";
import headline from "@/components/headline.vue";

我这么写的时候编辑器报错,找不到模块,必须要写成相对路径才可以

搭建vue-ts环境

首先非常感谢作者的demo,我想搭建ts-vue环境很久了,看过挺多的文章,按照他们的思路搭建出来的,根本都没法用.那个能不能请作者大大出个步骤,就是在原有的vue-cli的基础上,怎么搭建ts环境呢,需要安装哪些插件,修改哪些配置文件下面的项目来适应ts的环境.再次感谢作者大大

vue-ts环境搭建问题

1、vue-cli 项目搭建完成。
2、通过vuex-class的@getter 调用定义好的 getter方法报未定义类型

import { State, Action, Getter } from "vuex-class";
@component
export default class Main extends Vue {
@getter load: boolean; => (装饰器方式调用报错 Property 'load' has no initializer and is not definitely assigned in the constructor)
mounted() {
console.log(this.$store.getters.load); => (直接调用可以成功)
}
}

getters.ts 里面代码如下:
import { GetterTree } from "vuex";

const getters: GetterTree<any, any> = {
load(state): boolean {
const { load } = state;
return !!load;
}
}
export default getters;

tips: 试验后发现是node_modules包不一致。使用你的vue-typescript-dpapp-demo的node_modules可以正常运行,但copy 你的package.json在本地npm install后运行就报上述错误。

vue-router

大佬,在组件中,怎么使用beforeRouteEnter这类的路由钩子函数呢?在router/index.js使用的可以直接看vue-router.d.ts,但是在组件内,我该如何使用呢?谢谢大佬

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.