吴志勇的博客 吴志勇的博客
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

吴志勇

......
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML5&CSS3

  • CSS预处理语言

  • JavaScript

  • nodejs

  • webpack

  • VUE

    • vue2

      • 01 【Vue简介 初识Vue 模板语法和数据绑定】
      • 02 【el和data的两种写法 MVVM模型】
      • 03 【数据代理 事件处理】
      • 04 【计算属性 侦听属性】
      • 05 【绑定样式 条件渲染 列表渲染】
      • 06 【Vue数据监视 v-model双向绑定】
      • 07 【内置指令 自定义指令】
      • 08 【生命周期 组件】
      • 09 【CLI 初始化脚手架 Vue零碎的一些知识】
      • 10 【组件编码流程 组件自定义事件 全局事件总线】
      • 11 【组件通信】
      • 12 【nextTick 过渡与动画】
      • 13 【代理配置 插槽】
      • 14 【Vuex】
        • 1.理解 Vuex
          • 1.1 Vuex 是什么
          • 1.2 什么时候使用 Vuex
          • 1.3 原理图
        • 2.搭建Vuex环境
        • 3.使用Vuex编写
        • 4.getters 配置项
        • 5.四个map方法的使用
        • 6.模块化+命名空间
      • 15 【Vue-Router】
      • 16 【打包 图片懒加载】
    • vue3

  • react

  • Typescript
  • 前端
  • VUE
  • vue2
wuzhiyong
2024-09-22

14 【Vuex】

# 14 【Vuex】

# 1.理解 Vuex

# 1.1 Vuex 是什么

概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信

image-20220703163518855

image-20220703163536279

# 1.2 什么时候使用 Vuex

1多个组件依赖于同一状态 2来自不同组件的行为需要变更同一状态

# 1.3 原理图

image-20220703163619723

# 2.搭建Vuex环境

  1. 下载安装 pnpm add vuex@3

  2. 创建文件:src/store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'	// 引入Vuex
    
    Vue.use(Vuex)	// 应用Vuex插件
    
    const actions = {}		// 准备actions——用于响应组件中的动作
    const mutations = {}	// 准备mutations——用于操作数据(state)
    const state = {}			// 准备state——用于存储数据
    
    // 创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state,
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
  3. 在main.js中创建vm时传入store配置项

    import Vue from 'vue'
    import App from './App.vue'
    import store from './store'	// 引入store
    
    Vue.config.productionTip = false
    
    new Vue({
    	el: '#app',
    	render: h => h(App),
    	store,	// 配置项添加store
    	beforeCreate() {
    		Vue.prototype.$bus = this
    	}
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

# 3.使用Vuex编写

  1. 初始化数据、配置actions、配置mutations,操作文件store.js

    import Vue from 'vue'
    import Vuex from 'vuex'	// 引入Vuex
    
    Vue.use(Vuex)	// 应用Vuex插件
    
    // 准备actions——用于响应组件中的动作
    const actions = {
    	/* jia(context,value){
    		console.log('actions中的jia被调用了')
    		context.commit('JIA',value)
    	},
    	jian(context,value){
    		console.log('actions中的jian被调用了')
    		context.commit('JIAN',value)
    	}, */
    	jiaOdd(context,value){	// context 相当于精简版的 $store
    		console.log('actions中的jiaOdd被调用了')
    		if(context.state.sum % 2){
    			context.commit('JIA',value)
    		}
    	}
    }
    // 准备mutations——用于操作数据(state)
    const mutations = {
    	JIA(state,value){
    		console.log('mutations中的JIA被调用了')
    		state.sum += value
    	},
    	JIAN(state,value){
    		console.log('mutations中的JIAN被调用了')
    		state.sum -= value
    	}
    }
    // 准备state——用于存储数据
    const state = {
    	sum:0 //当前的和
    }
    
    // 创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state,
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
  2. 组件中读取vuex中的数据:$store.state.sum

  3. 组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据) 或 $store.commit('mutations中的方法名',数据)

    备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

src/components/Count.vue

<template>
	<div>
		<h1>当前求和为:{{ $store.state.sum }}</h1>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
	</div>
</template>

<script>
	export default {
		name:'Count',
		data() {
			return {
				n:1, //用户选择的数字
			}
		},
		methods: {
			increment(){
                // commit 是操作 mutations
				this.$store.commit('JIA',this.n)
			},
			decrement(){
                // commit 是操作 mutations
				this.$store.commit('JIAN',this.n)
			},
			incrementOdd(){
                // dispatch 是操作 actions
				this.$store.dispatch('jiaOdd',this.n)
			},
		}
	}
</script>

<style lang="css">button{margin-left: 5px;}</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 4.getters 配置项

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。

  2. 在store.js中追加getters配置

    ......
    
    const getters = {
    	bigSum(state){
    		return state.sum * 10
    	}
    }
    
    // 创建并暴露store
    export default new Vuex.Store({
    	......
    	getters
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  3. 组件中读取数据:$store.getters.bigSum

# 5.四个map方法的使用

  1. mapState方法:用于帮助我们映射state中的数据为计算属性

    computed: {
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
    1
    2
    3
    4
    5
    6
    7
  2. mapGetters方法:用于帮助我们映射getters中的数据为计算属性

    computed: {
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)
        ...mapGetters(['bigSum'])
    },
    
    1
    2
    3
    4
    5
    6
    7
  3. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

    methods:{
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //靠mapActions生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
    1
    2
    3
    4
    5
    6
    7
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

    methods:{
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    
    1
    2
    3
    4
    5
    6
    7

备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

<template>
	<div>
		<h1>当前求和为:{{ sum }}</h1>
		<h3>当前求和的10倍为:{{ bigSum }}</h3>
		<h3>我是{{ name }},我在{{ school }}学习</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment(n)">+</button>
		<button @click="decrement(n)">-</button>
		<button @click="addOdd(n)">当前求和为奇数再加</button>
		<button @click="addWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'	

	export default {
		name: 'Count',
		data() {
			return {
				n:1, //用户选择的数字
			}
		},
  computed: {		
			...mapState(['sum','school','name']),
			...mapGetters(['bigSum'])
		},
		methods: {
			...mapMutations({increment:'ADD', decrement:'SUBTRACT'}),
			...mapActions(['addOdd', 'addWait'])
		},
	}
</script>

<style>
	button{
		margin-left: 5px;
	}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 6.模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确。

  2. 修改store.js 为了解决不同模块命名冲突的问题,将不同模块的namespaced: true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名

    const countAbout = {
      namespaced:true,//开启命名空间
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//开启命名空间
      state:{ ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
  3. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
    1
    2
    3
    4
  4. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
    1
    2
    3
    4
  5. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
    1
    2
    3
    4
  6. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    
    1
    2
    3
    4

​

上次更新: 2024-09-30 01:09:25

← 13 【代理配置 插槽】 15 【Vue-Router】→

Copyright © 2020-2025 wuzhiyong
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式