vue全家桶-vuex深入讲解
加蓓努力我先飞 人气:0使用
index.js
import Vue from 'vue' import Vuex from 'vuex' import getters from './getters' import app from './modules/app' import settings from './modules/settings' import user from './modules/user' import system from './modules/system' Vue.use(Vuex) const store = new Vuex.Store({ modules: { app, settings, user, system }, getters }) export default store
getters.js
const getters = { sidebar: state => state.app.sidebar, device: state => state.app.device, token: state => state.user.token, avatar: state => state.user.avatar, name: state => state.user.name, currentuserinfo: state => state.system.currentuserinfo, count: state => state.system.count, } export default getters
system.js
const system = { namespaced: true, state: { currentuserinfo: {}, count: 0, }, mutations: { SET_CURRENTUSERINFO: (state, currentuserinfo) => { state.currentuserinfo = currentuserinfo }, SET_COUNT: (state, count) => { state.count = count }, } } export default system
全局使用:main.js文件中
import store from './store' new Vue({ el: '#app', router, store, render: h => h(App) })
Vuex概述
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享
使用Vuex管理数据的好处:
A.能够在vuex中集中管理共享的数据,便于开发和后期进行维护
B.能够高效的实现组件之间的数据共享,提高开发效率
C.存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新
Vuex中的核心特性
vuex中的主要核心概念如下:
- State
- Mutation
- Action
- Getter
A.State
State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储 例如,打开项目中的store.js文件,在State对象中可以添加我们要共享的数据,如:count:0
在组件中访问State的方式: 1).this.$store.state.全局数据名称 如:this.$store.state.count 2).先按需导入mapState函数: import { mapState } from 'vuex' 然后数据映射为计算属性: computed:{ ...mapState(['全局数据名称']) }
this.$store.state.全局数据名称-组件访问State中的数据的第一种方式
//访问 console.log("1111",this.$store.state.system.count); <h3>当前最新的count值为:{{$store.state.system.count}}</h3>
组件访问State中的数据的第二种方式:按需导入
2).先按需导入mapState函数: import { mapState } from 'vuex' //将全局数据,用展开运算符映射为当前组件的计算属性 // 然后数据映射为计算属性: computed:{ ...mapState(['count']) } mapState()可以传入对象或者数组 传入数组用法: mapState(['counte', 'name','age']) // 传入对象用法:可以重命名store中的数据 ...mapState({ sCounter: state => state.name, ...... }) computed:{ ...mapState({ count: state => state.system.count, ...... }), }
B.Mutation
Mutation用于修改变更$store中的数据
只能通过Mutation变更Store数据,不可以直接操作Store中的数据通过这种方式虽然操作起来稍微繁琐点,但是可以集中监控所有的数据变化
this.$store.commit是触发Mutation的第一种方式
1.定义:
const system = { namespaced: true, state: { count: 0, }, mutations: { add(state) { //变更状态 state.count++ } } } export default system
2.使用
<template> <div> <h3>当前最新的count值为:{{$store.state.system.count}}</h3> <el-button type="primary" @click="btnHandler1">+1</el-button> </div> </template> <script> export default { name: 'Addition', props: { }, data() { return { } }, computed: {}, mounted() {}, methods: { btnHandler1() { this.$store.commit("system/add") }, } } </script> <style scoped> </style>
1.传参—定义
mutations: { add(state) { state.count++ }, addN(state, step) { state.count += step } }
2.传参-使用
methods: { btnHandler1() { this.$store.commit("system/add") }, btnHandler2(val){ // commit 的作用就是调用某个mutation函数 this.$store.commit("system/addN",val) }, }
触发Mutation的第二种方式,按需导入
从vuex中按需导入mapMutations 函数
import { mapMutations } from 'vuex'
通过刚才导入的mapMutations 函数,将需要的mapMutations 函数,映射为当前组件的methods方法:
sub(state) { state.count-- }, subN(state, step) { state.count -= step },
method:{ ...mapMutations({ sub: 'system/sub' }), btnHandler1(){ this.sub()//直接引用 }, btnHandler2(val){ this.subN(val) }, }
C.Action
Action用于处理异步任务
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但Action中还是要通过出发Mutation的方式间接变更数据
this.$store.dispatch()是触发actions的第一种方式
actions: { addAsync(content) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('add') }, 1000) } }
methods: { // 异步的让count自增+1 btnHandler3(){ // 这里的dispatch函数,专门用来触发actions this.$store.dispatch('system/addAsync') }, }
actions携带参数
触发actions异步任务时携带参数
actions: { addNAsync(content, step) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('addN', step) }, 1000) }, }
methods: { btnHandler4(){ // 这里的dispatch函数,专门用来触发actions,传参 this.$store.dispatch('system/addNAsync',3) }, }
触发actions的第二种方式:按需导入
actions: { subAsync(content) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('sub') }, 1000) }, subNAsync(content, step) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('subN', step) }, 1000) }, }
import {mapActions } from 'vuex' methods:{ ...mapActions({ subAsync: 'system/subAsync', subNAsync: 'system/subNAsync', }), btnHandler3(){ this.subAsync() }, btnHandler4(){ this.subNAsync(3) }, }
D.Getter
Getter用于对Store中的数据进行加工处理形成新的数据
它只会包装Store中保存的数据,并不会修改Store中保存的数据,当Store中的数据发生变化时,Getter生成的内容也会随之变化
打开store.js文件,添加getters,如下:
使用getters的第一种方式
//system.js文件中的 getters中的showNum <h3>{{$store.getters['system/showNum']}}</h3> console.log('$store.state',this.$store.getters['system/showNum']);
使用getters的第二种方式
<h3>{{showNum}}</h3>
computed: { ...mapGetters({ showNum: 'system/showNum', }) },
代码总结
system.js
const system = { namespaced: true, state: { currentuserinfo: {}, count: 0, }, // 只有mutations中定义的函数,才有全力修改state中的数据 mutations: { // SET_CURRENTUSERINFO: (state, currentuserinfo) => { // state.currentuserinfo = currentuserinfo // }, // SET_COUNT: (state, count) => { // state.count = count // }, add(state) { state.count++ }, addN(state, step) { state.count += step }, sub(state) { state.count-- }, subN(state, step) { state.count -= step }, }, actions: { addAsync(content) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('add') }, 1000) }, addNAsync(content, step) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('addN', step) }, 1000) }, subAsync(content) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('sub') }, 1000) }, subNAsync(content, step) { setTimeout(() => { // 在actions中,不能直接修改state中的数据 // 必须通过content.commit() 去触发某个mutations才行 content.commit('subN', step) }, 1000) }, }, getters: { //添加了一个showNum的属性 showNum(state) { return '最新的count值为:【' + state.count + '】'; } } } export default system
src\views\learnVuex\index.vue
<template> <div> <my-addition ></my-addition> <p>----------------------</p> <my-subtranction ></my-subtranction> </div> </template> <script> // 导入 import Addition from '@/components/Addition'; import Subtranction from '@/components/Subtranction'; // import Subtranction from '../../components/Addition'; export default { name: 'learnVuex', props: {}, // 注册 components: { 'my-addition': Addition, 'my-subtranction': Subtranction }, data() { return { } }, computed: {}, mounted(){ console.log("1111",this.$store.state.system.count); }, } </script> <style scoped> </style>
src\components\Addition\index.vue
<template> <div> <h3>当前最新的count值为:{{$store.state.system.count}}</h3> <h3>{{$store.getters['system/showNum']}}</h3> <el-button type="primary" @click="btnHandler1">+1</el-button> <el-button type="primary" @click="btnHandler2(2)">+2</el-button> <el-button type="primary" @click="btnHandler2(3)">+3</el-button> <el-button type="primary" @click="btnHandler3">+1 Async</el-button> <el-button type="primary" @click="btnHandler4">+3 Async</el-button> </div> </template> <script> export default { name: 'Addition', props: { }, data() { return { } }, computed: {}, mounted() { console.log('$store.state',this.$store.getters['system/showNum']); }, methods: { btnHandler1() { this.$store.commit("system/add") }, btnHandler2(val){ // commit 的作用就是调用某个mutation函数 this.$store.commit("system/addN",val) }, // 异步的让count自增+1 btnHandler3(){ // 这里的dispatch函数,专门用来触发actions this.$store.dispatch('system/addAsync') }, // btnHandler4(){ // 这里的dispatch函数,专门用来触发actions this.$store.dispatch('system/addNAsync',3) }, } } </script> <style scoped> </style>
\src\components\Subtranction\index.vue
<template> <div> <h3>当前最新的count值为:{{count}}</h3> <h3>{{showNum}}</h3> <el-button type="primary" @click="btnHandler1">-1</el-button> <el-button type="primary" @click="btnHandler2(2)">-2</el-button> <el-button type="primary" @click="btnHandler2(3)">-3</el-button> <el-button type="primary" @click="btnHandler3">-1 Async</el-button> <el-button type="primary" @click="btnHandler4">-3 Async</el-button> </div> </template> <script> import { mapState,mapMutations,mapActions,mapGetters } from 'vuex' export default { name: 'Subtranction', props: {}, data(){ return{ } }, computed: { ...mapState({ count: state => state.system.count, }), ...mapGetters({ showNum: 'system/showNum', }) }, mounted(){ console.log("mapState",this.count); }, methods:{ ...mapMutations({ sub: 'system/sub', subN: 'system/subN', }), ...mapActions({ subAsync: 'system/subAsync', subNAsync: 'system/subNAsync', }), btnHandler1(){ this.sub() }, btnHandler2(val){ this.subN(val) }, btnHandler3(){ this.subAsync() }, btnHandler4(){ this.subNAsync(3) }, } } </script> <style scoped> </style>
加载全部内容