一、vuex的介绍
1、vuex的产生背景:
相比于之前的vue:想要实现添加数据就要在created阶段,调用加载数据(例如:axios查询所有需要的数据信息,并且将数维护在data里面)的函数,先渲染数据到页面,将数据先收集起来再调用methods的对应的方法,调用成功的回调函数内写数据刷新的函数。
vue里面数据库交互处理和逻辑处理是写在一个页面的。并且其中数据主要是通过axios来操作的。它的代码部分占据了一半。
由于:1)、vue里面数据共享麻烦。
2)、vue的视图逻辑(数据的增删改查或 者是页面显示等等)与数据逻辑代码混淆vue的数据逻辑和视图逻辑在一个页面中)于是,产生了vuex。
3)、当共享多个组件时单项数据流简洁性被破坏:多个视图依赖同一个状态,来自不同视图的行为需要变更同一状态时。
2、vuex的特点:
1)解决组件之间的数据(包括方法)共享问题。将项目中的所有数据和方法共同维护起来。
2)vuex使得代码更加结构化和易于维护————代码分离(视图逻辑和数据交互逻辑分离开)。
{
视图逻辑(写在vue中):打开模态框,成功提示,失败提示,事件绑定,数据绑定,数据渲染。(它们与页面显示有关,和后台数据无关)
数据交互(数据逻辑):(应该封装在vuex里面):例如查询所有数据的方法以及查询到的数据,删除数据,批量删除数据等等。
主要是用axios来获取或者提交数据。
拓展:java的三层架构:
视图层:专门做数据与前后台数据交互的模块。
业务逻辑层:业务逻辑:例如登录逻辑的设计,步骤。
数据访问层:数据的增删改查,与数据库打交道。
三层架构实行起来简单直接好运营。类似于之前的学过的vue。
}
3、vuex的使用情境:
当应用简单时,主要用store模式,即vue框架。
当用大型单页的应用时候,就用vuex。但是,它的数据维护有问题。
比如程序员的分模块代码,数据维护很难。
数据不能作共享。vue与vue不能共享。
4、vuex是vuex的状态管理机制。
1)有state:管理数据:
将数据源理解为状态(state)状态里面的内容就是共用的数据。。
2)、状态自管理概念:例如定一个变量count,用来计数。
例如组件封装后放在全局变量中。
即将组件的共享状态抽离出来放在全局中,以全局模式来管理。这个模式,将组件数构成了一个巨大的视图,任何组件都能获取状态或者触发行为。
3)组件共享的缺点:
多个视图依赖于同一状态,来自不同视图的xxxx依赖同一状态。过程复杂。
axios对数据的管理。但是他的代码繁琐。例如cms项目和课调项目。
Flus架构是类似于眼镜的作用,什么时候需要,本人自会知道。
5、vuex包括:
1)四部分(4个核心概念,都是对象)
state:状态,用于维护数据。或者用于直接取得数据。只有突变能影响改变state里面的状态。在computed中映射。
getters:获取器,用于对state中的数据进行过滤后输出。在computed中映射。
mutations:突变,用于直接修改state的值,并且只支持同步操作。唯一。里面只能包含同步函数。在methods中映射。
actions:动作,用于调用突变,执行数据改变,支持异步操作。(异步情况下必须用actions)。在methods中映射
2)逻辑过程
vue组件的数据来自于data,vue可以给vuex分发指令,通过stae把数据传给vue。当想要添加数据时候,不能直接调用axios,而是需要vue想vuex发送一个动作action.action封装了axios去执行添加操作,在刷新数据之后去查询,再把查询到的数据提交(commit)给突变(mutations),从而影响state的数据,从而影响页面的数据展现。
6、vuex如何引用:
方法一:如果引用vue-cli时:(模块化的)(脚手架)
先安装:npm install vuex--save
方法二:简单导入
二、vuex的核心概念
Vuex提供了Store构造函数。
那么在应用Vuex时候,先做到如下:
1、实例化一个唯一的Vuex的对象:store(作为数据仓库)
let store=new Vuex.Store({
state:{
//数据的状态
//在computed中映射
},
getters:{
//在computed中映射
//状态
},
mutations:{
//在methods中映射
//突变
},
actions:{
//在methods中映射
//动作
},
});
2、应用
vuex依赖于vue存在,所以写vuex的框架之前需要写vue的框架。
1)、如何在vue组件中获取vuex的状态(数据)
(也就是从store中读取状态的方法)
方法一:在vue的计算属性中返回某个状态,动态的获取store的变量值:
computed:{
属性名(){
return store.state.a;
//a为state中声明的属性,和它里面的命名一致,而属性名是在页面中要渲染的数据
}
}
方法二:将store对象注入到vue,在用计算属性获取。与router类似。
(也就是将store中的数据映射到本地vue的计算属性中了,写在vue的computed中)
new Vue({
data:{},
store,
computed:{
a(){
return this.$store.state.状态名;
//状态名是state中声明的属性,和它里面的命名一致。
//而a(计算属性名)是在页面中要渲染的数据
}
}
})
适用情况:常用。由于store只能被定一次,每个子vue文件不能任意的调用它,分别需要用import导入它。所以此时因为在vue的根实例中注入了一下,引用时就用:‘this.$store’可以了。
($是用来访问内部属性的)
方法三:mapState 辅助函数(做映射)--拿取state中的数据。
前提:store在vue中已经注入
(当组件要获取多个状态时,它们都声明为计算属性会有代码冗余)
1)·思想:在vuex的store和vue组件建立一个桥,桥可以把store的需要的状态直接映射到vue里面。
2)·格式(两种):
在vue的computed中:
3·1 mapState方法里面参数是数组.此时为极简格式。此时状态名不能重命名
computed:{
...Vuex.mapState(['状态名1','状态名2','状态名3'...]);
//状态名与state中的名字一致
});
}
3·2 mapState方法参数为对象:
computed:{
...Vuex.mapState({
a:'状态名1',
b:'状态名2'
});
//‘...’是解构符号
//状态名与state中的名字一致,
//a和b是计算属性名,此时渲染页面出的数据应该写为a或者b
});
}
2)、应用的步骤:
1)实例化vuex的对象,用于实现状态管理机制
2)将vuex的状态管理机制注入到vue的根实例中,通过this.$store调用
3)在计算属性中建立当前vue对象与vuex的数据映射关系。(将store中的数据映射到本地vue的计算属性中了)
有三种等价代码可以实现。
1、computed:{
...Vuex.mapState({
aaa:'状态名1',
bbb:'状态名2'
})
}
=====>
2、computed:{
//此时状态名不能被重命名
...Vuex.mapState(['状态名1','状态名2']);
}
=====>
3、computed:{
aaa(){
return this.$store,state.状态名1;
}
bbb(){
return this.$store.state.状态名2;
}
}
3、关于mutations————突变(类似于事件)
@1特点:
1)提交mutation是唯一能够直接改变store中的状态的存在。
2)封装了改变状态的突变。其中的每个突变都有一个字符串的事件类型和回调函数,这个回调函数就是具体更改状态的地方。(类似于click函数,左右点击事件发生后才会执行相应的handler函数)它的第一参数必须是state。第二个参数称为'载荷',载荷一般是个对象,包含多个字段并且容易读。
3)不能直接调用它的方法,必须用以下格式
来调用:store.commit('突变名',载荷);
4)它的映射写在vue的methods中。
@2提交载荷方式:
1)store.commit('突变名称',{
//要给当前突变传递的值
})
2)直接使用包含type的对象。
store.commit({
type:'突变名称',
//要给当前突变提交的值
})
@3在组件中提交突变的方法:
1、this.$store.commit('突变名称');
例如:resetUsers(){
this.$store.commit('setUsers',[{
name:'line',
age:12
}])
},
2、使用mapMutations辅助函数。此方法不支持异步操作。格式:
例如:
重置users方法2:ma
pMutations映射写在methods中
...Vuex.mapMutations(['setUsers']),
//setUsers是突变名称
//以下部分是载荷,会被提交,完成state的更新
resetUsers(){
this.setUsers([{name:'jacky'}]);
},
4、关于action
1)特点:通过提交突变来更改数据状态,可以包含异步操作。用法和mutation是类似的(在vue的methods中进行映射)。
2)启用action后整个数据流就是联通的。它的大概过程是:
vue的created方法调用在actions里面的函数,使得主要vue对象一建立,就调用action里面的方法执行操作。这个操作又以context(与store对象等价)为参数,并且在操作执行成功时调用context在mutations里面给数据做一个更新或者保存操作(此时是将数据提交给给突变,并且以他本身作为载荷),相应地这个数据的值传递到state里面,然后再在vue的计算属性(computed)中,用“...Vuex.mapState”映射出当前被更新好的数据。最后这个数据将页面重新渲染。
5、关于getter
1)特点:
@1:封装了获取数据的方法。(类似于一行设置了供客户取钱的柜台)。覆盖了之前直接从state中取得数据的方式。(类似于直接抢银行拿钱)。【这两个都可以实现数据的获取:state可以拿到原始数据;但是通过getter可以得到过滤后的数据,这个数据也是最后总源于state中的。】
@2:在计算属性中映射。
2)映射:
与state映射类似。它映射的目的是得到过滤后的数据。
格式1:‘...Vuex.mapGetters(['a'])’
//a为getters中声明的过滤方法名
3)功能:
取代之前直接从state中拿取数据的的方式,而是将数据经过招生说明方法(柜台)的过滤后,再把数据重新渲染到页面上。并且此时,这个计算属性名可以作为变量名进行v-for结构的渲染。
6、关于Module(模块)
1)来源:当项目很庞大时,store会变得很臃肿,为了解决这个问题,需要将store分割成模块(module)。每个模块有自己的state,mutation,actions,getter,甚至是嵌套子模块。
2)命名空间:
一般默认情况下,方法:action,mutation,getter,是注册在全局命名空间的,而state是单独注册的。这样做的好处是:多个模块可以对同一个mutation或action做出响应。
其中:namespaced:true ,
//体现了模块的封装性和复用性。表示该模块是带命名空间的模块,当该模块被注册后,它的所有getter,action,mutation,都会自动根据模块注册的路径调整命名。
感谢阅读,若有不对支出敬请指正。