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来调用 actions this.$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有五大重要特性,有四个都有对应的辅助函数
- 所有的辅助函数大多是一样的使用方式
-
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>