20230422----重返学习-vue数据集中管理vuex
day-055-fifty-five-20230422-vue数据集中管理vuex
vuex
vuex的说明
- vuex是专门为vue提供的大仓库,采用状态管理的大仓库
- Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
- 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex与vue版本的关联
- 一般vuex要比vue的版本多1
- vue2 —> vuex3
- vue3 —> vuex4
vuedevtools安装
- 解压vuedevtools文件夹
- 打开谷歌浏览器进行安装
- 网页右上角没有的V可以点开这个拼图图标,然后把V置顶就出现了
- 安装完成后,需要重新启动vue项目
安装vuex
-
方法1. 创建项目的时候,直接选vuex
- src目录先多一个文件夹 store —> index.js(写好的模板)导出仓库
-
多一个文件
/src/store/index.js
,里面会让vue使用vuex这个插件,同时初始化一个Vuex实例对象,并导出。import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)//让Vue构造函数使用了Vuex这个vue插件 const store=new Vuex.Store({})// 创建一个Vuex实例对象 export default store;// 导出Vuex实例对象
-
/src/main.js
中会导入Vuex实例对象,并将其挂载到根Vue实例对象上。import store from './store' let vm=new Vue({store,render: h => h(App) }).$mount('#app')
-
- src目录先多一个文件夹 store —> index.js(写好的模板)导出仓库
-
方法2. 创建项目的,没有选择vuex
-
重新安装vuex这个vue插件的npm依赖
npm install vuex --save//使用npm方式,个人推荐,最基础的方式 //yarn add vuex//yarn方式,npm方式因网络不好时再用
-
安装好vuex之后,项目中关于vuex的什么基础操作都没有,需要自己手动编写和操作
- 安装依赖的作用,主要是可以通过
import Vuex from 'vuex'
在项目中可以导入Vuex这个vue插件。
- 安装依赖的作用,主要是可以通过
-
src目录先多一个文件夹 store —> index.js(写好的模板)导出仓库
-
多一个文件
/src/store/index.js
,里面会让vue使用vuex这个插件,同时初始化一个Vuex实例对象,并导出。import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)//让Vue构造函数使用了Vuex这个vue插件 const store=new Vuex.Store({})// 创建一个Vuex实例对象 export default store;// 导出Vuex实例对象
-
/src/main.js
中会导入Vuex实例对象,并将其挂载到根Vue实例对象上。import store from './store' let vm=new Vue({store,render: h => h(App) }).$mount('#app')
-
-
vue五大模块
-
state: {}
相当于vue中的data-
设置值:
export default new Vuex.Store({state: {num:100,str:"hello"} })
-
获取值:
-
通过this.$store.state拿到state对象里的数据
-
直接取
<template><div>{{ $store.state.num }}</div> </template>
<script> export default {mounted() {this.$store.state.num} }; </script>
-
通过data取
<script> export default {data(){return {dataNum:this.$store.state.num}} }; </script>
-
通过computed
- 推荐
<script> export default {computed:{//推荐dataNum(){return this.$store.state.num}} }; </script>
-
-
通过mapState()辅助函数拿到state对象里的数据
-
mapState()辅助函数
- 推荐
<template><div>{{ num }}--{{ str }}</div> </template> <script> import { mapState } from 'vuex'; export default {computed:mapState(["num","str"]) }; </script>
-
步骤
-
引入
import { mapState } from 'vuex';
-
配合计算属性使用
computed:mapState(["num","str"])
computed:{...mapState(["num","str"])}
-
-
使用类型
-
数组:直接接收,直接使用
<template><div>{{ num }}--{{ str }}</div> </template> <script> import { mapState } from 'vuex'; export default {computed:mapState(["num","str"]) }; </script>
-
对象:接收后,换一个名称
<template><div>{{ nn }}---{{ ss }}---{{ mm }}</div> </template> <script> import { mapState } from 'vuex'; export default {computed:mapState({nn:state=>state.num,//使用函数的方式ss:"str",//使用字符串的方式//使用函数ES6简写的方式mm(state){return state.num+200}}) }; </script>
-
-
辅助函数 与 计算属性的其他属性共存
<template><div>{{ nn }}---{{ fullName }}---{{ str }}</div> </template> <script> import { mapState } from 'vuex'; export default {computed:{...mapState({nn:state=>state.num}),fullName(){return 5555},...mapState(['str'])} }; </script>
-
-
-
-
getters: {}
: 相当于vue中的计算属性,对state的数据二次处理-
函数的写法,属性的用法。
-
设置值:
export default new Vuex.Store({state: {arr:[10,20,30,40,50,60]},getters:{//函数的写法,属性的用法//作用 state里面的数据进行二次处理返回//箭头函数写法newarr:(state)=>{return state.arr.filter((item)=>item>30)}//ES6写法//newarr(state) {// return state.arr.filter((item) => item > 30);//},} })
export default new Vuex.Store({state: {arr:[10,20,30,40,50,60]},getters:{//ES6写法newarr(state) {return state.arr.filter((item) => item > 30);},} })
-
获取值:
-
通过this.$store.state拿到getters对象里的数据
-
直接取
<template><div>{{ $store.getters.newarr }}</div> </template>
<script> export default {mounted() {this.$store.getters.newarr} }; </script>
-
通过data取
<script> export default {mounted() {this.dataNum},data(){return {dataNum:this.$store.getters.newarr}} }; </script>
-
通过computed
- 推荐
<script> export default {mounted() {this.computedNum},computed:{//推荐computedNum(){return this.$store.getters.newarr}} }; </script>
-
-
通过mapGetters()辅助函数拿到getters对象里的数据
-
mapGetters()辅助函数
- 推荐
<template><div>{{ newarr }}</div> </template> <script> import { mapGetters } from 'vuex'; export default {computed:mapGetters(["newarr"]) }; </script>
-
步骤
-
引入
import { mapGetters } from 'vuex';
-
配合计算属性使用
computed:mapGetters(["newarr"])
computed:{...mapGetters(["newarr"])}
-
-
使用类型
-
数组:直接接收,直接使用
<template><div>{{ newarr }}</div> </template> <script> import { mapGetters } from 'vuex'; export default {computed:mapGetters(["newarr"]) }; </script>
-
对象:接收后,换一个名称
<template><div>{{ arr }}</div> </template> <script> import { mapGetters } from 'vuex'; export default {computed:mapGetters({arr:"newarr"}) }; </script>
-
-
辅助函数 与 计算属性的其他属性共存
<template><div>{{ newarr }}---{{ arr }}</div> </template> <script> import { mapGetters } from 'vuex'; export default {computed:{...mapGetters(["newarr"]),fullName(){return 5555},...mapGetters({arr:"newarr"})} }; </script>
-
-
-
-
mutations: {}
同步方法(仓库管理员)-
vuex是单向数据流,state只能通过Mutation来修改
-
设置方法:
export default new Vuex.Store({state: {num:100},mutations: {//箭头函数写法//无入参addNum:(state)=>{state.num++},} })
export default new Vuex.Store({state: {num:100},mutations: {//箭头函数写法//有入参addNum:(state,payload)=>{//console.log(payload);//state.num++state.num+=payload.n;}} })
export default new Vuex.Store({state: {num:100},mutations: {//ES6简写写法//无入参addNum(state){state.num++},} })
export default new Vuex.Store({state: {num:100},mutations: {//ES6简写写法//有入参addNum(state,payload){console.log(payload);state.num+=payload.n;}} })
-
使用方法:
-
通过this.$store.commit()使用mutations对象里的同步方法
-
要想执行 mutations里面的方法,必须通过 commit()
- commit(函数名,参数) 只有两个值
- 如果第二个
参数
那里,想要传递多个内容,可以使用数组,对象
- 如果第二个
<template><div>{{ $store.state.num }}<button @click="add">add</button></div> </template><script> export default {methods:{// add(){//页面数据可以修改,仓库数据无法修改// this.$store.state.num++;// }add(){//要想执行 mutations里面的方法,必须通过 commit()//commit(函数名,参数) 只有两个值 //如果第二个“参数”,想要传递多个内容,数组,对象this.$store.commit("addNum",{n:10,m:20})}} } </script>
- commit(函数名,参数) 只有两个值
-
-
通过mapMutations()辅助函数使用mutations对象里的同步方法
-
mapMutations()辅助函数
<template><div>{{ $store.state.num }}<button @click="add({n:10,m:20})">add</button></div> </template> <script> import { mapMutations } from 'vuex'; export default {methods:{...mapMutations({add:"addNum"})} }; </script>
-
步骤
-
引入
import { mapMutations } from 'vuex';
-
配合methods属性使用
methods:mapMutations({add:"addNum"})
methods:{...mapMutations({add:"addNum"})}
-
-
使用类型
-
数组:直接接收,直接使用
<template><div>{{ $store.state.num }}<button @click="addNum({n:10,m:20})">addNum</button></div> </template> <script> import { mapMutations } from 'vuex'; export default {methods:mapMutations(["addNum"]), }; </script>
-
对象:接收后,换一个名称
<template><div>{{ $store.state.num }}<button @click="add({n:10,m:20})">add</button></div> </template> <script> import { mapMutations } from 'vuex'; export default {methods:mapMutations({add:"addNum"}), }; </script>
-
-
辅助函数 与 methods的其他方法共存
<template><div>{{ $store.state.num }}<button @click="addNum({n:10,m:20})">addNum</button><button @click="add({n:10,m:20})">add</button></div> </template> <script> import { mapMutations } from 'vuex'; export default {methods:{...mapMutations(["addNum"]),...mapMutations({add:"addNum"})} }; </script>
-
-
-
-
-
actions: {}
-
设置异步方法
export default new Vuex.Store({state: {n:10}mutations: {addN(state,payload){//通过mutations做异步操作效果实现的不对state.n+=payload;}},actions: {AsyncAddN(context,payload){//console.log(context);//{commit,...}setTimeout(() => {context.commit("addN",payload);}, 1000);}} })
-
使用异步方法
<template><div>{{ $store.state.n }}<button @click="addN()">addN</button></div> </template><script> export default {methods:{addN(){//this.$store.commit("addN")//通过dispatch来调用 actionsthis.$store.dispatch("AsyncAddN",10)}} } </script>
-
使用辅助函数-对象可改名
<template><div>{{ $store.state.n }}<button @click="add(10)">add</button></div> </template><script> import { mapActions } from 'vuex'; export default {methods:{...mapActions({add:"AsyncAddN"})} } </script>
-
使用辅助函数-数组不可改名
<template><div>{{ $store.state.n }}<button @click="AsyncAddN(10)">add</button></div> </template><script> import { mapActions } from 'vuex'; export default {methods:{...mapActions(["AsyncAddN"])} } </script>
-
-
modules: {}
模块,将仓库进行划分,每个模块仍然具有五部分-
模式一: 不区别getters与mutations等
-
设置
const ModelA={state:{arra:[1,2,3,4,5]},getters:{newarra(store){return store.arra.filter((item)=>{return item>3})}} }const ModelB={state:{numb:200},mutations:{changeNum(state){state.numb+=10;}} }export default new Vuex.Store({modules: {a:ModelA,b:ModelB} })
-
使用
<template><div>{{ $store.state.b.numb }}{{ $store.getters.newarra }}<button @click="changeNum()">changeNum</button></div> </template><script> import { mapMutations } from 'vuex'; export default {methods:{...mapMutations(["changeNum"])} } </script>
-
-
模式二:使用命名空间,区别getters与mutations等
namespaced: true,//添加命名空间
-
设置
const ModelC = {namespaced: true,state: {arra: [1, 2, 3, 4, 5],},getters: {newarra(state) {return state.arra.filter((item) => item > 3);},}, };const ModelD = {namespaced: true,state: {numd: 5,},mutations: {changeNumd(state, payload = 10) {state.numd += payload;},},actions: {asyncChangeNumd(context, payload = 100) {setTimeout(() => {context.commit("changeNumd", payload);}, 1000);},}, };export default new Vuex.Store({modules: {c: ModelC,d: ModelD,} })
-
使用
-
方法一,使用命名空间直接访问
<template><div><h1>ModulesView01</h1><div>$store.getters["c/newarra"] --- {{ $store.getters["c/newarra"] }}</div><div>mapGetters('c',['newarra']) --- {{ newarra }}</div><div>{{ $store.state.d.numd }}</div><div><button @click="changeNumd()">同步改变值-辅助函数-数组-mapMutations("d", ["changeNumd"])</button><button @click="asyncChangeNumd()">异步改变值-辅助函数-数组-mapActions("d", ["asyncChangeNumd"])</button></div><div><button @click="handleChange01()">同步改变值-commit-对象-mapMutations({ handleChange01: "d/changeNumd" })</button><button @click="handleChange02()">异步改变值-dispatch-对象-mapActions({ handleChange02:"d/asyncChangeNumd" })</button></div><div><button @click="handleChange03()">同步改变值-辅助函数-对象-mapMutations("d", { handleChange03:"changeNumd" })</button><button @click="handleChange04()">异步改变值-辅助函数-对象-mapActions("d", { handleChange04:"asyncChangeNumd" })</button></div><div><button @click="handleChange05()">同步改变值-commit-this.$store.commit("d/changeNumd", num)</button><button @click="handleChange06()">异步改变值-dispatch-this.$store.dispatch("d/asyncChangeNumd", num)</button></div></div> </template><script> import { mapGetters } from "vuex"; import { mapMutations } from "vuex"; import { mapActions } from "vuex"; export default {computed: {...mapGetters("c", ["newarra"]),},methods: {...mapMutations("d", ["changeNumd"]), //常用,推荐使用方式...mapActions("d", ["asyncChangeNumd"]), //常用,推荐使用方式...mapMutations({ handleChange01: "d/changeNumd" }),...mapActions({ handleChange02: "d/asyncChangeNumd" }),...mapMutations("d", { handleChange03: "changeNumd" }),...mapActions("d", { handleChange04: "asyncChangeNumd" }),handleChange05() {this.$store.commit("d/changeNumd"); //常用,推荐使用方式},handleChange06() {this.$store.dispatch("d/asyncChangeNumd"); //常用,推荐使用方式},}, }; </script>
-
简洁
<template><div><h1>ModulesView01</h1><div>$store.getters["c/newarra"] --- {{ $store.getters["c/newarra"] }}</div><div>mapGetters('c',['newarra']) --- {{ newarra }}</div><div>{{ $store.state.d.numd }}</div><div><button @click="changeNumd()">同步改变值-辅助函数-数组-mapMutations("d", ["changeNumd"])</button></div></div> </template><script> import { mapGetters } from "vuex"; import { mapMutations } from "vuex"; export default {computed: {...mapGetters("c", ["newarra"]),},methods: {...mapMutations("d", ["changeNumd"]), //常用,推荐使用方式}, }; </script>
-
-
方法二:使用
import { createNamespacedHelpers } from "vuex";
<template><div><h1>ModulesView01</h1><div>$store.getters["c/newarra"] --- {{ $store.getters["c/newarra"] }}</div><div>mapGetters(['newarra']) --- {{ newarra }}</div><div>{{ $store.state.d.numd }}</div><div><button @click="changeNumd()">同步改变值-辅助函数-数组-mapMutations(["changeNumd"])</button><button @click="asyncChangeNumd()">异步改变值-辅助函数-数组-mapActions(["asyncChangeNumd"])</button></div><div><button @click="handleChange01()">同步改变值-commit-对象-mapMutations({ handleChange01: "changeNumd" })</button><button @click="handleChange02()">异步改变值-dispatch-对象-mapActions({ handleChange02:"asyncChangeNumd" })</button></div><div><button @click="handleChange05()">同步改变值-commit-this.$store.commit("d/changeNumd", num)</button><button @click="handleChange06()">异步改变值-dispatch-this.$store.dispatch("d/asyncChangeNumd", num)</button></div></div> </template><script> import { createNamespacedHelpers } from "vuex"; const { mapGetters } = createNamespacedHelpers("c"); const { mapMutations } = createNamespacedHelpers("d"); const { mapActions } = createNamespacedHelpers("d"); export default {computed: {...mapGetters(["newarra"]),},methods: {...mapMutations(["changeNumd"]),...mapActions(["asyncChangeNumd"]),...mapMutations({ handleChange01: "changeNumd" }),...mapActions({ handleChange02: "asyncChangeNumd" }),handleChange05() {this.$store.commit("d/changeNumd"); //常用,推荐使用方式},handleChange06() {this.$store.dispatch("d/asyncChangeNumd"); //常用,推荐使用方式},}, }; </script>
-
简洁
<template><div><h1>ModulesView01</h1><div>$store.getters["c/newarra"] --- {{ $store.getters["c/newarra"] }}</div><div>mapGetters(['newarra']) --- {{ newarra }}</div><div>{{ $store.state.d.numd }}</div><div><button @click="changeNumd()">同步改变值-辅助函数-数组-mapMutations(["changeNumd"])</button></div><div><button @click="handleChange05()">同步改变值-commit-this.$store.commit("d/changeNumd", num)</button></div></div> </template><script> import { createNamespacedHelpers } from "vuex"; const { mapGetters } = createNamespacedHelpers("c"); const { mapMutations } = createNamespacedHelpers("d"); export default {computed: {...mapGetters(["newarra"]),},methods: {...mapMutations(["changeNumd"]),handleChange05() {this.$store.commit("d/changeNumd"); //常用,推荐使用方式},}, }; </script>
-
-
-
-
vuex插件
-
日志插件
-
vuex自带一个日志插件用于一般的调试
import createLogger from 'vuex/dist/logger' const store = new Vuex.Store({plugins: [createLogger()] })
-
-
vuex数据持久化插件
- 详见:vuex的数据持久化插件vuex-persistedstate
辅助函数
-
vuex有五大重要特性,有四个都有对应的辅助函数
- 所有的辅助函数大多是一样的使用方式
-
State 相当于vue中的data
-
辅助函数为mapState()
import { mapState } from "vuex";
-
-
Getter 相当于vue中的计算属性,对State的数据二次处理
-
辅助函数为mapGetters()
import { mapGetters } from "vuex";
-
-
Mutation 管理同步方法,专门用来直接修改State中的数据的
-
辅助函数为mapMutations()
import { mapMutations } from "vuex";
-
-
Action 管理异步方法,专门用来调用的Mutation中的同步方法的
-
辅助函数为mapActions()
import { mapActions } from "vuex";
-
-
Module 管理模块的
vuex的作用
- vuex一般有两个作用
- 作用一: 实现数据通信
- 作用二: 数据缓存 切换页面(前进后退),数据不变(缓存); 除非刷新或者关闭
配置一个路由
-
在/src/views/新建一个vue文件,例如叫MutationView.vue
<template><div><h1>MutationView</h1></div> </template><script> export default {} </script>
-
在/src/router/index.js上进行修改,新添加一个动态路由
//一个动态路由{path: '/mutationView',//这个是页面URL路径name: 'MutationView',//这个是路由页面名称component: () => import('../views/MutationView.vue')//这个路径是之前新建文件的文件名。}
import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue'Vue.use(VueRouter)const routes = [{path: '/',name: 'home',component: HomeView},{path: '/about',name: 'about',component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path: '/mutationView',//这个是页面URL路径name: 'MutationView',//这个是路由页面名称,也是webpack的chunk名称component: () => import('../views/MutationView.vue')//这个路径是之前新建文件的文件名。} ]const router = new VueRouter({routes })export default router
-
在根组件上,写一个router-link标签,用于跳转到新建的路由页面。
- router-link标签的to属性与新建路由的页面URL路径保持一致
<template><div id="app"><router-link to="/mutationView">MutationView</router-link><router-view/></div> </template>
进阶参考
- Vue2配合使用的Vuex3官方中文文档
- Vue3配合使用的Vuex4官方中文文档
- Vuex官方中文文档–一般照着这个来就行了-这个一般都是最新版最主流的
- vuedevtools-官方git仓库
- vuex内置-logger-插件
- vuex数据持久化插件