vuex学习笔记
- 组件之间共享数据的方式:
- 父向子传值:v-bind属性绑定;
- 子向父传值:v-on事件绑定;
- 兄弟组件之间共享数据:EventBus($on: 接收数据的那个组件, $emit: 发送数据的那个组件)
- 使用vuex进行统一状态管理的好处:
- 能够在vuex中统一管理共享的数据,易于开发和后期维护;
- 能够高效地实现组件之间的数据共享,提高开发效率;
- 存储在vux中都数据都是响应式的,能够实时保持数据与页面的同步。
- 什么样的数据适合存储到vuex中:
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;对于组件中的私有数据,依旧存储在组件自身的data中即可。
- vuex的核心概念:
State, Mutation, Action, Getter
- State
State提供唯一的公共数据源,所有共享的数据都要放到Store的State中进行存储
定义:
state: { count: 0 }
调用方式一:
<p>{{$store.state.count}}</p>
调用方式二:
import {mapState} from 'vuex' export default{ computed:{ ...mapState(['count']) } } <p>{{count}}</p>
- Mutation
Mutation用于变更store中的数据。
- 只能通过Mutation变更store数据,不可以直接操作store中的数据;
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
定义:
mutations:{ add(state){ //不带参数 state.count++ }, addN(state, step){ //带参数 state.count+= step } }
调用方式一:
methods:{ add(){ this.$store.commit('add') //不带参数 }, add3(){ this.$store.commit('addN', 3) //带参数 } }
调用方式二:
import {mapMutations} from 'vuex' methods:{ ...mapMutations(['add','addN']) handleAdd(){ this.add() //不带参数 }, add3(){ this.addN(3) //带参数 } }
- Action
Action用于处理异步任务。
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
定义:
actions:{ addAsync(context){ //不带参数 setTimeout(()=>{ context.commit('add') }, 1000) }, addNAsync(context, step){ //带参数 setTimeout(()=>{ context.commit('addN', step) }, 1000) } }
调用方式一:
methods:{ addAsync(){ this.$store.dispatch('addAsync') //不带参数 }, add3Async(){ this.$store.dispatch('addNAsync', 3) //带参数 } }
调用方式二:
methods:{ ...mapActions(['addAsync', 'addNAsync']), handleAddAsync(){ this.addAsync() //不带参数 }, add3Async(){ this.addNAsync(3) //带参数 } }
- Getter
Getter用于对store中的数据进行加工处理形成新的数据。
- Getter可以对store中已有的数据加工处理之后形成新的数据,类似vue的计算属性;
- store中数据发生变化,Getter的数据也会跟着变化。
定义:
getters: { showCount: state => { return '当前count值为:' + state.count } }
调用方式一:
<p>{{$store.getters.showCount}}</p>
调用方式二:
import {mapGetters} from 'vuex' computed:{ ...mapGetters(['showCount']) } <p>{{showCount}}</p>
- 综合实例
main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import store from './store/index.js' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', store, //挂载到全局 components: { App }, template: '<App/>' })
store.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 0 }, getters: { showCount: state => { return '当前count值为:' + state.count } }, mutations:{ add(state){ state.count++ }, addN(state, step){ state.count+= step }, sub(state){ state.count-- }, subN(state, step){ state.count-= step } }, actions:{ addAsync(context){ setTimeout(()=>{ context.commit('add') }, 1000) }, addNAsync(context, step){ setTimeout(()=>{ context.commit('addN', step) }, 1000) }, subAsync(context){ setTimeout(()=>{ context.commit('sub') }, 1000) }, subNAsync(context, step){ setTimeout(()=>{ context.commit('subN', step) }, 1000) } } })
addition.vue(通过方式一调用store)
<template> <div> <p>{{$store.state.count}}</p> <p>{{$store.getters.showCount}}</p> <button @click="add()">+1</button> <button @click="add3()">+3</button> <button @click="addAsync()">+1 Async</button> <button @click="add3Async()">+3 Async</button> </div> </template> <script> export default{ name: 'Addition', methods:{ add(){ this.$store.commit('add') }, add3(){ this.$store.commit('addN', 3) }, addAsync(){ this.$store.dispatch('addAsync') }, add3Async(){ this.$store.dispatch('addNAsync', 3) } } } </script> <style> </style>
subtraction.vue(通过映射的方式调用store)
<template> <div> <p>{{count}}</p> <p>{{showCount}}</p> <button @click="handlesub()">-1</button> <button @click="sub3()">-3</button> <button @click="handlesubAsync()">-1 Async</button> <button @click="sub3Async()">-3 Async</button> </div> </template> <script> import {mapState, mapMutations, mapActions, mapGetters} from 'vuex' export default{ name: 'Subtraction', computed:{ ...mapState(['count']), ...mapGetters(['showCount']) }, methods:{ ...mapMutations(['sub', 'subN']), ...mapActions(['subAsync', 'subNAsync']), handlesub(){ this.sub() }, sub3(){ this.subN(3) }, handlesubAsync(){ this.subAsync() }, sub3Async(){ this.subNAsync(3) } } } </script> <style> </style>