Vue learning 105~116 (Vuex)

Schematic:

Insert image description here

4.1 Concept

​ A Vue plug-in that implements centralized state (data) management in Vue. It centrally manages (read/write) the shared state of multiple components in a Vue application. It is also a method of communication between components and is suitable for Communication between arbitrary components.

4.2 When to use Vuex?

  1. Multiple components depend on同一state
  2. Behavior from different components needs to change同一State

4.3 Build the vuex environment

In vue2, you need to use version 3 of vuex

npm i vuex@3

In vue3, you need to use version 4 of vuex

  1. Create a file:src/store/index.js

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //应用Vuex插件
    Vue.use(Vuex)
    
    //准备actions对象——响应组件中用户的动作
    const actions = {
          
          }
    //准备mutations对象——修改state中的数据
    const mutations = {
          
          }
    //准备state对象——保存具体的数据
    const state = {
          
          }
    
    //创建并暴露store
    export default new Vuex.Store({
          
          
    	actions,
    	mutations,
    	state
    })
    
  2. Pass in the configuration item when creating the vm inmain.jsstore

    ......
    //引入store
    import store from './store'
    ......
    
    //创建vm
    new Vue({
          
          
    	el:'#app',
    	render: h => h(App),
    	store
    })
    

4.4 Basic usage

  1. Initialization data, configurationactions, configurationmutations, operation filestore.js

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //引用Vuex
    Vue.use(Vuex)
    
    const actions = {
          
          
        //响应组件中加的动作
    	jia(context,value){
          
          
    		// console.log('actions中的jia被调用了',miniStore,value)
    		context.commit('JIA',value)
    	},
    }
    
    const mutations = {
          
          
        //执行加
    	JIA(state,value){
          
          
    		// console.log('mutations中的JIA被调用了',state,value)
    		state.sum += value
    	}
    }
    
    //初始化数据
    const state = {
          
          
       sum:0
    }
    
    //创建并暴露store
    export default new Vuex.Store({
          
          
    	actions,
    	mutations,
    	state,
    })
    
  2. Read data from vuex in the component:$store.state.sum

  3. Modify the data in vuex in the component: $store.dispatch('action中的方法名',数据) or $store.commit('mutations中的方法名',数据)

    Note: If there is no network request or other business logic, you can also skip actions in the component, that is, do not write dispatch but write directlycommit

Specific case:

index.js

//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(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){
    
    
		console.log('actions中的jiaOdd被调用了')
		if(context.state.sum % 2){
    
    
			context.commit('JIA',value)
		}
	},
	jiaWait(context,value){
    
    
		console.log('actions中的jiaWait被调用了')
		setTimeout(()=>{
    
    
			context.commit('JIA',value)
		},500)
	}
}
//准备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,
})

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>
		<button @click="incrementWait">等一等再加</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)
			},
			incrementWait(){
      
      
                // dispatch 是操作 actions
				this.$store.dispatch('jiaWait',this.n)
			},
		},
		mounted() {
      
      
			console.log('Count',this)
		},
	}
</script>

<style lang="css">
	button{
      
      
		margin-left: 5px;
	}
</style>

4.5 Use of getters

  1. Concept: When the data in the state needs to be processed before use, getters can be used for processing.

  2. Existingstore.jsAdditionallygettersPlacement

    ......
    
    const getters = {
          
          
    	bigSum(state){
          
          
    		return state.sum * 10
    	}
    }
    
    //创建并暴露store
    export default new Vuex.Store({
          
          
    	......
    	getters
    })
    
  3. Read data from the component:$store.getters.bigSum

4.6 Use of four map methods

import

import {
    
    mapState, mapGetters, mapActions, mapMutations} from 'vuex'
  1. mapState method: is used to help us map the data in state to computed properties

    computed: {
          
          
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({
          
          sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
  2. mapGetters method: is used to help us map the data in getters to computed properties

    computed: {
          
          
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({
          
          bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)
        ...mapGetters(['bigSum'])
    },
    
  3. mapActions method: is used to help us generate a method to talk to actions, that is: a function containing $store.dispatch(xxx)

    methods:{
          
          
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({
          
          incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //靠mapActions生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
  4. mapMutations method: is used to help us generate a method that talks to mutations, that is: a function containing $store.commit(xxx)

    methods:{
          
          
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({
          
          increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    

Note: When using mapActions and mapMutations, if you need to pass parameters, you need to: pass the parameters when binding the event in the template, otherwise the parameters passed are event objects (events).

Specific case:

<template>
  <div>
    <h1>当前求和为:{
   
   { sum }}</h1>
    <h3>当前求和放大10倍为:{
   
   { bigSum }}</h3>
    <h3>年龄:{
   
   { age }}</h3>
    <h3>姓名:{
   
   {name}}</h3>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
	<!-- 用了mapActions 和 mapMutations 的话要主动传参 -->
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">当前求和为奇数再加</button>
    <button @click="incrementWait(n)">等一等再加</button>
  </div>
</template>

<script>
import {
      
       mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
      
      
  name: "Count",
  data() {
      
      
    return {
      
      
      n: 1, //用户选择的数字
    };
  },
  computed: {
      
      
	...mapState(['sum', 'age', 'name']),
	...mapGetters(['bigSum'])  
  },
  methods: {
      
      
    ...mapActions({
      
      incrementOdd: 'sumOdd', incrementWait: 'sumWait'}),
    ...mapMutations({
      
      increment: 'sum', decrement: 'reduce'})
  },
  mounted() {
      
      
    console.log("Count", this);
  },
};
</script>

<style lang="css">
button {
      
      
  margin-left: 5px;
}
</style>

4.7 Modularity + Namespace

  1. Purpose: Make the code easier to maintain and make the classification of various data more clear.

  2. Revisestore.js

    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
      }
    })
    
  3. After opening the namespace, read the state data in the component:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    // 用 mapState 取 countAbout 中的state 必须加上 'countAbout'
    ...mapState('countAbout',['sum','school','subject']),
    
  4. After opening the namespace, read the getters data in the component:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  5. After opening the namespace, call dispatch in the component

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{
          
          incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. After opening the namespace, call commit in the component

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

Specific case:
count.js

//求和相关的配置
export default {
    
    
	namespaced:true,
	actions:{
    
    
		jiaOdd(context,value){
    
    
			console.log('actions中的jiaOdd被调用了')
			if(context.state.sum % 2){
    
    
				context.commit('JIA',value)
			}
		},
		jiaWait(context,value){
    
    
			console.log('actions中的jiaWait被调用了')
			setTimeout(()=>{
    
    
				context.commit('JIA',value)
			},500)
		}
	},
	mutations:{
    
    
		JIA(state,value){
    
    
			console.log('mutations中的JIA被调用了')
			state.sum += value
		},
		JIAN(state,value){
    
    
			console.log('mutations中的JIAN被调用了')
			state.sum -= value
		},
	},
	state:{
    
    
		sum:0, //当前的和
		school:'尚硅谷',
		subject:'前端',
	},
	getters:{
    
    
		bigSum(state){
    
    
			return state.sum*10
		}
	},
}

person.js

//人员管理相关的配置
import axios from 'axios'
import {
    
     nanoid } from 'nanoid'
export default {
    
    
	namespaced:true,
	actions:{
    
    
		addPersonWang(context,value){
    
    
			if(value.name.indexOf('王') === 0){
    
    
				context.commit('ADD_PERSON',value)
			}else{
    
    
				alert('添加的人必须姓王!')
			}
		},
		addPersonServer(context){
    
    
			axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
				response => {
    
    
					context.commit('ADD_PERSON',{
    
    id:nanoid(),name:response.data})
				},
				error => {
    
    
					alert(error.message)
				}
			)
		}
	},
	mutations:{
    
    
		ADD_PERSON(state,value){
    
    
			console.log('mutations中的ADD_PERSON被调用了')
			state.personList.unshift(value)
		}
	},
	state:{
    
    
		personList:[
			{
    
    id:'001',name:'张三'}
		]
	},
	getters:{
    
    
		firstPersonName(state){
    
    
			return state.personList[0].name
		}
	},
}

index.js

//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//应用Vuex插件
Vue.use(Vuex)

//创建并暴露store
export default new Vuex.Store({
    
    
	modules:{
    
    
		countAbout:countOptions,
		personAbout:personOptions
	}
})

count.vue

<template>
	<div>
		<h1>当前求和为:{
   
   {sum}}</h1>
		<h3>当前求和放大10倍为:{
   
   {bigSum}}</h3>
		<h3>我在{
   
   {school}},学习{
   
   {subject}}</h3>
		<h3 style="color:red">Person组件的总人数是:{
   
   {personList.length}}</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="incrementOdd(n)">当前求和为奇数再加</button>
		<button @click="incrementWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import {
      
      mapState,mapGetters,mapMutations,mapActions} from 'vuex'
	export default {
      
      
		name:'Count',
		data() {
      
      
			return {
      
      
				n:1, //用户选择的数字
			}
		},
		computed:{
      
      
			//借助mapState生成计算属性,从state中读取数据。(数组写法)
			...mapState('countAbout',['sum','school','subject']),
			...mapState('personAbout',['personList']),
			//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
			...mapGetters('countAbout',['bigSum'])
		},
		methods: {
      
      
			//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
			...mapMutations('countAbout',{
      
      increment:'JIA',decrement:'JIAN'}),
			//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
			...mapActions('countAbout',{
      
      incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
		},
		mounted() {
      
      
			console.log(this.$store)
		},
	}
</script>

<style lang="css">
	button{
      
      
		margin-left: 5px;
	}
</style>

person.view

<template>
	<div>
		<h1>人员列表</h1>
		<h3 style="color:red">Count组件求和为:{
   
   {sum}}</h3>
		<h3>列表中第一个人的名字是:{
   
   {firstPersonName}}</h3>
		<input type="text" placeholder="请输入名字" v-model="name">
		<button @click="add">添加</button>
		<button @click="addWang">添加一个姓王的人</button>
		<button @click="addPersonServer">添加一个人,名字随机</button>
		<ul>
			<li v-for="p in personList" :key="p.id">{
   
   {p.name}}</li>
		</ul>
	</div>
</template>

<script>
	import {
      
      nanoid} from 'nanoid'
	export default {
      
      
		name:'Person',
		data() {
      
      
			return {
      
      
				name:''
			}
		},
		computed:{
      
      
			personList(){
      
      
				return this.$store.state.personAbout.personList
			},
			sum(){
      
      
				return this.$store.state.countAbout.sum
			},
			firstPersonName(){
      
      
				return this.$store.getters['personAbout/firstPersonName']
			}
		},
		methods: {
      
      
			add(){
      
      
				const personObj = {
      
      id:nanoid(),name:this.name}
				this.$store.commit('personAbout/ADD_PERSON',personObj)
				this.name = ''
			},
			addWang(){
      
      
				const personObj = {
      
      id:nanoid(),name:this.name}
				this.$store.dispatch('personAbout/addPersonWang',personObj)
				this.name = ''
			},
			addPersonServer(){
      
      
				this.$store.dispatch('personAbout/addPersonServer')
			}
		},
	}
</script>

Guess you like

Origin blog.csdn.net/m0_57809042/article/details/129688900