[聚合文章] TypeScript + Vue系列(二): 引入vuex + vue-class

vue.js 2018-01-15 30 阅读

前言

TypeScript + Vue系列(一): 新项目配置中, 我们已经初始化了一个TypeScript + Vue的模板. 但是对于一个大型的Vue项目来说, Vuex的使用是必不可少的. 所以这一节我们将来展示一下如何在Vue + TypeSciprt的项目中中引入Vuex. 如果想在Vuex中写TypeScript, 需要借助vuex-class.

下载依赖

在命令行下输入以下内容

npm install vuex vuex-class --save

添加Couter.vue

src/components/下新增Couter.vue文件, 用于展示项目中引入了Vuex的效果

  • 初始化Couter.vue单文件
<template>            
  <div class="counter">
    <h1>Couter.vue</h1>
  </div>
</template>
        
<script>
  import Vue from 'vue'
  import Component from 'vue-class-component'

  @Component
  export default class Counter extends Vue {

  }  
</script>
  • 增添路由跳转到Couter.vue

src/router/index.ts中新增对Couter.vue组件的跳转

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld.vue'
import Counter from '@/components/Counter.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/counter',
      name: 'Couter',
      component: Counter
    }
  ]
})

因为装饰器的缘故, 会出现以下的报错信息

只需要按照指引npm install babel-plugin-transform-decorators-legacy --save-dev, 并在.babelrc中新增"plugins": ["transform-decorators-legacy"], 即可消除错误信息

  • 查看Counter.vue是否添加成功

在url中输入http://localhost:8080/#/counter, 可以看到Counter.vue添加成功

增加Vuex及相关文件

src/下新建store文件夹, 并在store文件夹中新增index.ts, state.ts, mutations-types.ts, mutations.ts, actions.ts共5个文件. 文件内容如下所示

  • index.ts文件
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'

Vue.use(Vuex);

export default new Vuex.Store({
  state,
  mutations,
  actions
})
  • state.ts文件
export default {
  initNumber: 1
}
  • mutations-types.ts文件
export const INCREMENT_NUMBER = 'INCREMENT_NUMBER';
  • mutations.ts文件
import * as types from './mutations-types'
import { MutationTree } from 'vuex'

const mutations: MutationTree<any> = {
  [types.INCREMENT_NUMBER](state, data:number): void {
    state.initNumber += data;
  }
}

export default mutations
  • actions.ts文件
import * as types from './mutations-types'

export default {
  incrementNumberAsync({ commit }, data:number) {
    setTimeout(() => {
      let mutation = types.INCREMENT_NUMBER;
      commit(mutation, data)
    }, 1000)
  }
}
  • main.ts中引入store
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

修改Couter.vue单文件

<template>
  <div class="counter">
    <h1>Coute.vue</h1>
    <h1>从Vuex中获取的数字是: {{number}}</h1>
    <button @click="incrementNumber(1)">点击同步加1</button>
    <button @click="incrementNumberAsync(1)">点击异步加1</button>
  </div>
</template>

<script lang="ts">
  import Vue from 'vue'
  import Component from 'vue-class-component'
  import { State, Action, Mutation} from 'vuex-class'
  import * as types from '../store/mutations-types'

  @Component
  export default class Counter extends Vue {
    @State('initNumber') number
    @Mutation(types.INCREMENT_NUMBER) incrementNumber
    @Action('incrementNumberAsync') incrementNumberAsync
  }  
</script>

参考链接

示例代码

  1. Github仓库

TypeScript相关文档

  1. TypeScript入门教程
  2. TypeScript官网

参考文章

  1. Decorators in ES7: ES7中装饰器
  2. ES7 Decorator 装饰者模式
  3. vue + typescript 新项目起手式
  4. vue + typescript 进阶篇

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。