一、概念
状态数据管理器是用于管理全局状态数据、实现数据流控制、实现数据跨组件传递的一个数据管理库
它是使用闭包来实现避免全局数据污染,使用单向数据流来实现数据流控制。
1.安装:cnpm i -S vuex@3
2.它是一个全局唯一数据单向流的一个状态数据管理JS对象
状态数据:就是指页面虚拟dom状态的数据,可以是data数据,props,computed
3.为什么要用?需要全局数据单一,不被污染,数据流可控,数据可变化追溯。
在Vue上全局注入使用:Vue.use(Vuex)
4.实例化:new Vuex.Store():实例化一个可以用于存储数据和提供操作数据的一个存储对象(Store)
在这个对象下又模块化属性:modules接收一个对象。有模块就有开启命名空间属性来进行对模块文件划分
namespaced:true (一旦这个命名空间开启后 ,就所有的getter、mutation、action等内置方法名字就都必须加上 模块名字+'/')
=>getters.getAmount =>getters['cart/getAmount']
模块核心四大属性:
1)state定义和初始化数据的属性(这里放数据源或者初始化定义的数据)
2)getters:是定义外部获取state中的数据的getter方法的属性
注意点:所有的getter方法会有一个state形参,而且这个函数可以返回state数据
3)actions:是定义执行数据处理的异步方法的函数
注意点:它有两个形参:第一个是store实例对象 - -因为要调用commit方法提交处理好的数据到mutation方法
第二个参数:是dispatch发送过来的参数
4)mutaitions:定义扭转数据的方法的属性
注意点:第一个为state对象,第二个为commit方法传递的参数对象
//定义数据管理器的state、getters、mutations、actions、的modules(模块配置) //进行vuex插件注册 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) //引入模块 import common from './common' //实例化 - - 因为是模块化管理,所以每一个模块应该是一个独立的模块(每一个模块应该是一个文件) const store = new Vuex.Store({ modules:{ common, }) export default store //导出该管理器文件后需要在渲染到vue全局上来使用
这里是配置模块文件,可以将模块文件分开进行配置,直接修改数据管理文件操作就可以(然后进行导出引入对象文件)
//定义common模块,进行导出到管理器 //action定义也可以单独写对象声明来使用,单独写出来是为方便进行操作 const actions={ //把处理后的数据提交到mutation中去进行数据更新,接收数据,所以就有两个形参 tokenAct(_store,_data){ Promise.resolve().then(()=>{ //为什么这里不需要加模块名字 _store.commit('setToken','TOKEN - '+ _data) //第一个参数是提交到扭转下的方法 所以不是模块名 }) } } //这里导出时没有声明因为花括号在js里是属于空对象定义 export default { //开启命名空间 namespaced:true, //四大核心属性配置 //state是公共数据源,共享和存储的地方 state:{ //通用票据 -- 是用来解决http无状态使用的一个凭证 常见于(登录的token的存储) }, getters:{ //getter方法要获取到state的值,才能返回state值,所以方法必须有一个 state形参 getToken(_state){ return _state.token } }, actions, mutations:{ //给state数据赋值,就需要接收数据,那么就需要连个形参 setToken(_state,_token){ _state.token = _token } } } //在形参后面就是跟着state对象下的属性然后赋值改变,获取
//定义common模块,进行导出到管理器 //action定义也可以单独写对象声明来使用,单独写出来是为方便进行操作 const actions={ //把处理后的数据提交到mutation中去进行数据更新,接收数据,所以就有两个形参 tokenAct(_store,_data){ Promise.resolve().then(()=>{ //为什么这里不需要加模块名字 _store.commit('setToken','TOKEN - '+ _data) //第一个参数是提交到扭转下的方法 所以不是模块名 }) } } //这里导出时没有声明因为花括号在js里是属于空对象定义 export default { //开启命名空间 namespaced:true, //四大核心属性配置 //state是公共数据源,共享和存储的地方 state:{ //通用票据 -- 是用来解决http无状态使用的一个凭证 常见于(登录的token的存储) }, getters:{ //getter方法要获取到state的值,才能返回state值,所以方法必须有一个 state形参 getToken(_state){ return _state.token } }, actions, mutations:{ //给state数据赋值,就需要接收数据,那么就需要连个形参 setToken(_state,_token){ _state.token = _token } } } //在形参后面就是跟着state对象下的属性然后赋值改变,获取
二、全局注入:store:Store实例对象(在全局上使用$store对象后面跟模块方法名)
1.getters属性:获取数据的getter方法 :
好处“常常使用computed来接收数据,可以实时获取state中的最新数据
2.commit方法:提交到mutation中去更新数据:第一个参数是mutation方法名字,第二个参数是需要传递的数据对象
3.dispatch方法:调用action的方法:第一个参数action名字,第二个参数需要传递的数据对象
!!!这里插一段页面调用的$store方法代码使用
//全局使用数据状态管理器对象 <template> <div> <h3>状态数据测试</h3> <p>created里获取的值 :{{value}}</p> <p>computed获取到的值:{{token}}</p> <p> <button @click="changeToken">更新按钮</button> <button @click="asyncChangeToken">异步更新按钮</button> </p> <hr> <button @click="logoutEvt">退出</button> </div> </template> <script> export default{ data(){ return { value:'' } }, created(){ this.value =this.$store.getters['common/getToken'] }, computed:{ token(){ return this.$store.getters['common/getToken'] } }, methods:{ logoutEvt(){ //清除路由拦截标识,然后再退出到登录界面 sessionStorage.clear()//这个是全部清除,单个清除需要用到removeItem('key') this.$router.push('/login') }, changeToken(){ //直接调用commit方法 this.$store.commit('commont/setToken',Math.random()) }, asyncChangeToken(){ //调用异步action方法然后再异步操作提交到mutation扭转数据方法来更新 this.$store.dispatch('common/tokenAct',Math,random()) } } } </script>
this.$route:打印注册激活路由的信息对象,每个对象是局部的,有获取到当前·路由·是·path,name,params,query等属性使用
$route.matched是数组,包含当前路由所有嵌套记录,包含自己信息和children数据:就是routes配置中的对象数组
this.$router:可以打印全局的router的实例,也是经常用到的跳转页面路由功能。包含很多属性及history对象,任何页面调用方法,
push('home' || {path:'home'}) =>写法字符串路径或则地址对象
,replace, 跳转指定url路径,会在history不加记录,点击返回转到上上页面,上面是上一个页面
go(n) =>跳转正负整数
原理和redux是一样的:
vuex有四个属性值:state,getters,mutations,actions
在没有actions情况下,
数据state-->data
获取数据:getters-->computed
更改数据:mutations->methods
三、原理:Vuex采用MVC模式中的Model层,规定所有数据必须通过action --> mutations -->state 这个流程来进行改变状态
再结合Vue的数据视图双休绑定实现页面的更新
这样做法:是为统一页面状态管理,可以让复杂的组件交互变的简单清晰。
关于页面数据会丢失问题?(一般是全局唯一单向数据使用 =>token 或者菜单)
会丢失(解决使用vuex数据持久存储vuex-persistedstate) 可以在Vuex.Store实例加一个vuex针对模块进行数据持久化库插件
//实例化 -- 因为是模块化管理,每个模块应该是一个独立的模块(每个模块也就是一个文件) const store =new Vuex.Store({ //添加vuex数据持久化库插件 plugins:[ //注册插件 //我们的数据都是用户登录以后才会有的数据,应该为一个会话数据,所以应该存在sessionStorage中 persistedState({ //默认存储在localStorage中,项目框架指定存在sessionStorage storage:window.sessionStorage }) ], //模块配置 modules:{} })