Getting Started Quick Cheats for Vuex State Management of Vue Family Bucket

As an important member of the vue family bucket, we often use vuex in the vue construction project.

About VueX

Vuex is a state management pattern** developed specifically for Vue.js applications . It uses a centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable manner.
VueX is a state management tool suitable for use in Vue project development. Just imagine, if you frequently use component passing parameters to synchronize the values ​​in data in a project development, once the project becomes very large, managing and maintaining these values ​​will be quite a tricky job. To this end, Vue provides a unified management tool for these values ​​frequently used by multiple components - VueX. In a Vue project with VueX, we only need to define these values ​​in VueX to be used in components of the entire Vue project.

Why use vuex
For example: you have several data and several operations that need to be used on multiple components. If each component is called and written, it will be very troublesome, and the code is cumbersome and long. It’s easy to mess up in use. At this time, if we use vuex for unified management, it will be very convenient to manage, and it will be more convenient and concise to modify data.

When should I use Vuex?
Vuex can help us manage shared state and comes with more concepts and frameworks. This requires a trade-off between short-term and long-term benefits.

Using Vuex can be tedious and redundant if you're not planning to develop a large single-page application. It's true - if your application is simple enough, you'd better not use Vuex. A simple store pattern is all you need. However, if you need to build a medium-to-large single-page application, you are likely to consider how to better manage the state outside the component, and Vuex will become a natural choice.

There is no way to share data between vuex components

Passing value from parent to child: v-bind attribute binding

Passing values ​​from child to parent: v-on event binding

Data sharing between sibling components: EventBus

  • $on The component that receives the data
  • $emit The component that sends data

insert image description here

The benefits of using Vuex to manage state uniformly

Vuex is a mechanism to realize the global state (data) management of components, which can facilitate the sharing of data between components.

1. It can centrally manage shared data in vuex, which is easy to develop and maintain later

2. It can efficiently realize data sharing between components and improve development efficiency

3. The data stored in vuex is responsive and can keep the data and page in real time

insert image description here

What is stored in vuex

Multiple components share state and store it in vuex

Private data in a component is still stored in data

For example:

  • The login user name needs to be used on the home page , personal center , and settlement page, and the user name is stored in vuex
  • The article details data can only be viewed on the article details page, and declared in its own data

Basic use of Vuex

1. Install vuex

npm i vuex -S

2.store/index.js - create a definition export store object

Registered in Vue, the function is also an object, you can also point attributes

new A Vuex Store data warehouse

// 1. 引入vuex
import Vuex from 'vuex'
// 2. Vue.use注册使用
Vue.use(Vuex)
// 3. 实例化store对象 这个store对我们的状态进行管理
const store = new Vuex.Store({
    
    
//4.
})
// 5. 导出store对象
export default store

3. Mount the store to the Vue instance of the current project

Import store into main.js

import store from './store'

Vue.config.productionTip = false

new Vue({
    
    
  // 注入到vue实例中
  store, //store:store将我们创建的Vuex实例挂载到这个vue实例中
  render: h => h(App),
}).$mount('#app')

4. Using Vuex in components

For example, in App.vue, we want to display the name defined in the state in the h1 tag

<template>
    <div id='app'>
        name:
        <h1>{
    
    {
    
     $store.state.name }}</h1>
    </div>
</template>

Use of data sources:

It can only be used and mapped directly within the component (the file ending in .APP is a component) (auxiliary function)

In the file ending with the .js suffix, you need to import and use

import store from '@/store' //引入
store.state.token        //使用

state data source

State provides the only public data source, and all shared data must be stored in the State of the Store.

define state

/*语法格式
const store = new Vuex.Store({
    state: {
        变量名: 初始值
    }
})	
*/
//具体代码:
const store = new Vuex.Store({
    
    
    state: {
    
    
        count: 100 // 库存
    }
})

There are 2 ways to use state:

1. The first way for a component to access data in State : within the component - direct use

// this.$store.state.全局数据名称
this.$store.state.count

2. The second way for components to access data in State : within components - mapping (recommended)

// 1. 拿到mapState辅助函数
import {
    
     mapState } from 'vuex'
export default {
    
    
    computed: {
    
    
        // 2. 把state里变量映射到计算属性中
        ...mapState(['count']) //count就是state里的变量名
    }
}

Through the mapState function imported just now, the global data required by the current component will be transferred. Mapped to the computed property of the current component:

<template>
  <div>
    <h3>方法一:当前最新的count值:{
    
    {
    
    $store.state.count}}</h3>
    <h3>方法二-03:当前最新的count值:{
    
    {
    
    count}}</h3>
    <button>+1</button>
  </div>
</template>

<script>
import {
    
     mapState } from 'vuex' //方法二-01

export default {
    
    
  computed: {
    
     //方法二-02
    ...mapState(['count'])
  }
}
</script>

Notice

The state is responsive, as long as the state value changes, the places used on the page will be automatically updated and synchronized

summary

  1. State role?

    Define a global state data source

  2. How is state defined?

    In store, state: {variable name: initial value}

  3. How to use the value of state in specific vue components?

    • Use this.$store.state. variable name directly
    • Mapping uses...mapState(['state variable name'])

mutations - synchronous modification

Mutations are similar to data stewards, manipulating the data in the state

Define mutations in store/index.js

grammar:

/*
const store  = new Vuex.Store({
	mutations: {
		函数名 (state, 可选值) {
			// 同步修改state值代码
		}
	}
})
*/

Reference Code

const store  = new Vuex.Store({
    
    
    state: {
    
    
        count: 100 // 库存
    },
	mutations: {
    
    
		addCount (state, value) {
    
     // 负责增加库存的管家
			state.count += value
		},
        subCount (state, value) {
    
     // 负责减少库存的管家
            state.count -= value
        },
        setCount (state, value) {
    
     // 负责直接修改库存的管家
            state.count = value;
        }
	}
})

Notice

  1. Mutations are the only place where state can be modified, ensuring that debugging tools can track changes
  2. In the mutations function, only synchronous code can be written, and the debugging tool can track the change process
    • Because the debugging tool needs to generate a record immediately , it must be synchronous

summary

  1. Functions in mutations?

    • Responsible for modifying the data in the state
  2. What kind of code can only be written in mutations?

    • code for synchronous process

2 ways to use mutations

  • Method 1: Inside the component - use d directly

    grammar:

    this.$store.commit("mutations里的函数名", 具体值)
    
  • Method 2: In-component- mapping usage

    grammar:

    // 1. 拿到mapMutations辅助函数
    import {
          
           mapMutations } from 'vuex'
    export default {
          
          
        methods: {
          
          
            // 2. 把mutations里方法映射到原地
            ...mapMutations(['mutations里的函数名'])
        }
    }
    

AddItem directly use

  • Click event binding
  • Submit mutations incoming values
<button @click="addFn">库存+1</button>

<script>
export default {
  methods: {
    addFn(){
      this.$store.commit('addCount', 1)
    }
  }
}
</script>

App.vue is used directly

  • Trigger the set method of the computed property
  • Submit mutations incoming values
<span>库存总数: </span>
<input type="text" v-model="count">

<script>
export default {
  computed: {
    count: {
      set(val){
        this.$store.commit('setCount', val) // 把表单值提交给store下的mutations
      },
      get(){
        return this.$store.state.count
      }
    }
  }
}
</script>

SubItem mapping for

  • click event
  • Methods for mapping mutations
  • Call the mutations method to pass the value
<button @click="subFn">库存-1</button>

<script>
// 需求2: 映射mutations到方法里
// 1. 拿到辅助函数 mapMutations
// 2. 在methods内, ...mapMutations(['mutations函数名'])
// 3. 当普通方法使用

import { mapMutations } from 'vuex'
export default {
  methods: {
    ...mapMutations(['subCount']),
    subFn(){
      this.subCount(1)
    }
  }
}
</script>

Notice

On the mutations function, only one parameter value can be received , if the correct one is passed, please pass an object

summary

  1. What are the 2 ways to use mutations?

    Use this.$store.commit() directly

    Mapping uses mapMutations to map methods to direct calls in components

  2. state, mutations, view components, what are the 3 relationships?

insert image description here

actions - asynchronous modification

Action is similar to mutation, the difference is:

  • Actions submit mutations instead of directly changing the state.
  • Action can contain arbitrary asynchronous operations.

If you change data through asynchronous operations, you must use Action instead of Mutation, but you still need to indirectly change data by triggering Mutation in Action.

define actions

Define actions in store/index.js

grammar:

/*
const store = new Vuex.Store({
	actions: {
		函数名 (store, 可选值) {
			// 异步代码, 把结果commit给mutations给state赋值
		}
	}
})
*/

Specific code:

const store  = new Vuex.Store({
    
    
    // ...省略state和mutations此处
    actions: {
    
    
        asyncAddCount(store, num){
    
    
            setTimeout(() => {
    
     // 1秒后, 异步提交给add的mutations
                store.commit('addCount', num)
            }, 1000)
        },
        asyncSubCount(store, num) {
    
    
            setTimeout(() => {
    
     // 1秒后, 异步提交给sub的mutations
                store.commit('subCount', num)
            }, 1000)
        }
    }
})

summary

  1. What is the difference between actions and mutations?

    Synchronously modify state in mutations

    Put asynchronous operations in actions

  2. Can actions manipulate state?

    Not recommended, commit to mutations (trackable for debugging tools)

  3. What is the first formal parameter of the functions in actions and mutations?

    mutations are state

    actions are store

2 ways to use actions

  • Method 1: In the component - direct use

    grammar:

    this.$store.dispatch('actions函数名', 具体值)
    
  • Method 2: In-component- mapping usage

    grammar:

    // 1. 拿到mapActions辅助函数
    import {
          
           mapActions } from 'vuex'
    export default {
          
          
        methods: {
          
          
            // 2. 把actions里方法映射到原地
            ...mapActions(['actions里的函数名'])
        }
    }
    

Case code:

AddItem directly use

  • click event
  • dispatch triggers action
<button @click="asyncAddFn">延迟1秒, 库存+5</button>

<script>
export default {
  methods: {
    asyncAddFn(){
      this.$store.dispatch('asyncAddCount', 5)
    }
  }
}
</script>

SubItem mapping for

  • click event
  • Methods for mapping actions
  • Call the method of actions to pass the value
<button @click="asyncSubFn">延迟1秒, 库存-5</button>

<script>
// 需求3: 映射actions到方法里
// 1. 拿到辅助函数 mapActions
// 2. 在methods内, ...mapActions(['actions函数名'])
// 3. 当普通方法使用

import { mapActions } from 'vuex'
export default {
  methods: {
    ...mapActions(['asyncSubCount']),
    asyncSubFn(){
      this.asyncSubCount(5)
    }
  }
}
</script>

summary

  1. How to use actions?

    Method 1: this.$store.dispatch('actions method name', value)

    Method 2: …mapActions(['method name in actions']) is mapped to in-place use

  2. What is the relationship between view components, state, mutations, and actions?

insert image description here

getters - computed properties

concept of getters

computed properties of vuex,

Getter is used to process the data in the Store to form new data.

  • 1. Getter is similar to Vue's computed property
  • 2. When the data in the Store changes, the Getter data will also change

define getters

Define getters in store/index.js

grammar:

// 定义 Getter
const store = new Vuex.Store({
    
    
    state: {
    
    
        count: 0
    },
    getters: {
    
    
        getSum: state => {
    
    
            return `当前的新数据是【${
      
      state}`
        }
    }
})

2 ways to use getters

  • Method 1: In the component - direct use

    grammar:

    //this.$store.getters.计算属性名
    this.$store.getters.getSum
    
  • Method 2: In-component- mapping usage

    grammar:

    // 1. 拿到mapGetters辅助函数
    import {
          
           mapGetters } from 'vuex'
    export default {
          
          
    	computed: {
          
          
            // 2. 把getters里属性映射到原地
          ...mapGetters(['getSum'])
        }   
    }
    

modules- sub-module

When the project is huge and has many states, the modular management mode can be adopted. Vuex allows us to split the store into modules . Each module has its own state、mutation、action、getter, and even nested, submodules - split the same way from top to bottom.

The following is a comparison between modules and sub-modules:

insert image description here

Create modules module object

  • New store/modules/user.js
  • New store/modules/cart.js

Grammar: The object contains 5 core concepts, only the state becomes a function form

user.js - the user module object

// 用户模块对象
const userModule = {
    
    
    state(){
    
    
        return {
    
    
            name: "",
            age: 0,
            sex: ''
        }
    },
    mutations: {
    
    },
    actions: {
    
    },
    getters: {
    
    }
}
export default userModule

cart.js - shopping cart module object

// 购物车模块对象
import axios from 'axios'
const cartModule = {
    
    
    state() {
    
    
        return {
    
    
            goodsList: []
        }
    },
    mutations: {
    
    
        setGoodsList(state, newList) {
    
    
            state.goodsList = newList
        }
    },
    actions: {
    
    
        async asyncGetGoodsList(store) {
    
    
            const url = `https://www.escook.cn/api/cart`
            // 发送异步请求
            const res = await axios({
    
     url: url });
            store.commit('setGoodsList', res.data.list) // 提交mutation修改state中的数据
        }
    },
    getters: {
    
    
        allCount(state) {
    
    
            return state.goodsList.reduce((sum, obj) => {
    
    
                if (obj.goods_state === true) {
    
     // 选中商品才累加数量
                    sum += obj.goods_count;
                }
                return sum;
            }, 0)
        },
        allPrice(state) {
    
    
            return state.goodsList.reduce((sum, obj) => {
    
    
                if (obj.goods_state) {
    
    
                    sum += obj.goods_count * obj.goods_price
                }
                return sum;
            }, 0)
        }
    }
}
export default cartModule

define modules

grammar:

modules: {
    
    
    模块名: 模块对象
}
  • Bring 2 module objects back to the store for registration
import Vue from 'vue'
import Vuex from 'vuex'
import cartModule from './modules/cart'
import userModule from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
    
    
    modules: {
    
    
        user: userModule,
        cart: cartModule
    }
})
export default store

summary

  1. Why sub-modules?

    The centralized management project is too large and there are too many variables, which will lead to bloated state and difficult maintenance

  2. How to divide modules?

    Define the module object , the state becomes the function return object form, each module has state/mutations/actions/getters/modules

  3. How to register the root store?

    In modules { module name: module object }

sub-module-namespace

Target

  • Prevent name conflicts of mutations/actions/getters between multiple modules

Enable namespace

set inside the module objectnamespaced: true

const moduleShopCar = {
    
    
    namespaced: true,
    state () {
    
    },
    mutations: {
    
    },
    actions: {
    
    },
    getters: {
    
    },
    modules: {
    
    }
}

state usage modification

  • Direct use without change: this.$store.state.module name.variable name

  • Helper functions need to respect the format

    ...mapState("模块名", ['state变量名'])
    

mutations usage modification

  • Method 1: In the component - direct use

    • Original syntax:

      this.$store.commit("mutations里的函数名", 具体值)
      
    • Syntax after opening a namespace:

      this.$store.commit("模块名/mutations里的函数名", 具体值)
      
  • Method 2: In-component- mapping usage

    • Original syntax:

      ...mapMutations(['mutations里方法名'])
      
    • Syntax after opening a namespace:

      ...mapMutations("模块名", ['mutations里方法名'])
      

Actions usage modification

  • Method 1: In the component - direct use

    • Original syntax:

      this.$store.dispatch("actions里的函数名", 具体值)
      
    • Syntax after opening a namespace:

      this.$store.dispatch("模块名/actions里的函数名", 具体值)
      
  • Method 2: In-component- mapping usage

    • Original syntax:

      ...mapActions(['actions里方法名'])
      
    • Syntax after opening a namespace:

      ...mapActions("模块名", ['actions里方法名'])
      

Getters usage modification

  • Method 1: In the component - direct use

    • Original syntax:

      this.$store.getters.计算属性名
      
    • Syntax after opening a namespace:

      this.$store.getters['模块名/计算属性名']
      
  • Method 2: In-component- mapping usage

    • Original syntax:

      ...mapGetters(['getters里计算属性名'])
      
    • Syntax after opening a namespace:

      ...mapGetters("模块名", ['getters里计算属性名'])
      

summary

  1. What is the difference between state and mutations, in the root store and in the open namespace?

insert image description here

  1. What is the whole vuex system?

    insert image description here

Extension: Use Devtools to debug vuex data

Excellent debugging tools can make us write programs with half the effort. Finally, let's learn how to use dev-tools to debug the data in vuex, which is also an indispensable part of the predictable data feature.

Target

  • Master dev-tools debugging vuex
  • Understand what data state is traceable

how to debug

Note that only vue+vuex projects can be used

insert image description here

Description of debugging information

insert image description here

Guess you like

Origin blog.csdn.net/weixin_48585264/article/details/119521624