如何简单、快速的理解vuex,花10分钟看看下面这篇文章你就知道了。话不多说,直接进入主题。
一、什么是vuex
我们要了解一门技术是什么,最直接的就是去它的官网看看。我们可以清晰的看到它是一个状态管理模式。
那什么是状态管理模式呢?它是以相应的规则保证状态以一种可预测的方式发生变化。听起来很绕对吧,看完下面,你或许能有自己对vuex的理解。
二 、 为什么要用vuex
想象一下,当我们在做项目的时候,我们会创建很多的页面(组件/试图)。这个时候就涉及到了组件通信和页面之间的多级嵌套。此时我们就会遇到两个问题:
- 多个试图依赖同一个状态
- 不同的试图行为需要变更为同一个状态
对于页面嵌套我们可以用父子组件通信来解决。但是对于兄弟组件间的通信或其他更复杂的关系,这个就显得捉襟见肘了。那我们可不可以有一个类似仓库的东西,把各个组件都需要依赖的同一个状态抽取出来,在全局使用单例模式进行管理。在这种模式下,任何组件都可以直接访问到这个状态,或者当状态发生改变时,所有的组件都获得更新。
所以vuex诞生了,Vuex 是专门为 Vue 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。
三 、 如何使用vuex
1. 安装
npm install vuex –save
2. 配置
先在src下创建store文件夹,然后在其下创建index.js,引入vuex,完成配置如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
// 定义一个num,以供全局使用
num:1,
// 定义一个name,以供全局使用
name: '小黄同学',
// 定义一个age,以供全局使用
age: 18,
},
mutations: {
},
actions: {
},
getters:{
},
modules: {
}
})
export default store
复制代码
然后在main.js 中引入,并挂载到vue实例上:
import Vue from 'vue'
import App from './App.vue'
import store from './store' //引入store
Vue.config.productionTip = false
new Vue({
store, //挂载到vue实例上
render: h => h(App)
}).$mount('#app')
复制代码
最后可以在组件中直接使用了
<template>
<div id="app">
<p>{{this.$store.state.name }}</p>
</div>
</template>
复制代码
那对vuex的基本了解和基本使用我们已经知道了,接下来我们就要对vuex的原理进行剖析,在store文件夹下创建myStore.js.让我们的myStore.js具备和vuex 一样的作用。
- 首先我们对myStore.js的结构进行分析,它要new Vuex.Store(),说明Vuex.store是一个类。并且它可以Vue.use(Vuex),说明Vuex上具备inStall方法。我们就可以先写出Vuex的总体框架了。
import Vue from "vue"
class Store{
constructor(){}
}
let Vuex = {
Store,
install
}
export default Vuex
复制代码
2. inStall函数
inStall函数的作用就是在Vue.use(Vuex)后,每个组件上都具有store方法,以此来达到任何组件都可以直接访问到这个状态
let install = function(Vue){
Vue.mixin({//让每个组件都具有store方法
beforeCreate() {
if(this.$options && this.$options.store){ // $options获取根组件
this.$store = this.$options.store
}else{ //如果是子组件的话
this.$store = this.$parent && this.$parent.$store //去父组件上找
}
},
})
}
复制代码
1. state
state作为一个“唯一数据源”而存在,而且它的数据在vuex中是响应式的,那么我们如何实现这种响应式呢,这时候我们就能想到 new Vue({})中的数据也是响应式的,state就可以重写出来了。
import Vue from "vue"
class Store{
constructor(options){ //options 代表 new Vuex.store({}) 中的整个实例对象
//state
this.vm = new Vue({
data:{
state : options.state || {}
},
})
}
}
let Vuex = {
Store,
install
}
export default Vuex
复制代码
这样我们就能在组件中使用vuex里面的数据了,我们使用用自己写的myVuex.js,在组件中:
不过我们一般为了使用方便,会用代理
import Vue from "vue"
class Store{
constructor(options){ //options 代表 new Vuex.store({}) 中的整个实例对象
//state
this.vm = new Vue({
data:{
state : options.state || {}
},
})
}
get state(){ // 函数前面加get,当我们要取函数内部的返回值时,只需要写函数名state就可以
return this.vm.state
}
}
let Vuex = {
Store,
install
}
export default Vuex
复制代码
就可以少写一层vm了
2. Getters
从state派生出一些状态,并进行计算和测量。Getters的实现原理就是先获取 Getters对象内所有的函数名,然后数据劫持forEach遍历每一个函数并调用掉。
//getters
let getters = options.getters || {}
this.getters = {}
Object.keys(getters).forEach(getterName =>{//得到了所有函数的函数名
Object.defineProperty(this.getters,getterName,{
get:()=>{
return getters[getterName](this.state) //返回并调用每一个函数
}
})
})
复制代码
在Getters里面写入一个函数:
import Vue from 'vue'
import Vuex from './myVuex.js'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
num:1,
name:'小黄同学',
age:18
},
getters:{
getNum(state){
return state.num * 10
}
},
})
export default store
复制代码
在组件中使用:
3. Mutation
用于更改vuex中的状态,类似于事件 第一个参数为state,第二个参数为自己传入的值。并且想要在组件中调用Mutation的函数,要用commit调用。实现原理和Getters类似,但是可以不用数据劫持,直接重写函数即可:
//mutations
let mutations = options.mutations || {}
this.mutations = {}
Object.keys(mutations).forEach(mutationName =>{
this.mutations[mutationName] = (arg) =>{//将mutations中的函数重写成函数调用
mutations[mutationName](this.state,arg)
}
})
commit = (method,arg) =>{ //用commit开启函数的调用,要写成箭头函数,
this.mutations[method](arg) // 不然后面Actions中会出现this执向错误
}
复制代码
import Vue from 'vue'
import Vuex from './myVuex.js'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
num:1,
name:'小黄同学',
age:18
},
mutations: {
incre(state,arg){
state.num += arg
}
},
})
复制代码
在组件中使用:点击后发生变化
4.Actions
Action 类似于mutation ,Action 提交的是 mutation,而不是直接变更状态。用法同mutation基一致,并且可以执行异步操作,用dispatch调用:
//actions
let actions = options.actions || {}
this.actions = {}
Object.keys(actions).forEach(actionName =>{
this.actions[actionName] = (arg) =>{
actions[actionName](this,arg)
}
})
}
dispatch(method,arg ){
this.actions[method](arg)
}
复制代码
我们可以在组件中使用,可以看到,俩秒后才出现结果
5. Module
将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter,防止store对象太大变得臃肿。
这个作者就不对其复写了。
关于vuex分享到这里就结束了,希望看完这篇文章能对你产生帮助。如果文章有不对或者是任何问题,欢迎点评和指出