Vue才出来不久就深得国人的喜爱,粉丝一路飙升,一方面是因为vue且对国人友好,看完文档即可开鲁上线织梦无限,比起原生JS更为方便,另一方面则是因为生态丰富,插件齐全,Vue全家桶(VueCli、VueRouter、VueX)配合(axios、elementui)看起来香极了,另外还有很多基于Vue量身打造的UI框架,PC端常用(
Element、iView、vue-element-admin、VueMaterial、VueStrap、KeenUI)等,移动端常用(Vant、Muse-ui、MintUI)等。
说了这么多那就进入今天的正题吧,此篇文章适用于有一定vue基础的同学,Vuex为状态管理工具,它由以下几个核心共同组成,而且他们分工很明确,他们分别是:
State
(原始数据仓库)、Getter
(查询及订阅更新)、Mutation
(改变原始仓库数据的唯一入口)、Action
(用于异步提交Mutation)。
1. State(原始数据仓库)
上面贴了一张官方的图片看起来不是太能浅显易懂,为了便于理解我们用银行来比作Vuex(下文同此),State就好比一个个银行的仓库,那么这个仓库自然就是用来存钱的地方。
mapState 辅助函数
可以查看存了多少钱,但一般用mapGetter代替
2.Getter(查看及订阅)
那么我们怎么样才能知道我们小两口存了多少钱呢?这时我们就要用到Getter了,他就好比一个绑定在支付宝或者微信上的银行卡,不过他只要查看和订阅的权限,他可以看到银行卡中存了多少钱,而且每当银行卡中的钱改变时,他会实时知道是不是被取或者被存了多少,但是他不能取钱和存钱。
mapGetters 辅助函数
可以很方便的查看存和取了多少钱
3. Mutation(改变原始仓库数据的唯一入口)
如果你这个月赚了一些钱你是不是要背着老婆存点私房钱呢,这时我们就要找Mutation了,他可以帮您取钱和存钱,Mutation就像银行柜台或者存取款机一样,而且只有在Mutation中才可以取钱和存钱,取和存了多少钱我们的Getter都会实时知道,以防被盗刷了。
mapMutation 辅助函数
可以很方便的存钱和取钱。
4. Action(用于异步提交Mutation)
当某一天你存私房钱被你老婆发现后,你仍然要偷偷存钱,那这个事情就要拜托你的好朋友Action,让他帮你去Mutation存钱。如果某一天想出去找你的小情人那么也可以叫你的好朋友Action取钱,你不用担心他会拿钱跑路,因为Getter会实时通知你取了多少钱。
mapAction 辅助函数
很方便的帮助Mutation存钱和取钱。
5. Module
有一天随着你走上人生巅峰迎娶了白富美钱越来越多的时候,你发现跑来跑去取银行存钱不是很方便,这时你就想到了要请一个Module这样的好会计,让他统一帮您看管,以防出错,这样你就方便很多了呢。
接下来我们通过用vuecli2.x和webpack构建的的简单例子来进行讲解:
(创建)main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
// 挂载实例
el: '#app',
// 加入路由
router,
//加入状态管理
store,
// 注册组件
components: { App },
// 模板
template: '<App/>'
})
(创建)App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
创建Vuex原始仓库
先安装 vuex npm install vuex --save
store—>index.js
(创建)index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 注册vuex插件
Vue.use(Vuex)
//1.创建原始仓库
// mapState辅助函数(可以用来修改及展示,为了便于管理不建议用它,用以下两个即可.)
const state = {
username: '三叶雨',
work: 'web全栈哲学'
}
//2.创建查询器(订阅更新)
// Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:
// mapGetter辅助函数(主要用来展示响应数据的更新)
//一般在computed中使用
const getters = {
username: state => state.username,
work: state => state.work
}
//3.修改原始数据(唯一用来修改原始数据)
//mapMutations辅助函数(用来改变原始数据)
//一般用在methods中使用
const mutations = {
// 改变原始仓库数据
// 只可以传一个参数,要传多个就要用数组或以对象的形式进行传过去
'SET_USERNAME': (state, data) => {
state.username = data
},
'SET_WORK': (state, data) => {
state.work = data
}
}
// 4.Action 用于提交的是 mutation,可以包含任意异步操作,因为Mutation 必须是同步函数,无法满足更多的处理。// Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个
const actions = {
setUsername({ commit }, username){
return commit('SET_USERNAME', username)
},
setWork({ commit }, work) {
return commit('SET_WORK', work)
}
}
//5.导出
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
添加路由
router—>index.js
index.js
import Vue from 'vue'
import Router from 'vue-router'// @代表src import HelloWorld from '@/components/HelloWorld'import Vuexs from '@/components/Vuexs.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
// 嵌套路由路径可以不用包含'/'
// chidren:{
// path: 'vuexs', component: Vuexs
// }
},
{
path: '/vuexs',
name: 'Vuexs',
component: Vuexs
}
]
})
组件中使用
components—>HelloWorld.vue
HelloWorld.vue
<template>
<div class="hello">
<p>username: {{username}}</p>
<p>work:{{work}}</p>
</div></template>
<script>
/**
* mapMutations(存钱和取钱)
* mapGetter(订阅查看还有多少钱)
* mapActions(帮忙存钱和取钱)
* **/
import {mapMutations, mapGetter,mapActions} from 'vuex'
// 自己实现一个mapGetter函数
// function mapGetter(arr){
// const obj = {}
// arr.forEach(k => {
// abj[k] = function(){
// return this.$store.getters[k]
// }
// })
// return obj
// }
// 同上的实现原理是一样的
// 如果某些时候mapGetter有问题这可以用以下方法解决
const obj = {
work(){
return this.$store.getters['work']
},
username(){
return this.$store.getters['username']
}
}
//1.存钱和取钱
//建议使用后者
methods:{
//bad
//提交存钱和取钱
...mapMutations(['SET_USERNAME']),
...mapMutations(['SET_WORK'])
//good
//异步提交存钱和取钱
...mapActions(['setUsername']),
...mapActions(['setWork'])
}
//1.1使用方法(在需要改变原始仓库的地方)
this.setUsername('我存了1000000,所以我叫三叶雨')
this.setWork('一入web深似海')
// 2.查看及订阅
computed:{
...mapGetters{[
'username',
'work'
]}
}
</script>
// 2.1使用方法
直接使用...mapGetters中的名称即可,见头部使用。
Modules
当项目越来越庞大数据管理越来越多的时候,你会发现数据状态会变得很难管理这个时候我们就要用到Modules,他可以帮状态管理器解耦分模块出来而不是全部挤在一起,便于代码的维护更新,接下来我们看看如何分模块进行管理。
首先我们创建好如下文件夹的嵌套结构:
original.js(原始仓库)
export const original = {
// 原始仓库
state: {
username: ''
},
// 提交修改
mutations: {
'SET_USERNAME': (state, username) => {
state.username= username
}
}
}
getters.js(查询及订阅)
export const getters = {
username: state => state.original.username
}
// 导出
// export default getters
actions.js(异步提交修改)
export const actions = {
setUserName: ({ commit }, userName) => {
return commit('SET_USERNAME', userName)
}
}
// 导出
// export default actions
与上面同级的index.js(全部导入后导出统一管理,而不是单个导出,为了更方便单个导出我已经注释掉。)
// 全部导入后导出统一管理
export { actions } from './actions'
export { getters } from './getters'
export { original } from './original'
与modules同级的index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { actions, getters, original } from './modules/index'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
original
},
getters,
actions
})
以上就是实现Modules的方法文件的嵌套你可以自行决定,但是为了便于管理文件夹的命名即嵌套要通俗易懂美观。
小结:本篇文章通过一个简单的例子主要介绍了Vuex中以下几个辅助函数和模块的使用,相信大家应该掌握了。
mapMutations(存钱和取钱)
mapGetter(订阅查看还有多少钱)
mapActions(帮忙存钱和取钱)
modules模块化
在Vue大型项目的开发中能用好Vuex可以大大提高工作效率,让自己有更多的时间去学习一些新的技术,让我们徘徊在大海的世界里,无法自拔,如果本篇文章对你有用,记得拿起的你的小武器点赞关注我哦。