Please move to understand the core concept of vuex/zh/
1. Initial vuex
1.1 What is vuex
Let’s take a look at these two questions first:
What is vuex? The official website says: Vuex is a state management model specially developed for applications. In a common sense, vuex is used to manage some states between various components, which can be understood as these states are public (shared) parts. At this time, any component can obtain state from it or trigger some behavioral events.
Under what circumstances should vuex be used? The official website says: If you do not plan to develop large single-page applications, using Vuex may be tedious and redundant. It's true - if your application is simple enough, you'd better not use Vuex. A simpleglobal event bus It's enough for you to need. However, if you need to build a medium-to-large single page application, you will most likely consider how to better manage state outside of components, and Vuex will be a natural choice.
OK, so now I will think that you are developing a relatively large project. Will you use vuex in those places? As the complexity of the application increases, the data or component states will be passed between components. For example: When component A enters component B (page A enters page B), you often need to bring some parameters. Then at this time, you may choose to place it behind the url as a parameter to pass it. If you don't want to easily expose the parameters, you may save it in the session or localstorage first, and then take it out when you enter the second page. Yes, this is indeed a solution, and it is used a lot. But this is not a good way, at this time, you need vuex to help you. In addition, when you basically understand some of the superficial aspects of vuex, you will find that vuex management is based on modularity, which is very friendly to project post-management and maintenance.
so, now you have to get a deeper understanding of the core concept of vuex. The following is a concept of personal understanding. First of all, it is recommended to put the official documents first.Vuex2.0 conceptGo through it once.
vuex stores all the variables that need to be shared in one object, and then puts this object in the top-level component for other components to use
When parent-child components communicate, we usually use props + emit. However, when the communication parties are not parent-child components or even have no correlation at all, or a state needs to be shared with multiple components, it will be very troublesome and the data will be quite difficult to maintain.
1.2 What is in vuex
const store = new ({ state: { name: 'weish', age: 22 }, getters: { personInfo(state) { return `My name is ${}, I am ${}`; } } mutations: { SET_AGE(state, age) { commit(age, age); } }, actions: { nameAsyn({commit}) { setTimeout(() => { commit('SET_AGE', 18); }, 1000); } }, modules: { a: modulesA } }
This is the most basic and complete vuex code; vuex contains five basic objects
- state: Store state. That is, variables;
- getters : derived state. That is, get in set and get, there are two optional parameters: state and getters to get variables in state and other getters respectively. External calling method: (). It's almost the same as vue's computed;
- mutations: Submit status modification. That is, set in set and get, this is the only way to modify state in vuex, but it does not support asynchronous operations. The first parameter is state by default. External call method: ('SET_AGE', 18) . Similar to methods in vue.
- actions: Similar to mutations. However, actions support asynchronous operations. The first parameter is an object with the same parameter attribute as store. External call method: ('nameAsyn') .
- modules: The submodule of store, the content is equivalent to an instance of store. The call method is similar to the one introduced earlier, except that the current submodule name must be added, such as: ()
1.3 How to use vuex in vue-cli
Directory structure
├── ├── ├── components └── store ├── # Where we assemble the module and export the store ├── # and level state ├── # and level getter ├── # root level mutation name (officially recommended mutation method name is capitalized) ├── # root level mutation ├── # root level action └── modules ├── #Module 1 └── #Module 2
State Example
const state = { name: 'weish', age: 22 }; export default state;
getter example
Example (We generally use getters to get the state of state instead of using state directly)
export const name = (state) => { return ; } export const age = (state) => { return } export const other = (state) => { return `My name is ${}, I am ${}.`; }
mutation-type example
Put all the function names of mutations in this file
export const SET_NAME = 'SET_NAME'; export const SET_AGE = 'SET_AGE';
mutations example
import * as types from './'; export default { [types.SET_NAME](state, name) { = name; }, [types.SET_AGE](state, age) { = age; } };
Actions example
Asynchronous operation, multiple commits
import * as types from './'; export default { nameAsyn({commit}, {age, name}) { commit(types.SET_NAME, name); commit(types.SET_AGE, age); } }
modules – Example
If it is not a very complex application, it will generally not be divided into modules.
export default { state: {}, getters: {}, mutations: {}, actions: {} }
Example (assembly vuex)
import vue from 'vue'; import vuex from 'vuex'; import state from './'; import * as getters from './'; import mutations from './'; import actions from './'; import m1 from './modules/'; import m2 from './modules/'; import createLogger from 'vuex/dist/logger'; // Modify log (vuex); const debug = .NODE_ENV !== 'production'; // True in the development environment, otherwise it is false export default new ({ state, getters, mutations, actions, modules: { m1, m2 }, plugins: debug ? [createLogger()] : [] // Display vuex status modification in development environment});
Finally, just mount the store instance to vue inside
import store from './store/'; new Vue({ el: '#app', store, render: h => h(App) });
When using in vue components, we usually use mapGetters , mapActions , mapMutations , and then we can call these variables or functions in the way vue calls methods and computed. Examples such as
import {mapGetters, mapMutations, mapActions} from 'vuex'; /* Write only the script part in the component */ export default { computed: { ...mapGetters([ name, age ]) }, methods: { ...mapMutations({ setName: 'SET_NAME', setAge: 'SET_AGE' }), ...mapActions([ nameAsyn ]) } };
2. modules
In the src directory, create a new store folder, and then create a new one in it
import Vue from 'vue' import vuex from 'vuex' (vuex); export default new ({ state:{ show:false } })
The code in it should be changed to add a store object when instantiating a Vue object
//vuex import store from './store' new Vue({ el: '#app', router, store,//Use the store template: '<App/>', components: { App } })
This separates the store. Then there is another problem: Here, no matter which component you can use, then after there are too many components, there are also more states. So many states are piled in the store folder. What should I do if I cannot maintain it?
We can use vuex modules to change the store folder to
import Vue from 'vue' import vuex from 'vuex' (vuex); import dialog_store from '../components/dialog_store.js';//Introduce a store object export default new ({ modules: { dialog: dialog_store } })
Here we refer to a dialog_store.js , in this js file we can write the status of the dialog component separately
export default { state:{ show:false } }
After making such a modification, we can change all the $ we used before to $
If there are other components that need to use vuex, create a corresponding status file and add them to the modules in the file under the store folder
modules: { dialog: dialog_store, other: other,//Other components}
III. Mutations
The dependence on vuex is only one $ and one state, but if we want to perform an operation, we need to rely on many states, which will be troublesome to manage.
The operations in mutations must be synchronous
export default { state:{//state show:false }, mutations:{ switch_dialog(state){//The state here corresponds to the state above = ?false:true; //You can also perform other operations here to change the state } } }
After using mutations , our parent component can be changed to
<template> <div > <a href="javascript:;" rel="external nofollow" rel="external nofollow" @click="$('switch_dialog')">Click</a> <t-dialog></t-dialog> </div> </template> <script> import dialog from './components/' export default { components:{ "t-dialog":dialog } } </script>
Use $('switch_dialog') to trigger the switch_dialog method in mutations
IV. Actions
Multiple state operations, using mutations will trigger them, which will be easier to maintain. If you need to execute multiple mutations, you need to use action.
export default { state:{//state show:false }, mutations:{ switch_dialog(state){//The state here corresponds to the state above = ?false:true; //You can also perform other operations here to change the state } }, actions:{ switch_dialog(context){//The context here has the same object and method as the $store we use ('switch_dialog'); //You can also trigger other mutation methods here }, } }
So, in the previous parent component, we need to make changes to trigger the switch_dialog method in the action
<template> <div > <a href="javascript:;" rel="external nofollow" rel="external nofollow" @click="$('switch_dialog')">Click</a> <t-dialog></t-dialog> </div> </template> <script> import dialog from './components/' export default { components:{ "t-dialog":dialog } } </script>
Use $('switch_dialog') to trigger the switch_dialog method in action.
Official recommendation: Put asynchronous operations in action
5. Getters
getters is similar to computed in vue, both are used to calculate state and then generate new data (state)
If we need a state that is exactly the opposite of the state show, we can calculate it like this using computed in vue
computed(){ not_show(){ return !this.$; } }
So, if this state that is exactly the opposite of show is needed in many components, then we need to write many not_shows and use getters to solve this problem.
export default { state:{//state show:false }, getters:{ not_show(state){//The state here corresponds to the state above return !; } }, mutations:{ switch_dialog(state){//The state here corresponds to the state above = ?false:true; //You can also perform other operations here to change the state } }, actions:{ switch_dialog(context){//The context here has the same object and method as the $store we use ('switch_dialog'); //You can also trigger other mutation methods here }, } }
We use $ in the component to get the state show, similarly, we can use $.not_show to get the state not_show
Note: The value of $.not_show cannot be modified directly, and the corresponding state needs to change before it can be modified.
6. mapState, mapGetters, mapActions
Many times, the writing method of $ and $('switch_dialog') is very inconvenient
It will not be so complicated to use mapState, mapGetters, mapActions
<template> <el-dialog :="show"></el-dialog> </template> <script> import {mapState} from 'vuex'; export default { computed:{ //The three points here are called: extension operator ...mapState({ show:state=> }), } } </script>
Equivalent to
<template> <el-dialog :="show"></el-dialog> </template> <script> import {mapState} from 'vuex'; export default { computed:{ show(){ return this.$; } } } </script>
mapGetters , mapActions and mapState are similar. mapGetters are generally written in computed, and mapActions are generally written in methods
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.