vuex学习笔记
一、Vuex的介绍
1、简介:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
Vuex就是用来存放全局变量的,供所有组件使用
2、通俗理解
Vuex相当于一个仓库,仓库中可以存全局变量,方法。一个项目一个仓库,Vuex充当项目的存储模块
二、安装,配置Vuex
1、安装:进入项目终端,输入
npm install vuex@3
2、引入
(1)终端启动项目
npm run serve
(2)在mian.js文件引入vuex,使用Vuex
import Vue from 'vue' import App from './App.vue' import router from './router' import Vuex from 'vuex' //引入 Vue.config.productionTip = false Vue.use(Vuex) //使用 new Vue({ router, render: h => h(App) }).$mount('#app')
3、创建使用实例
import Vue from 'vue' import App from './App.vue' import router from './router' import Vuex from 'vuex'//引入 Vue.config.productionTip = false Vue.use(Vuex) const store = new Vuex.Store({}) //创建实例,注意Vuex.Store的大小写 new Vue({ router, store, //使用 render: h => h(App) }).$mount('#app')
4、代码例子
import Vue from 'vue' import App from './App.vue' import router from './router' import Vuex from 'vuex'//引入 Vue.config.productionTip = false Vue.use(Vuex) const store = new Vuex.Store({ state:{ count:0, }, }) new Vue({ router, store, render: h => h(App) }).$mount('#app')
去任意页面获取显示count数据
<template> <div class="home"> <h1>这是count:{{ $store.state.count }}</h1> </div> </template>
三、封装
1、新建
文件夹store-->在文件夹下新建store.js-->进行以下配置
import Vuex from 'vuex' import Vue from 'vue' Vue.use(Vuex) const store = new Vuex.Store({ state:{ count:0, }, }) export default store //将值导出给main.js
2、main.js文件
import Vue from 'vue' import App from './App.vue' import router from './router' import store from '@/store/store' //引入 Vue.config.productionTip = false new Vue({ router, store, //使用 render: h => h(App) }).$mount('#app')
四、state状态存放
1、简介
用于存放全局变量,供任意组件访问
2、使用:$store.state.变量名
(1)在store.js这个封装文件,定义需要的变量
import Vuex from 'vuex' import Vue from 'vue' Vue.use(Vuex) const store = new Vuex.Store({ state:{ count:0, userInfo:[ { name:'申小兮', age:18, }, { name:'老墨', age:34, }, ] }, }) export default store
(2)在任意vue文件进行输出,显示
<template> <div class="home"> <h1>这是count:{{ $store.state.count }}</h1> <h1>卖鱼的{{ $store.state.userInfo[1].name }}</h1> <!-- <HelloWorld msg="Welcome to Your Vue.js App"/> --> </div> </template> <script> // @ is an alias to /src export default { name: 'HomeView', created(){ console.log('count',this.$store.state.count); console.log('userInfo',this.$store.state.userInfo); } } </script>
五、getters状态派生
1、简介
有时候我们需要从 store 中的 state 中派生出一些状态,类似Vue中的computed
计算属性的功能,例如:格式化数据等。
处理数据:当我们想用或修改的数据,在多个组件或页面,且需要统一修改时,这个状态可以很方便进行修改。
使用:$store.getters.变量名
2、参数
(1)state参数:每个getters
都是一个方法,接受 state 作为其第一个参数,用来访问vuex中的state数据
import Vuex from 'vuex' import Vue from 'vue' Vue.use(Vuex) const store = new Vuex.Store({ state:{ count:0, userInfo:[ { name:'申小兮', age:18, }, { name:'老墨', age:34, }, ] }, getters:{ info(state){ console.log(state); return `告诉${state.userInfo[1].name},我想吃鱼了` } } }) export default store
<template> <div class="home"> <h1>这是count:{{ $store.state.count }}</h1> <h1>卖鱼的{{ $store.state.userInfo[1].name }}</h1> <h2>{{ $store.getters.info }}</h2> <!-- <HelloWorld msg="Welcome to Your Vue.js App"/> --> </div> </template> <script> // @ is an alias to /src export default { name: 'HomeView', created(){ // console.log('count',this.$store.state.count); // console.log('userInfo',this.$store.state.userInfo); console.log('getters',this.$store.getters.info); } } </script>
(2)getter参数:获取自己本身的数据
getters:{ info(state,getter){ console.log('state:',state); console.log('getter:',getter); return `告诉${state.userInfo[1].name},我想吃鱼了` } }
3、绑定点击改值事件
事件的错误使用
<template> <div class="home"> <h1>这是count:{{ $store.state.count }}</h1> <div> <button @click="add">+</button> <button @click="sub">-</button> </div> </div> </template> <script> export default { name: 'HomeView', created(){ console.log('getters',this.$store.getters.info); }, methods:{ add(){ this.$store.state.count++ }, sub(){ } } } </script>
观察上图发现:在点击改变count值时,虽然页面跟着变化了,但是vuex检测系统并没有变化,只有鼠标去触发才会更新
那么怎样才能正确修改count值呢?这时候就要介绍第三个状态mutations🧐
六、mutations状态修改
1、简介
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler),类似Vue【子向父通信】的emit
每个mutations
都是一个方法,接受 state
作为第一个参数,payload
作为第二个参数
(1)state:用来访问vuex中的state数据
(2)payload:获取此次mutation提交的数据荷载
注意:mutation中不能在异步函数里修改state值,必须是同步函数
2、使用
(1)提交形式:$store.commit(type, payload)
(2)state参数
mutations:{ addCount(state){ console.log('M',state); state.count++ } }
add(){ this.$store.commit('addCount') },
(3)payload参数
mutations:{ addCount(state,payload){ console.log('M',state); state.count+=payload } }
add(){ this.$store.commit('addCount',10) },
(4)对象写法
add(){ this.$store.commit({ type:'addCount', num:10 }) },
mutations:{ addCount(state,payload){ console.log('M',state); state.count+=payload.num } }
3、模拟接口
(1)例子1:接口是异步的,我们用定时器类比
mutations:{ getStudentInfo(state){ setTimeout(()=>{ let info = {name:"张三",age:43} state.studentInfo.push(info) }) } }
created(){ this.$store.commit('getStudentInfo') },
<h3>{{ $store.state.studentInfo }}</h3>
(2) 例子2:在异步中改变count
addCount(state,payload){ console.log('M',state); setTimeout(()=>{ state.count+=payload.num }) },
这时候发现,vue编译器每次会比实际数据慢一次,这个问题是为什么?因为mutation无法处理异步问题
注意:mutation必须是同步函数,这时候就引出第四个状态actions,来解决mutation的异步问题
七、actions状态修改
1、简介
Action 类似于 mutation,不同的是Action用于提交mutation,而不是直接变更状态;且Action 可以包含任意异步操作
2、使用
每个Action
都是一个方法,接受 context
作为第一个参数,payload
作为第二个参数
(1)提交形式:$store.dispatch(type, payload)
(2)参数
①context参数:store实例对象,用以调用mutation
、访问state
②payload参数:获取此次mutation提交的数据荷载
(3)解决第六大点mutations无法解决的异步问题
mutations:{ addCount(state,payload){ console.log('M',state); state.count+=payload.num }, getStudentInfo(state,payload){ state.studentInfo = payload } }, actions:{ getInfoApi(context){ setTimeout(()=>{ let info = {name:"张三",age:43} context.commit('getStudentInfo',info) }) }, addTime(context){ setTimeout(()=>{ context.commit({type:'addCount',num:10}) }) } }
methods:{ add(){ this.$store.dispatch('addTime') }, sub(){ this.$store.dispatch('getInfoApi') } }
<template> <div class="home"> <h1>这是count:{{ $store.state.count }}</h1> <div> <button @click="add">+</button> <button @click="sub">-</button> </div> <h3>{{ $store.state.studentInfo }}</h3> </div> </template>
(4)到这里可能有些小伙伴们已经开始凌乱了,对上面代码逻辑小编的解析如下🧐
(5)几个状态使用的连接
①State:存储数据。调用语句$store.state.变量名
②Getter:更好的处理数据,但是无法实时改变后台数据。调用语句$store.getter.变量名
③Mutation:任意更改state的数据,但是只允许同步函数。调用语句$store.commit(type, payload)
④Action:不能改state数据,但是可以帮助mutation做异步操作。调用语句$store.dispatch(type, payload)
八、Module模块化
1、简介
(1)原因:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
(2)解决:为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。
2、理解
将 store 内的state、mutation、action、getter每个完整的对象分割成一个个单独的模块(module),然后写成一个变量导入。
通常是在做大项目时候才会用上
3、例子
这里举一个简易的例子
(1)将state、mutation、action、getter单独到外面
import Vuex from "vuex"; import Vue from "vue"; Vue.use(Vuex); const moduleA = { namespaced: true, //命名空间 state: { count: 0, }, }; const store = new Vuex.Store({ modules: { a: moduleA, }, }); export default store;
(2)这时候获取及显示数据的写法要有所改变
<template> <div class="about"> <h1>这是count:{{ $store.state.a.count }}</h1> <!-- <h1>This is an about page</h1> --> </div> </template>
4、相关文档
小伙伴们可以查看文档,深入学习🧐
九、拓展
1、关于vuex编写登录模块的思想流程
2、vue-cookie的使用,小伙伴们可以在下面这个网站进行学习
#vue##前端##vuex#Vue的基础语法,组件化开发,CLI,Vue-router,Vuex详解,网络封装,UI框架