vuex 从入门到精通

1.引言

下面我将以一个简单的计数器做为例子来使用vuex。vue

2.vuex通讯原理讲解

以前版本的通讯处理:

父子组件:直接经过Props属性
兄弟组件:跟组件APP.vue组件下面有A.vue和B.vue两个子组件
复制代码

A组件和B组件之间的通讯过程是这样的:
A组件:老爸,帮我传递个消息给B组件。(这时候A.vue dispatch 一个事件给 APP.vue)
APP组件:就是干(APP.vue 监听A.vue的 dispatch事件,同时须要broadcast一个事件给B组件)
B组件:收到信息(经过on监听App.vue组件的分发事件)
复制代码

vuex通讯原理

具体逻辑以下webpack

用户在组件中的输入操做触发 action 调用;
Actions 经过分发 mutations 来修改 store 实例的状态;
Store 实例的状态变化反过来又经过 getters 被组件获知。
复制代码

3.安装使用vuex(简易版本)

  • 3.1 首先经过命令行生成项目结构
$ vue init webpack vuex
$ cnpm install

安装vuex(vuex会添加到dependencies中)
$ npm install vuex --save
复制代码
  • 3.2 将store相关的代码分离出来
  • 在src文件夹下面新建store文件夹
  • 在store文件夹下面新建 index.js 文件 index.js
<template>
  <div class="hello">
    <p>{{count}}
      <button @click="inc">+</button>
      <button @click="dec">-</button>
    </p>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  computed: {
    count() {
      return this.$store.state.count
    }
  },
  methods: {
    inc() {
      this.$store.commit('inc')
    },
    dec() {
      this.$store.commit('dec')
    }
  }
}
</script>
复制代码
  • 3.3 在main.js中引入store文件 main.js
import store from './store'
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
复制代码
  • 3.4 在HelloWorld.vue中使用store里面的count变量 HelloWorld.vue
<template>
  <div class="hello">
    <p>{{count}}
      <button @click="inc">+</button>
      <button @click="dec">-</button>
    </p>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count
    }
  },
  methods: {
    inc() {
      this.$store.commit('inc')
    },
    dec() {
      this.$store.commit('dec')
    }
  }
}
</script>
复制代码

完成到这一步 , 上述例子中的 this.$store.state.count 就能够使用了。咱们就能够实现计数的功能。web

4.组件化使用vuex,加入vuex中的核心概念(state,getters,mutations,actions)下面就直接上代码了,毕竟跑起来才是真理。

main.jsvuex

import Vue from 'vue'
import App from './App'
import router from './router'
import vuex from 'vuex'
import store from './store'
Vue.use(vuex);

Vue.config.productionTip = false

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

HelloWorld.vuenpm

<template>
  <div class="hello">
    <p>
      Value: {{ count }}
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
    </p>
  </div>
</template>

<script>
  import {mapGetters, mapActions} from 'vuex'

  export default {
    created() {
      console.log(this.$store)
    },
    computed: mapGetters([
      'count'
    ]),
    methods: mapActions([
      'increment',
      'decrement'
    ])
  }
</script>
复制代码

actions.jsbash

export const increment = ({ commit }) => commit('increment')
export const decrement = ({ commit }) => commit('decrement')
复制代码

mutations.jsapp

export const increment = state => {
  state.count++
}
export const decrement = state => {
  state.count--
}
复制代码

getters.js组件化

export const count = state => state.count
复制代码

index.jsui

import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from './getters'
import * as actions from  './action'
import * as mutations from './mutataions'

Vue.use(Vuex);

const state = {
  count: 0
}

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})
复制代码