vuex source code analysis (e) action Comments

mutation action similar, except that the mutation is submitted Action, rather than directly change the status, and can contain any action in the asynchronous operation, the parameters of each mutation is an object 1, may contain the following six properties:

    commit; current namespace corresponding to the commit
    dispatch; namespace corresponding to the current dispatch
    State; namespace corresponding to the current State
    getters; current namespace corresponding getters
    rootState; root module State
    getters root module; rootGetters

Similar to the mutation, created Vuex.Store () can be created through the actions of each action when instances warehouse

Neither should we call an action, but is called by store.dispatch, dispatch can take two parameters, as follows:

  type; the corresponding action name

  payload; incoming parameters

There is also a dispatch written is passed to an object, the object can take a type argument, type the name of the specified action, the entire object is passed as an argument to the action. Note: action can contain a asynchronous operation

E.g:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
</head>
<body>
    <div id="app">
        <p>{{no}}</p>
        <button @click="test">测试</button>
    </div>
    <script>
        const store = new Vuex.Store({
            state:{no:100},
            mutations:{
                increment(state,payload){state.no+=payload.no;}
            },
            actions:{
                increment({commit},info){
                    return new Promise(function(Resolve, Reject) {             // Action in the object returns a Promise 
                        the setTimeout ( function () { 
                            the commit ( ' INCREMENT ' , info) 
                            Resolve ( ' OK ' ) 
                        }, 500 ) 
                    }) 
                } 
            } 
        }) 

        var App =  new new Vue ( { 
            EL: " #app " , 
            Store, 
            computed: { 
                NO () { return this.$store.state.no}
            },
            methods:{
                test(){
                    this.$store.dispatch('increment',{no:100})
                }
            }
        })  
    </script>
</body>
</html>

We do not return a promise object action can also be held, internal vuex calls Promise.resolve automatically return value to a target Promise

 

Source code analysis


writer by: Desert QQ: 22969969

Creating Vuex.Store () performs installModule () to install root module initialization, and mutation related as follows:

  function installModule (Store, rootState, path, module, Hot) {     // install modules 
    / * slightly * / 

    module.forEachAction ( function (Action, Key) {                      // Action objects traverse module module, if found, then the implementation of this anonymous function parameter 1: each action value key: the key corresponding to the name 
      var of the type = action.root key: namespace + key;?                    // corresponding namespaces key + 
      var Handler = action.handler || action;                            // get the corresponding function 
      registerAction (Store, of the type, Handler, local);                       // call registerAction registered Action 
    }); 

    / * slightly * / 
  }

 registerAction is used to register action as follows:

  function the RegisterAction (Store, type, handler, local) {        // Register action function store: Store Example type: name action handler comprise namespace: function local: contextual objects 
    var entry = store._actions [type] || ( store._actions [type] = []);     // if _actions store object corresponding to the type is empty, the array is initialized to an empty 
    entry.push ( function wrappedActionHandler (payload, CB) {             // to store._actions push into an anonymous function 
      var RES = handler.call (Store, {                                      // this function 
        dispatch: local.dispatch, 
        the commit: local.commit, 
        getters: local.getters, 
        State: local.state, 
        rootGetters: store.getters,
        rootState: store.state 
      }, payload, CB);                                                     // execution handler function context for Store, parameters of the object is 1, 2 is parameter data payload, the return value is stored in res 
      IF ) {(isPromise (res!)                                               / / If not a res Promise 
        res = Promise.resolve (res);                                          // it is converted into an object Promise 
      }
       IF (store._devtoolHook) {
         return res. the catch ( function (ERR) { 
          store._devtoolHook.emit ( 'vuex : error ' , ERR);
           the throw ERR 
        })
      } else {
        return res
      }
    });
  }

From here we can see that each action corresponding parameter 1 is the handler function is performed here, the incoming object, the return value if not Promise object, call Promise.resolve () to convert it to an object Promise

We like to call this $ store.dispatch ( 'increment', {no: 100}). Action a trigger, the first trigger dispatch function Store redefined, it will function Store the current context object prototype continue Store the dispatch function, as follows:

  = Store.prototype.dispatch function dispatch (_type, _payload) {     // distribute an action asynchronous operation 
      var  the this $. 1 = the this ; 

    // Check-style Object dispatch 
    var REF = unifyObjectStyle (_type, _payload);                           // specification following parameters, returns an object, and the commit call is the same as here 
      var type = ref.type;
       var payload = ref.payload; 

    var Action = {type: type, payload: payload};
     var entry = the this ._actions [type];                                       / / try to obtain type type of Action 
    IF (!entry) {                                                         //如果不存在则报错并返回
      {
        console.error(("[vuex] unknown action type: " + type));
      }
      return
    }

    try {
      this._actionSubscribers
        .filter(function (sub) { return sub.before; })
        .forEach(function (sub) { return sub.before(action, this$1.state); });
    } catch (e) {
      {
        console.warn("[vuex] error in before action subscribers: ");
        console.error(e);
      }
    }

    var result = entry.length > 1
      ? Promise.all(entry.map(function (handler) { return handler(payload); }))
      : entry[0](payload);                                                //执行该action,如果大于1则用Promise.all()

    return result.then(function (res) {
      try {
        this$1._actionSubscribers
          .filter(function (sub) { return sub.after; })
          .forEach(function (sub) { return sub.after(action, this$1.state); });
      } catch (e) {
        {
          console.warn("[vuex] error in after action subscribers: ");
          console.error(e);
        }
      }
      return res
    })
  };

The last return was a res, Promise is the object, thus achieving the asynchronous operation.

 

Guess you like

Origin www.cnblogs.com/greatdesert/p/11424516.html