Summary of vuex and vuex

Source: Internet
Author: User

Summary of vuex and vuex

What is Vuex?

Vuex is a State Management Mode Designed for Vue. js applications. It uses centralized storage to manage the status of all components of an application, and uses corresponding rules to ensure that the status changes in a predictable manner. Vuex is also integrated with the official Vue debugging tool devtools extension, which provides advanced debugging functions such as time-travel debugging with zero configuration, and status snapshot import and export.

Install

Direct download of CDN reference

  <script src="/path/to/vue.js"></script>  <script src="/path/to/vuex.js"></script>

Npm 

npm install vuex --save

In a modular packaging system, you must explicitly install Vuex through Vue. use.

import Vue from 'vue'  import Vuex from 'vuex'  Vue.use(Vuex) 

Vuex is a State Management Mode Designed for Vue. js applications. It centrally stores and manages the status of all components of an application.

Status management includes the following states:

State-driven application data source;

The view maps the state to the view in the life mode.

Actions responds to state changes caused by user book input on The view.

Helps us manage the sharing status, medium and large single page applications.

State

With a single State Tree, Vuex uses a single State Tree and uses an object to contain all application-level states.

Obtain the Vuex status in the Vue component.

Because the Vuex status store is responsive, the easiest way to read the status from the store instance

Is to return a status in the calculation attribute.

Create a Counter component

 const Counter = {        template: '<div>{{ count }}</div>'        computed: {          count (){            return store.state.count          }        }      }

Every time the store. state. count changes, the calculation attribute is retrieved again and the related DOM is updated.

With the store option, Vuex provides a mechanism to "inject" the State from the root component to each sub-component (Vue. use (Vuex) needs to be called )):

Const app = new Vue ({el: '# app', // provide the store object to the "store" option, which can inject the store instance into all sub-component store, components: {Counter}, template: '<div class = "app"> <counter> </div> '})

By registering the store option in the root instance, the store instance registers all the sub-components under the and components, and the sub-components can be accessed through this. $ store. Update counter implementation:

 const Counter = {        template : '<div>{{ count }}</div>',        computed: {          count this.$store.state.count          }      }

    MapState auxiliary functions

When a component needs to obtain multiple states, declaring these States as computing properties may be redundant.

To solve this problem, we can use the mapState helper function to help us generate computing attributes.

// In a separately constructed version, the auxiliary function is Vuex. mapState import {mapState} from 'vuex' export default {computed: mapState ({// arrow function can make the code more concise count: state => state. count, // The string parameter 'Count' is equivalent to 'State => state. count 'countalias: 'Count', // to obtain the local state using 'it', you must use the regular function countPlusLocalState (state) {return state. count + this. localCount }})}

When the name of the mapped computing attribute is the same as the name of the state subnode, we can also send a string array to mapState.

Computed: mapState ([// ing this. count to store. state. count 'Count'])

The component is still in the local state.

Getters

Sometimes we need to derive some States from the state in the store, such as filtering and calculating the list.

    computed: {        doneTodosCount() {            return this.$store.state.todos.filter(todo => todo.done).length        }      }

Vuex allows us to define getters in store again (it can be considered as the computing attribute of stroe)

Getters accepts state as its first parameter.

const store = new Vuex.Store({            state: {              todos:[                {id:1, text: '...' ,done: true},                {id:2,text:'...',done: false}              ]            },          getters: {            doneTodos: state => {                return state.todos.filter(todo=> todo.done)              }            }          })

Getters will be exposed as a store. getters object:

 store.getters.doneTodos // [{id:1,text: '...',done:true}]

Getter can also accept other getters as the second parameter:

getters: {          doneTodosCount: (state,getters) => {            return getters.doneTodos.length          }      }    store.getters.doneTodosCount // -> 1

We can easily use it in any component.

 computed: {          doneTodosCount() {            return this.$store.getters.doneTodosCount        }      }

MapGetters auxiliary functions

The mapGetters helper function is only used to map getters in store to local computing attributes.

Import {mapGetter} form 'vuex' export default {computed: {// use the object expansion operator to mix getters into... mapGetters (['donetodoscount ', 'anothergetter'])}

If you want to name another getter attribute

MapGetters ({// ing this. doneCount to store. getters. doneTodosCount doneCount: 'donetodoscount '})

Mutations

The only way to change the status in the Vuex store is to submit mutation in mutation Vuex.

Similar to events, each mutation has a string of event types and callback functions. This callback function is where we actually change the status. And he will accept the state as the first parameter.

const store = new Vue.Store({        state: {            count: 1        },      mutations: {          inctement (state) {          state.count++        }      }    })

This function is called when a mutation of the increment type is triggered ." To wake up

Mutation handler, you need to call the store. commit method with the corresponding type

store.commit('increment')

Payload)

You can input an additional parameter to store. commit, that is, the mutation load:

mutations: {          increment (state, n) {          state.count += n        }      }      store.commit('increment', 10)

In most cases, the load should be an object, which can contain multiple fields and the record mutation will be easier to read.

mutations: {      increment (state,payload) {        state.count += payload.amount        }      }      store.commit('increment', {        amount:10    })

Object-style submission method

Another way to submit mutation is to directly use an object containing the type attribute:

 store.commit({        type: 'increment',        amount:10      })

When the object-style submission method is used, the entire object is transmitted as the load to the mutation function, so the handler remains unchanged:

 mutations: {        increment (state, payload) {          state.count += payload.amount        }       }

Mutations must comply with vue response rules

Since the status in the Vuex store is responsive, when we change the status, we monitor the status of vue updates, this also means that the mutation in the value Vue must follow the same precautions as using Vue.

1. It is best to initialize all required attributes in your store in advance.

2. When you need to submit new attributes on the object, you should use

Vue.set(obj, 'newProp', 123)

Use the new object to replace the old object state. obj = {... state. obj, newProp: 123}

Replace Mutation event type with Constants

Replacing mutation event types with constants is a common mode in various Flux implementations.

Export const SOME_MUTATION = 'some _ mutation'; import Vuex from 'vuex' import {SOME_MUTATION} from '. /mutation-types 'const store = new Vuex. store ({state :{...} mutations: {// we can use the ES2015 style computing attribute naming function to use a constant as the function name [SOME_MUTATION] (state) {// mutate state }}})

Mutation must be a synchronous function.

One important principle is to remember that mutation must be a synchronous function.

 mutations: {          someMutation (state) {            api.callAsyncMethod(() => {                state.count++            })          }        }

Submit Mutations in components

You can use this in components. $ store. commit ('xxx') submits mutation, or uses the mapMutations helper function to map the methods in the build to store. commit call (store injection is required on the root node)

Import {mapMutations} from 'vuxx' expor default {methods: {mapMutations ([methods: {mapMutations (['credentials' // ing this. increment () is this. $ store. commit ('credentials')]), mapMutations ({add: 'credentials' // ing this. add () is this. $ store. commit ('credentials')}]}

Actions

In mutation, mixed asynchronous calls will make debugging difficult for your program.

Actions

Action is similar to mutation.

Action submits mutation instead of directly changing the status.

Action can include any asynchronous operation.

Register a simple action

const store = new Vuex.Store({      state: {          count:0      },    mutations: {      increment (state) {        state.count++      }    },    actions: {        increment (context){          context.commit('increment')          }        }    })

The Action function accepts a context object that has the same methods and attributes as the store instance. Therefore, you can call context. commit submits a mutation, or uses context. state and context. getters to get the state and getters. When we introduce Modules later, you will know why the context object is not the store instance itself.

actions: {      increment({commit}){        commit('increment')      }    }

Distribute Action

Action is triggered using the store. dispatch method:

store.dispatch('increment')

We can perform asynchronous operations within the action.

 actions: {      incrementAsync({commit}){        setTimeout(() => {          commit('increment')        },1000)        }      }

Actions supports distribution by the same load and object Methods

// Distribute the store as a load. dispatch ('initmentasync', {amount: 10}) // distribute the store as an object. dispatch ({type: 'initmentasync', amount: 10 })

Distribute actions in components

You usethis.$store.dispatch('xxx') Distribute Actions, or use the map Actions helper function to map the component's methods to store. dispatch calls.

Import {mapActions} from 'vuex' export default {methods :( ['credentials' // ing this. increment () is this. $ store. dispatch ('credentials')]) mapActions ({add: 'inctement' // ing this. add () is this. $ store. dispatch ('credentials ')})}

Combine Actions

Action is usually asynchronous, so how do you know when the action ends.

You need to understand that store. dispatch can process the Promise returned by the callback function of the triggered action, and store. dispatch still returns Promise

actions: {        actionA({commit}){        return new Promise((resolve)=>{            setTimeout (() => {              commit('someMutation')              resolve()            },1000)          })        }      }

Now you can

store.dispatch('actionA').then(()=>{        //...      })

It can also be used in another action.

actions: {      actionB({dispath,commit}){        return dispatch('actionA').then(() => {         commit('someOtherMutation')      })    }    }

We use async/await

// Assume that getData () and getOther () return a Promis actions: {async actionA ({commit}) {commit ('gotdata', await getData ())}, async actionB ({dispatch, commit}) {await dispatch ('actiona ') // wait for actionA to complete commit ('gootherdata', await getOtherData ())}}

Modules

When a single State Tree is used, the store object will become bloated when the application becomes very large.

Vuex allows us to split the store into modules. Each module has its own state, mutation, action, getters, and even nested submodules for similar splitting from top to bottom.

Const moduleA = {state :{...}, mutations :{...} actions :{...} getters :{...}} const moduleA = {state :{...}, mutations :{...} actions :{...}} const store = new Vuex. store ({modules: {a: moduleA, B: moduleB}) store. state. a //-> Status store of moduleA. state. B //-> moduleB status

Module local status

For mutation and getter in the module, the first parameter received is the partial state of the module.

Const moduleA = {state: {count: 0}, mutations: {increment (state) {// state the local state of the module. count ++ }}, getters: {doubleCount (state) {return state. count * 2 }}}

For actions in the module, context. state is a local state, and context. rootState is the window stone of the root node:

const moduleA = {          actions: {          incrementIfOddOnRootSum ({state, commit ,rootState}) {            if((state.count + rootState.count) %2 ===1){                commit('increment')          }         }        }      }

For the getter inside the module, the node status will be used as the third parameter:

const moduleA = {          getters: {            getters: {              sumWithRootCount (state,getters,rootState) {                      return state.count + rootState.count                }              }          }        }

Namespace

The action, mutation, and getter in the module are still registered in the global namespace. This ensures that multiple modules can respond to the same mutation or action. You can also add prefix or suffix

To avoid conflicts.

// Define the names of getter, action, and mutation as constants and use the module name 'todo 'as the prefix. Export const DONE_COUNT = 'todos/DONE_COUNT 'export const FETCH_ALL = 'todos/FETCH_ALL' export const TOGGLE_DONE = 'todos/TOGGLE_DONE 'import * as types form '.. /types '// use the name definition to understand the prefix, getter, action, and mutation const todosModule = {state: {todo: []}, getters: {[type. DONE_COUNT] (state) {}} actions: {[types. FETCH_ALL] (context, payload) {}}, mutations: {[type. TOGGLE_DONE] (state, payload )}}

Dynamic module Registration

After creating a store, you can use the store. registerModule method to register a module.

store.registerModule('myModule',{})

The module status will be store. state. myModule.

The module dynamic registration function allows other Vue plug-ins to add new modules to the application store.

To separate the Vuex status management.

    Project Structure

Vuex does not limit your code structure. However, it specifies some rules to be followed:

1. application-level statuses should be concentrated in a single store object.

2. Submitting mutation is the only way to change the state, and this process is synchronized.

3. asynchronous logic should be encapsulated in action.

As long as you follow the rules above, you can organize the code as needed. If your store file is too large, you only need to split action, mutation, and getters into separate files. For large applications, we want to split Vuex-related code into modules. The following is an example of the project structure.

── Index.html ── main. js ├ ── api │ └ ──... # extract the API request ── components │ ├ ── App. vue │ ──... ── store ── index. js # We assemble the module and export the store region -- actions. js # Root-level action ── mutations. js # Root-level mutation ── modumodumodumoducart. js # shopping cart module ── products. js # product Module

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.