VueX
1、认识vueX
状态(数据)管理模式(vueX)
==》也可以戳这儿查看更多官方教程
2、vueX的使用场景
vue单页面应用中,每个组件内部的数据在data中存放,供vue组件内部使用,但是,vue组件之间的数据共享怎么办?
来看看常见处理方法的弊端吧!
- 1、兄弟组件传值:
缺点:
1、数据传递复杂,容易出错
2、浪费内存 - 2、平行组件,无关组件
缺点:
1、数据传递复杂,容易出错
2、浪费内存
这时候,vueX的作用就来了!
那么,vueX的作用:
1、vuex能够保存全局数据,供整个应用使用
2、vuex保存的数据是响应式的
3、vuex保存的数据可以跟踪状态的变化
3、vueX的核心概念(创建vueX.store对象里的配置项)
state
: 数据仓库 ,存储所有的 共享数据 ,相当于vue组件里的data
Getter
: 在state的基础上 派生的数据, 相当于vue组件里 computed
Mutation
:修改state的数据时,用mutation,这与跟踪状态 有关系
Action
:解决mutation里只能有同步代码的问题,action里可以有异步代码
modules
:模块化
4、vueX的数据流转
5、vueX的基本使用步骤
现在就开始学习如何使用vueX吧!
5.1、安装
npm install vuex –save
5.2、创建vueX.store对象
在项目src目录下新建store/index.js
import Vue from 'vue'
//引入vueX
import Vuex from 'vuex'
//把vueX安装到Vue里
Vue.use(Vuex)
export default new Vuex.Store({
state:{
},
getters:{},
mutations:{},
actions:{}
})
5.3、把vueX.store对象植入到vue的根属性
在src/main.js文件中
./src/main.js
//引入store
import store from './store'
new Vue({
el: '#app',
store,//把store对象植入到vue的根属性,在vue组件里就可以使用 this.$store拿到vueX.store对象
})
5.4、在组件里获取数据:
//模板里:
$store.state.id
//脚本里
this.$store.state.id
5.5、组件里保存数据
this.$store.state.id = '02'
//不推荐这种写法来修改state数据,
//因为,它不能跟踪状态,推荐使用mutation来修改数据。
6、vueX的核心概念详解
我们已经知道,vueX的核心概念就是创建vueX.store对象时里面的配置项
现在,我们就来详细学习这些配置项所代表的的含义以及用法。
6.1、state
(数据仓库 ,存储所有的 共享数据 ,相当于vue组件里的data,是一个单一状态树
)
在store/index.js中的写法
export default new VueX.Store({
state:{
age:12,
isAdult:"未成年",
isAllowMarry:false
}
});
获取state数据
//script里获取
this.$store.state.属性名
//模板里获取
{{$store.state.age}}
{{$store.state.isAdult}}
6.2、Getter
在state的基础上 派生的数据, 相当于vue组件里 computed
getters:{
ageChina:state=>{
//state:就是state配置项
let shi = parseInt(state.age/10); //1
let ge = state.age%10;//2
let str = "";
switch(shi){
case 1:str='一';break;
case 2:str='二';break;
}
str+='十'
switch(ge){
case 1:str+='一';break;
case 2:str+='二';break;
case 3:str+='三';break;
case 4:str+='四';break;
case 5:str+='五';break;
}
return str+'岁';
}
},
组件里获取
{{$store.getters.ageChina}}
6.3、 Mutation
修改state的数据时,用mutation,可以跟踪状态。
在vuex中,强烈建议使用mutation改变state中的值。
mutations:{
incAge(state,payload){
//state:store中的state
state.age+=payload.num;
if(state.age>=18){
state.isAdult = "已成年";
}else{
state.isAdult = "未成年";
}
if(state.age>=22){
state.isAllowMarry = true;
}else{
state.isAllowMarry = false;
}
}
},
提交mutation(如果有异步就在action提交,如果没有异步就在组件里提交)
//组件里提交
this.$store.commit('incAge',num);
//action提交
incAge(context,num){
context.commit('incAge',num);
}
6.4、Action
解决mutation里只能有同步代码
的问题,action里可以有异步代码
actions:{
incAge(context,payload){
//context:store对象
context.commit(payload);
}
}
此处注意:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
6.5、Module
当项目比较大时,所有的全局数据存放在state里,会非常混乱,
此时需要使用module,即:模块化。
每个模块是一个独立的store。然后由总体的store引入所有的分模块store。
具体实现步骤:
- 新建文件,每个模块分别管理不同类型的数据
- 添加配置信息
- 在总的store里包含所有的模块
使用:
$store.state.moduleA.count // -> moduleA 的状态
$store.state.moduleB.count // -> moduleB 的状态
7、模块(Module)里的命名空间
组件里派发action时,如果,直接写action的名字,那么就会找到所有同名的action。
如:
this.$store.dispatch({
type:"incCount"
});
//会派发给moduleA和moduleB里的incCount。即:moduleA和moduleB里的incCount都被执行了。如果不希望这样,那就用命名空间
这时候,就需要用到命名空间(namespaced:true)
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
可以通过添加 namespaced: true
的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
具体步骤:
- 模块定义时,加上namespaced:true
export default {
namespaced:true,//此处加上namespaced:true
state:{
},
mutations:{
},
actions:{
}
}
- 组件里派发action时,加上模块名
this.$store.dispatch('moduleA/incCount');//此处是路径
实例代码:vueX异步代码的运行走向