vue part5.1 vuex引入及案例 计数
基本
https://vuex.vuejs.org/zh-cn
state --> view --> action -> state
多组件共享状态, 之前操作方式,由父组件传递到各个子组件。 当路由等加入后,会变得复杂。 引入viewx 解决共享问题。
原vue结构图
vuex结构图
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
app.uve 如果对应名不同,由[ ] 改为{}即可
<template> <div> <!--<p>点击次数{{count}}, 奇偶数:{{eventOrOdd}}</p>--> <!--<p>点击次数{{$store.state.count}}, 奇偶数:{{eventOrOdd}}</p>--> <p>点击次数{{count}}, 奇偶数:{{eventOrOdd}}</p> <button @click="increment">+</button> <button @click="decrement">-</button> <button @click="incrementIfOdd">奇数加</button> <button @click="incrementAsync">异步加</button> </div> </template> <script> import {mapState, mapGetters, mapActions} from 'vuex' export default { computed: { ...mapState(['count']), ...mapGetters(['evenOrOdd']) // count () { // return this.$store.state.count // }, // evenOrOdd () { // return this.$store.getters.eventOrOdd // } }, methods: { ...mapActions(['increment', 'decrement', 'incrementIfOdd', 'incrementAsync']) } // methods: { // increment () { // this.$store.dispatch('increment') // }, // decrement () { // this.$store.dispatch('decrement') // }, // incrementIfOdd () { // this.$store.dispatch('incrementIfOdd') // }, // incrementAsync () { // this.$store.dispatch('incrementAsync') // } // } } </script> <style> </style>
官方另一个案例购物车, store以目录结构呈现
https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart