今天主要解决:
1. 什么是vuex?
2. 为什么要用到vuex?
3. 怎么用?
文字比较多,不要嫌繁琐,跟这练习一遍就会了,博主可是一个字一个字写上的。
我们都知道,在做项目时,页面与页面之间要用到传值和通信,都清楚父子通信,兄弟间通信等等。。。
但是有复杂的项目,可能会嵌套很多层,这样一层一层的传值,很麻烦!不光是对代码质量造成了影响,也对代码运行的性能造成了影响,甚至会造成难以排查的bug。
之前给几个小白同学讲个例子:
小朋友想要零花钱,会先和妈妈要,妈妈没有,就去和爸爸要,爸爸把零花钱给了妈妈,妈妈再给了小朋友。
这个就很麻烦了,解决办法,不如直接爸爸把零花钱放在一个指定的位置,谁要,谁就去那个位置拿,这样就方便多了。
所以,vuex就是那个指定的地方,官方给起了个很专业的名字,叫:状态管理模式,说白了,就是一个统一存放状态的地方,谁用里边的值都可以取到,无论页面的层次多深,不用担心拿不到的问题,这样解决复杂通信或传值的问题就很方便了。
用到的地方也有很多:比如页面切换后再回来,依然显示上次搜索条件的结果,或n个组件同时共享一个状态等等……
这些理解了,前两个问题【什么是vuex/为什么要用到vuex】自然就迎刃而解了,接下来讲一下vuex的实现原理,我们先来附上一张第一眼难以理解的官方图片
相信很多小白看完这张图片后根本不理解,没关系,我举例说一下:
比如有一个A页面显示了“100”这个数字,并且我可以随意更改,但是需求上,其他BCD三个页面也要显示同样的数字,这个字段改成什么,就显示什么,要求就是要显示的数字一模一样。
那么我就要有个地方,来放这个数据,我们先创建一个js文件,在里边定义一个对象,起名叫state,这个state专门定义这个数据的
const state={
name : 100
}
然后所有页面都可以显示出这个name,显示后还要有一个可以改的地方,我们同样,在这个js文件中,在定义一个可以写方法的对象叫mutations,它里边专门放方法,如下:
const mutations ={
addNumber(){
state.name+=100
},
miunNumber(){
state.name-=100
}
}
文件中我写了一个方法叫addNmuber,这个名字随便起,我每次调用这个方法,就可以增加100,这样就实现了所有页面显示的数字,都会增加。
这个mutations中所写的方法,vue要求必须要是同步的,所以这里都写同步的方法,比如加100,或减100,或变颜色等需求都属于同步方法。这样也就是mutations控制了state中某个值的改变。
回到官网图,看下图中上边还有一个actions,actions和mutations是一样的写法,区别在于,actions中要写异步的方法,比如要调用某个异步接口,可以写在这个当中,比如高德地图和百度地图的接口,就是异步请求,页面中要引入一个地图组件,很多页面都公用,就可以写在这个当中。
那么这个异步方法actions有什么用?如果有需求,说必须等待这个接口成功返回一个数值后,再改变state中的值,这时就需要actions中调用一个接口,接口返回后,调用mutations中的方法,来改变state中的值。
const actions = {
actionsAddNumber(context){
this.axios.get('/接口名').then(()=>{
context.commit('addNumber')
})
},
}
actionsAddNumber名字随便起,它接收一个context参数。其中调用了异步方法,成功用,利用commit触发了mutations中的addNumber方法。
实战当中,我们可以利用ES5的结构赋值,改变一下代码,直接提取context参数中的commit使用,如下:
const actions = {
// 结构赋值提取commit
actionsAddNumber({commit}){
this.axios.get('/接口名').then(()=>{
// 直接使用commit
commit('addNumber')
})
},
}
那么在vue页面使用store.dispatch
触发action中的方法:this.$store.dispatch('actionsAddNumber')
不过注意的是,非大型项目actions并不是必须要用到的,一般state和mutations已足够我们使用。官网也建议,非必须情况下,不建议使用vuex,因为我们需要下载,还要引入,在文件大小和加载上,都是会受到影响的。
回过头来看官网的图片,或许,你就理解了,若面试问到,说一下vuex的实现原理,就按照这个理解,按照官网的图说:
页面中的组件,通过dispatch,来调用actions方法异步加载,成功后,通过commit触发mutations中的某个方法,来改变state中的某个值,这就是原理,最好再加上自己的理解说出来。
接下来说下vuex的用法:
创建项目时,vuex不会自带,因为不是每个项目都需要vuex,所以我们需要下载
npm install vuex --save
创建一个store文件夹,这个名字自己随意起,规范一些起个store
文件夹中放入一个js文件,例如:store.js。
文件中引入vuex,并创建出state、mutations即可(getters本文暂时不讲)。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 定义数据
// state在vuex中是用于储存数据的
const state={
name : 100
}
// 定义方法 mutation同步
// mutations 里面方的是方法,主要用于改变state中的数据源
const mutations ={
addNumber(){
state.name+=100
},
}
// 实例化 Vuex.store,用到什么引什么,用到actions就引入actions,用到getters就引入getters,本文只用到这两个
const store = new Vuex.Store({
state,
mutations
})
export default store;
搞定,vuex建立完成,就这么简单的一个vuex文件写完了,接下来vue页面文件中该使用这个了
首先我们需要找到目录中main.js中引入vuex,把文件目录引入,main.js是什么,不懂的小白要去查查。
import Vue from 'vue'
import router from './router'
import store from './store/store'
new Vue({
el: '#app',
router, // 这个要使用
store, // 这个也要使用
components: { App },
template: '<App/>'
})
使用很简单,因为我们在上边的store中实力化了这几个方法(看上边注释),所以我们就需要用this.$store来进入这个文件中,那么我想在页面中显示state中的数字100,如下写法:
<div>{{this.$store.state.name}}</div>
任何一个页面都可以这样引用,引入一个,显示一个。改变值的方法如下:
<button @click="add">增加100</button>
methods:{
add(){
this.$store.commit('addNumber')
},
}
点击按钮,就会增加数字了,并且改变一个,所有页面上的这个属性,也会跟着改变,多加练习和理解。
当然,我们可以向mutations中,传入数值:
mutations: {
// 两个参数,一个是state,一个是参数n(也叫payload载荷)
addNumber(state, n) {
state.name+= n
}
}
this.$store.commit('addNumber', 100)
这样就是非固定的写法,可以传入你想要的参数值。
avillin笔记:
1. 能改变state的方法是mutations。
2. 页面中用this.$store.state来获取到state中的某个值。
3. 页面中使用this.$store.commit来调用vuex中mutations里的某个方法。
4. 页面中使用this.$store.dispatch来调用vuex中actions里的某个方法。