Vuex基础
https://vuex.vuejs.org/zh-cn
state --> view --> action -> state
多组件共享状态, 之前操作方式,由父组件传递到各个子组件。 当路由等加入后,会变得复杂。 引入viewx 解决共享问题。
原vue结构图
vuex结构图
Vuex对象结构 (state,mutations,getters,actions)
state 对象数据
mutations 操作变更state数据
getters 计算state
actions 触发mutations
★学习之后分析数据流向图★
安装
npm install --save vuex
调试
目标
代码1 :原vue实现计数器
app.uve
<template> <div> <p>点击次数{{count}}, 奇偶数:{{eventOrOdd}}</p> <button @click="increment">+</button> <button @click="decrement">-</button> <button @click="incrementIfOdd">奇数加</button> <button @click="incrementAsync">异步加</button> </div> </template> <script> export default { data () { return { count: 0 } }, computed: { eventOrOdd () { return this.count % 2 === 0 ? '偶数' : '奇数' } }, methods: { increment () { const count = this.count this.count = count + 1 }, decrement () { const count = this.count this.count = count - 1 }, incrementIfOdd () { const count = this.count if (count % 2 === 1) { this.count = count + 1 } }, incrementAsync () { setTimeout(() => { const count = this.count this.count = count + 1 }, 1000) } } } </script> <style> </style>
代码2: VUEX实现
store.js
/** * Created by infaa on 2018/9/22. */ import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { // 初始化状态 count: 0 } const mutations = { INCREMENT (state) { state.count++ }, DECREMENT (state) { state.count-- } } const actions = { increment ({commit}) { commit('INCREMENT') }, decrement ({commit}) { commit('DECREMENT') }, incrementIfOdd ({commit, state}) { if (state.count%2 === 1) { commit('INCREMENT') } }, incrementAsync ({commit}) { setTimeout( () => { commit('INCREMENT') }, 1000) } } const getters = { eventOrOdd (state) { return state.count % 2 === 0 ? '偶数' : '奇数' } } export default new Vuex.Store({ state, // 状态对象 mutations, // 更新state函数的对象 actions,// dispatch 对应actiong getters // 对应computed 中getters })
main.js
/** * Created by infaa on 2018/9/19. */ import Vue from 'vue' import App from './App' import store from './store' /* eslint-disable no-new */ new Vue({ el: '#app', components: {App}, template: '<App/>', store // 所有组件对象多了一个属性$store })
app.vue
<template> <div> <!--<p>点击次数{{count}}, 奇偶数:{{eventOrOdd}}</p>--> <p>点击次数{{$store.state.count}}, 奇偶数:{{eventOrOdd}}</p> <button @click="increment">+</button> <button @click="decrement">-</button> <button @click="incrementIfOdd">奇数加</button> <button @click="incrementAsync">异步加</button> </div> </template> <script> export default { // data () { // return { // count: 0 // } // }, computed: { eventOrOdd () { // return this.count % 2 === 0 ? '偶数' : '奇数' return this.$store.getters.eventOrOdd // js中要写this,模版中不用直接写$store } }, methods: { increment () { this.$store.dispatch('increment') }, decrement () { // const count = this.count // this.count = count - 1 this.$store.dispatch('decrement') }, incrementIfOdd () { this.$store.dispatch('incrementIfOdd') // const count = this.count // if (count % 2 === 1) { // this.count = count + 1 // } }, incrementAsync () { this.$store.dispatch('incrementAsync') // setTimeout(() => { // const count = this.count // this.count = count + 1 // }, 1000) } } } </script> <style> </style>
代码3 优化app.js
app.uve 如果对应名不同,由[ ] 改为{}即可
<template> <div> <!-- <h2>点击的个数:{{count}}</h2> --> <!-- <h3>{{eventOrOdd}}</h3> --> <!-- Vuex 版本 --> <h2>点击次数{{$store.state.count}}, 奇偶数:{{eventOrOdd}}</h2> <button @click="increment">+</button> <button @click="decrement">-</button> <button @click="incrementIfOdd">奇数+</button> <button @click="incrementAsync">异步加</button> </div> </template> <script type="text/ecmascript-6"> import {mapState, mapGetters, mapActions} from 'vuex' // export default{ // data(){ // return{ // count:0 // } // }, // computed:{ // eventOrOdd(count){ // // return this.count % 2 === 0?'偶数':'奇数' // return this.$store.getters.eventOrOdd // } // }, // methods:{ // increment () { // // const count = this.count; // // this.count = count+1 // this.$store.dispatch('increment') // }, // decrement (){ // // const count = this.count; // // this.count = count -1 // this.$store.dispatch('decrement') // }, // incrementIfOdd () { // // const count = this.count; // // if(count % 2 === 1 ){ // // this.count = count + 1 // // } // this.$store.dispatch('incrementIfOdd'); // }, // incrementAsync () { // // setTimeout(() => { // // const count = this.count // // this.count = count + 1 // // }, 1000) // this.$store.dispatch('incrementAsync') // } // } // }; // 优化 App.vue 代码格式 export default{ computed:{ ...mapState['count'], ...mapGetters['eventOrOdd'] }, methods:{ ...mapActions(['increment','decrement','incrementIfOdd','incrementAsync']) } }; </script> <style type="stylus" rel="stylesheet/stylus"> </style>
官方另一个案例购物车, store以目录结构呈现
https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart