浏览代码

[build] 2.4.0

Evan You 7 年之前
父节点
当前提交
2aff08ec22
共有 6 个文件被更改,包括 1183 次插入120 次删除
  1. 16 0
      2.4.0.md
  2. 26 22
      dist/logger.js
  3. 883 0
      dist/vuex.common.js
  4. 129 49
      dist/vuex.esm.js
  5. 128 48
      dist/vuex.js
  6. 1 1
      dist/vuex.min.js

+ 16 - 0
2.4.0.md

@@ -0,0 +1,16 @@
+### New
+
+- New helper method `createNamesapcedHelpers`: a helper-generator that generates namespaced `mapXXX` helpers for you:
+
+  ``` js
+  const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
+  // everything generated by mapState and mapActions are bound to the module.
+  ```
+
+  See [docs](https://vuex.vuejs.org/en/modules.html#binding-helpers-with-namespace) for more info.
+
+  (@riophae via #800)
+
+### Misc
+
+- Various typing and assertion improvements.

+ 26 - 22
dist/logger.js

@@ -63,6 +63,7 @@ function deepCopy (obj, cache) {
 function createLogger (ref) {
 function createLogger (ref) {
   if ( ref === void 0 ) ref = {};
   if ( ref === void 0 ) ref = {};
   var collapsed = ref.collapsed; if ( collapsed === void 0 ) collapsed = true;
   var collapsed = ref.collapsed; if ( collapsed === void 0 ) collapsed = true;
+  var filter = ref.filter; if ( filter === void 0 ) filter = function (mutation, stateBefore, stateAfter) { return true; };
   var transformer = ref.transformer; if ( transformer === void 0 ) transformer = function (state) { return state; };
   var transformer = ref.transformer; if ( transformer === void 0 ) transformer = function (state) { return state; };
   var mutationTransformer = ref.mutationTransformer; if ( mutationTransformer === void 0 ) mutationTransformer = function (mut) { return mut; };
   var mutationTransformer = ref.mutationTransformer; if ( mutationTransformer === void 0 ) mutationTransformer = function (mut) { return mut; };
 
 
@@ -74,29 +75,32 @@ function createLogger (ref) {
         return
         return
       }
       }
       var nextState = deepCopy(state);
       var nextState = deepCopy(state);
-      var time = new Date();
-      var formattedTime = " @ " + (pad(time.getHours(), 2)) + ":" + (pad(time.getMinutes(), 2)) + ":" + (pad(time.getSeconds(), 2)) + "." + (pad(time.getMilliseconds(), 3));
-      var formattedMutation = mutationTransformer(mutation);
-      var message = "mutation " + (mutation.type) + formattedTime;
-      var startMessage = collapsed
-        ? console.groupCollapsed
-        : console.group;
-
-      // render
-      try {
-        startMessage.call(console, message);
-      } catch (e) {
-        console.log(message);
-      }
-
-      console.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState));
-      console.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation);
-      console.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState));
 
 
-      try {
-        console.groupEnd();
-      } catch (e) {
-        console.log('—— log end ——');
+      if (filter(mutation, prevState, nextState)) {
+        var time = new Date();
+        var formattedTime = " @ " + (pad(time.getHours(), 2)) + ":" + (pad(time.getMinutes(), 2)) + ":" + (pad(time.getSeconds(), 2)) + "." + (pad(time.getMilliseconds(), 3));
+        var formattedMutation = mutationTransformer(mutation);
+        var message = "mutation " + (mutation.type) + formattedTime;
+        var startMessage = collapsed
+          ? console.groupCollapsed
+          : console.group;
+
+        // render
+        try {
+          startMessage.call(console, message);
+        } catch (e) {
+          console.log(message);
+        }
+
+        console.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState));
+        console.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation);
+        console.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState));
+
+        try {
+          console.groupEnd();
+        } catch (e) {
+          console.log('—— log end ——');
+        }
       }
       }
 
 
       prevState = nextState;
       prevState = nextState;

+ 883 - 0
dist/vuex.common.js

@@ -0,0 +1,883 @@
+/**
+ * vuex v2.4.0
+ * (c) 2017 Evan You
+ * @license MIT
+ */
+'use strict';
+
+var applyMixin = function (Vue) {
+  var version = Number(Vue.version.split('.')[0]);
+
+  if (version >= 2) {
+    Vue.mixin({ beforeCreate: vuexInit });
+  } else {
+    // override init and inject vuex init procedure
+    // for 1.x backwards compatibility.
+    var _init = Vue.prototype._init;
+    Vue.prototype._init = function (options) {
+      if ( options === void 0 ) options = {};
+
+      options.init = options.init
+        ? [vuexInit].concat(options.init)
+        : vuexInit;
+      _init.call(this, options);
+    };
+  }
+
+  /**
+   * Vuex init hook, injected into each instances init hooks list.
+   */
+
+  function vuexInit () {
+    var options = this.$options;
+    // store injection
+    if (options.store) {
+      this.$store = typeof options.store === 'function'
+        ? options.store()
+        : options.store;
+    } else if (options.parent && options.parent.$store) {
+      this.$store = options.parent.$store;
+    }
+  }
+};
+
+var devtoolHook =
+  typeof window !== 'undefined' &&
+  window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
+
+function devtoolPlugin (store) {
+  if (!devtoolHook) { return }
+
+  store._devtoolHook = devtoolHook;
+
+  devtoolHook.emit('vuex:init', store);
+
+  devtoolHook.on('vuex:travel-to-state', function (targetState) {
+    store.replaceState(targetState);
+  });
+
+  store.subscribe(function (mutation, state) {
+    devtoolHook.emit('vuex:mutation', mutation, state);
+  });
+}
+
+/**
+ * Get the first item that pass the test
+ * by second argument function
+ *
+ * @param {Array} list
+ * @param {Function} f
+ * @return {*}
+ */
+/**
+ * Deep copy the given object considering circular structure.
+ * This function caches all nested objects and its copies.
+ * If it detects circular structure, use cached copy to avoid infinite loop.
+ *
+ * @param {*} obj
+ * @param {Array<Object>} cache
+ * @return {*}
+ */
+
+
+/**
+ * forEach for object
+ */
+function forEachValue (obj, fn) {
+  Object.keys(obj).forEach(function (key) { return fn(obj[key], key); });
+}
+
+function isObject (obj) {
+  return obj !== null && typeof obj === 'object'
+}
+
+function isPromise (val) {
+  return val && typeof val.then === 'function'
+}
+
+function assert (condition, msg) {
+  if (!condition) { throw new Error(("[vuex] " + msg)) }
+}
+
+var Module = function Module (rawModule, runtime) {
+  this.runtime = runtime;
+  this._children = Object.create(null);
+  this._rawModule = rawModule;
+  var rawState = rawModule.state;
+  this.state = (typeof rawState === 'function' ? rawState() : rawState) || {};
+};
+
+var prototypeAccessors$1 = { namespaced: {} };
+
+prototypeAccessors$1.namespaced.get = function () {
+  return !!this._rawModule.namespaced
+};
+
+Module.prototype.addChild = function addChild (key, module) {
+  this._children[key] = module;
+};
+
+Module.prototype.removeChild = function removeChild (key) {
+  delete this._children[key];
+};
+
+Module.prototype.getChild = function getChild (key) {
+  return this._children[key]
+};
+
+Module.prototype.update = function update (rawModule) {
+  this._rawModule.namespaced = rawModule.namespaced;
+  if (rawModule.actions) {
+    this._rawModule.actions = rawModule.actions;
+  }
+  if (rawModule.mutations) {
+    this._rawModule.mutations = rawModule.mutations;
+  }
+  if (rawModule.getters) {
+    this._rawModule.getters = rawModule.getters;
+  }
+};
+
+Module.prototype.forEachChild = function forEachChild (fn) {
+  forEachValue(this._children, fn);
+};
+
+Module.prototype.forEachGetter = function forEachGetter (fn) {
+  if (this._rawModule.getters) {
+    forEachValue(this._rawModule.getters, fn);
+  }
+};
+
+Module.prototype.forEachAction = function forEachAction (fn) {
+  if (this._rawModule.actions) {
+    forEachValue(this._rawModule.actions, fn);
+  }
+};
+
+Module.prototype.forEachMutation = function forEachMutation (fn) {
+  if (this._rawModule.mutations) {
+    forEachValue(this._rawModule.mutations, fn);
+  }
+};
+
+Object.defineProperties( Module.prototype, prototypeAccessors$1 );
+
+var ModuleCollection = function ModuleCollection (rawRootModule) {
+  // register root module (Vuex.Store options)
+  this.register([], rawRootModule, false);
+};
+
+ModuleCollection.prototype.get = function get (path) {
+  return path.reduce(function (module, key) {
+    return module.getChild(key)
+  }, this.root)
+};
+
+ModuleCollection.prototype.getNamespace = function getNamespace (path) {
+  var module = this.root;
+  return path.reduce(function (namespace, key) {
+    module = module.getChild(key);
+    return namespace + (module.namespaced ? key + '/' : '')
+  }, '')
+};
+
+ModuleCollection.prototype.update = function update$1 (rawRootModule) {
+  update([], this.root, rawRootModule);
+};
+
+ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
+    var this$1 = this;
+    if ( runtime === void 0 ) runtime = true;
+
+  if (process.env.NODE_ENV !== 'production') {
+    assertRawModule(path, rawModule);
+  }
+
+  var newModule = new Module(rawModule, runtime);
+  if (path.length === 0) {
+    this.root = newModule;
+  } else {
+    var parent = this.get(path.slice(0, -1));
+    parent.addChild(path[path.length - 1], newModule);
+  }
+
+  // register nested modules
+  if (rawModule.modules) {
+    forEachValue(rawModule.modules, function (rawChildModule, key) {
+      this$1.register(path.concat(key), rawChildModule, runtime);
+    });
+  }
+};
+
+ModuleCollection.prototype.unregister = function unregister (path) {
+  var parent = this.get(path.slice(0, -1));
+  var key = path[path.length - 1];
+  if (!parent.getChild(key).runtime) { return }
+
+  parent.removeChild(key);
+};
+
+function update (path, targetModule, newModule) {
+  if (process.env.NODE_ENV !== 'production') {
+    assertRawModule(path, newModule);
+  }
+
+  // update target module
+  targetModule.update(newModule);
+
+  // update nested modules
+  if (newModule.modules) {
+    for (var key in newModule.modules) {
+      if (!targetModule.getChild(key)) {
+        if (process.env.NODE_ENV !== 'production') {
+          console.warn(
+            "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
+            'manual reload is needed'
+          );
+        }
+        return
+      }
+      update(
+        path.concat(key),
+        targetModule.getChild(key),
+        newModule.modules[key]
+      );
+    }
+  }
+}
+
+function assertRawModule (path, rawModule) {
+  ['getters', 'actions', 'mutations'].forEach(function (key) {
+    if (!rawModule[key]) { return }
+
+    forEachValue(rawModule[key], function (value, type) {
+      assert(
+        typeof value === 'function',
+        makeAssertionMessage(path, key, type, value)
+      );
+    });
+  });
+}
+
+function makeAssertionMessage (path, key, type, value) {
+  var buf = key + " should be function but \"" + key + "." + type + "\"";
+  if (path.length > 0) {
+    buf += " in module \"" + (path.join('.')) + "\"";
+  }
+  buf += " is " + (JSON.stringify(value)) + ".";
+
+  return buf
+}
+
+var Vue; // bind on install
+
+var Store = function Store (options) {
+  var this$1 = this;
+  if ( options === void 0 ) options = {};
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
+    assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
+    assert(this instanceof Store, "Store must be called with the new operator.");
+  }
+
+  var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
+  var strict = options.strict; if ( strict === void 0 ) strict = false;
+
+  var state = options.state; if ( state === void 0 ) state = {};
+  if (typeof state === 'function') {
+    state = state();
+  }
+
+  // store internal state
+  this._committing = false;
+  this._actions = Object.create(null);
+  this._mutations = Object.create(null);
+  this._wrappedGetters = Object.create(null);
+  this._modules = new ModuleCollection(options);
+  this._modulesNamespaceMap = Object.create(null);
+  this._subscribers = [];
+  this._watcherVM = new Vue();
+
+  // bind commit and dispatch to self
+  var store = this;
+  var ref = this;
+  var dispatch = ref.dispatch;
+  var commit = ref.commit;
+  this.dispatch = function boundDispatch (type, payload) {
+    return dispatch.call(store, type, payload)
+  };
+  this.commit = function boundCommit (type, payload, options) {
+    return commit.call(store, type, payload, options)
+  };
+
+  // strict mode
+  this.strict = strict;
+
+  // init root module.
+  // this also recursively registers all sub-modules
+  // and collects all module getters inside this._wrappedGetters
+  installModule(this, state, [], this._modules.root);
+
+  // initialize the store vm, which is responsible for the reactivity
+  // (also registers _wrappedGetters as computed properties)
+  resetStoreVM(this, state);
+
+  // apply plugins
+  plugins.forEach(function (plugin) { return plugin(this$1); });
+
+  if (Vue.config.devtools) {
+    devtoolPlugin(this);
+  }
+};
+
+var prototypeAccessors = { state: {} };
+
+prototypeAccessors.state.get = function () {
+  return this._vm._data.$$state
+};
+
+prototypeAccessors.state.set = function (v) {
+  if (process.env.NODE_ENV !== 'production') {
+    assert(false, "Use store.replaceState() to explicit replace store state.");
+  }
+};
+
+Store.prototype.commit = function commit (_type, _payload, _options) {
+    var this$1 = this;
+
+  // check object-style commit
+  var ref = unifyObjectStyle(_type, _payload, _options);
+    var type = ref.type;
+    var payload = ref.payload;
+    var options = ref.options;
+
+  var mutation = { type: type, payload: payload };
+  var entry = this._mutations[type];
+  if (!entry) {
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(("[vuex] unknown mutation type: " + type));
+    }
+    return
+  }
+  this._withCommit(function () {
+    entry.forEach(function commitIterator (handler) {
+      handler(payload);
+    });
+  });
+  this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
+
+  if (
+    process.env.NODE_ENV !== 'production' &&
+    options && options.silent
+  ) {
+    console.warn(
+      "[vuex] mutation type: " + type + ". Silent option has been removed. " +
+      'Use the filter functionality in the vue-devtools'
+    );
+  }
+};
+
+Store.prototype.dispatch = function dispatch (_type, _payload) {
+  // check object-style dispatch
+  var ref = unifyObjectStyle(_type, _payload);
+    var type = ref.type;
+    var payload = ref.payload;
+
+  var entry = this._actions[type];
+  if (!entry) {
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(("[vuex] unknown action type: " + type));
+    }
+    return
+  }
+  return entry.length > 1
+    ? Promise.all(entry.map(function (handler) { return handler(payload); }))
+    : entry[0](payload)
+};
+
+Store.prototype.subscribe = function subscribe (fn) {
+  var subs = this._subscribers;
+  if (subs.indexOf(fn) < 0) {
+    subs.push(fn);
+  }
+  return function () {
+    var i = subs.indexOf(fn);
+    if (i > -1) {
+      subs.splice(i, 1);
+    }
+  }
+};
+
+Store.prototype.watch = function watch (getter, cb, options) {
+    var this$1 = this;
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(typeof getter === 'function', "store.watch only accepts a function.");
+  }
+  return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
+};
+
+Store.prototype.replaceState = function replaceState (state) {
+    var this$1 = this;
+
+  this._withCommit(function () {
+    this$1._vm._data.$$state = state;
+  });
+};
+
+Store.prototype.registerModule = function registerModule (path, rawModule) {
+  if (typeof path === 'string') { path = [path]; }
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(Array.isArray(path), "module path must be a string or an Array.");
+    assert(path.length > 0, 'cannot register the root module by using registerModule.');
+  }
+
+  this._modules.register(path, rawModule);
+  installModule(this, this.state, path, this._modules.get(path));
+  // reset store to update getters...
+  resetStoreVM(this, this.state);
+};
+
+Store.prototype.unregisterModule = function unregisterModule (path) {
+    var this$1 = this;
+
+  if (typeof path === 'string') { path = [path]; }
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(Array.isArray(path), "module path must be a string or an Array.");
+  }
+
+  this._modules.unregister(path);
+  this._withCommit(function () {
+    var parentState = getNestedState(this$1.state, path.slice(0, -1));
+    Vue.delete(parentState, path[path.length - 1]);
+  });
+  resetStore(this);
+};
+
+Store.prototype.hotUpdate = function hotUpdate (newOptions) {
+  this._modules.update(newOptions);
+  resetStore(this, true);
+};
+
+Store.prototype._withCommit = function _withCommit (fn) {
+  var committing = this._committing;
+  this._committing = true;
+  fn();
+  this._committing = committing;
+};
+
+Object.defineProperties( Store.prototype, prototypeAccessors );
+
+function resetStore (store, hot) {
+  store._actions = Object.create(null);
+  store._mutations = Object.create(null);
+  store._wrappedGetters = Object.create(null);
+  store._modulesNamespaceMap = Object.create(null);
+  var state = store.state;
+  // init all modules
+  installModule(store, state, [], store._modules.root, true);
+  // reset vm
+  resetStoreVM(store, state, hot);
+}
+
+function resetStoreVM (store, state, hot) {
+  var oldVm = store._vm;
+
+  // bind store public getters
+  store.getters = {};
+  var wrappedGetters = store._wrappedGetters;
+  var computed = {};
+  forEachValue(wrappedGetters, function (fn, key) {
+    // use computed to leverage its lazy-caching mechanism
+    computed[key] = function () { return fn(store); };
+    Object.defineProperty(store.getters, key, {
+      get: function () { return store._vm[key]; },
+      enumerable: true // for local getters
+    });
+  });
+
+  // use a Vue instance to store the state tree
+  // suppress warnings just in case the user has added
+  // some funky global mixins
+  var silent = Vue.config.silent;
+  Vue.config.silent = true;
+  store._vm = new Vue({
+    data: {
+      $$state: state
+    },
+    computed: computed
+  });
+  Vue.config.silent = silent;
+
+  // enable strict mode for new vm
+  if (store.strict) {
+    enableStrictMode(store);
+  }
+
+  if (oldVm) {
+    if (hot) {
+      // dispatch changes in all subscribed watchers
+      // to force getter re-evaluation for hot reloading.
+      store._withCommit(function () {
+        oldVm._data.$$state = null;
+      });
+    }
+    Vue.nextTick(function () { return oldVm.$destroy(); });
+  }
+}
+
+function installModule (store, rootState, path, module, hot) {
+  var isRoot = !path.length;
+  var namespace = store._modules.getNamespace(path);
+
+  // register in namespace map
+  if (module.namespaced) {
+    store._modulesNamespaceMap[namespace] = module;
+  }
+
+  // set state
+  if (!isRoot && !hot) {
+    var parentState = getNestedState(rootState, path.slice(0, -1));
+    var moduleName = path[path.length - 1];
+    store._withCommit(function () {
+      Vue.set(parentState, moduleName, module.state);
+    });
+  }
+
+  var local = module.context = makeLocalContext(store, namespace, path);
+
+  module.forEachMutation(function (mutation, key) {
+    var namespacedType = namespace + key;
+    registerMutation(store, namespacedType, mutation, local);
+  });
+
+  module.forEachAction(function (action, key) {
+    var namespacedType = namespace + key;
+    registerAction(store, namespacedType, action, local);
+  });
+
+  module.forEachGetter(function (getter, key) {
+    var namespacedType = namespace + key;
+    registerGetter(store, namespacedType, getter, local);
+  });
+
+  module.forEachChild(function (child, key) {
+    installModule(store, rootState, path.concat(key), child, hot);
+  });
+}
+
+/**
+ * make localized dispatch, commit, getters and state
+ * if there is no namespace, just use root ones
+ */
+function makeLocalContext (store, namespace, path) {
+  var noNamespace = namespace === '';
+
+  var local = {
+    dispatch: noNamespace ? store.dispatch : function (_type, _payload, _options) {
+      var args = unifyObjectStyle(_type, _payload, _options);
+      var payload = args.payload;
+      var options = args.options;
+      var type = args.type;
+
+      if (!options || !options.root) {
+        type = namespace + type;
+        if (process.env.NODE_ENV !== 'production' && !store._actions[type]) {
+          console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
+          return
+        }
+      }
+
+      return store.dispatch(type, payload)
+    },
+
+    commit: noNamespace ? store.commit : function (_type, _payload, _options) {
+      var args = unifyObjectStyle(_type, _payload, _options);
+      var payload = args.payload;
+      var options = args.options;
+      var type = args.type;
+
+      if (!options || !options.root) {
+        type = namespace + type;
+        if (process.env.NODE_ENV !== 'production' && !store._mutations[type]) {
+          console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
+          return
+        }
+      }
+
+      store.commit(type, payload, options);
+    }
+  };
+
+  // getters and state object must be gotten lazily
+  // because they will be changed by vm update
+  Object.defineProperties(local, {
+    getters: {
+      get: noNamespace
+        ? function () { return store.getters; }
+        : function () { return makeLocalGetters(store, namespace); }
+    },
+    state: {
+      get: function () { return getNestedState(store.state, path); }
+    }
+  });
+
+  return local
+}
+
+function makeLocalGetters (store, namespace) {
+  var gettersProxy = {};
+
+  var splitPos = namespace.length;
+  Object.keys(store.getters).forEach(function (type) {
+    // skip if the target getter is not match this namespace
+    if (type.slice(0, splitPos) !== namespace) { return }
+
+    // extract local getter type
+    var localType = type.slice(splitPos);
+
+    // Add a port to the getters proxy.
+    // Define as getter property because
+    // we do not want to evaluate the getters in this time.
+    Object.defineProperty(gettersProxy, localType, {
+      get: function () { return store.getters[type]; },
+      enumerable: true
+    });
+  });
+
+  return gettersProxy
+}
+
+function registerMutation (store, type, handler, local) {
+  var entry = store._mutations[type] || (store._mutations[type] = []);
+  entry.push(function wrappedMutationHandler (payload) {
+    handler.call(store, local.state, payload);
+  });
+}
+
+function registerAction (store, type, handler, local) {
+  var entry = store._actions[type] || (store._actions[type] = []);
+  entry.push(function wrappedActionHandler (payload, cb) {
+    var res = handler.call(store, {
+      dispatch: local.dispatch,
+      commit: local.commit,
+      getters: local.getters,
+      state: local.state,
+      rootGetters: store.getters,
+      rootState: store.state
+    }, payload, cb);
+    if (!isPromise(res)) {
+      res = Promise.resolve(res);
+    }
+    if (store._devtoolHook) {
+      return res.catch(function (err) {
+        store._devtoolHook.emit('vuex:error', err);
+        throw err
+      })
+    } else {
+      return res
+    }
+  });
+}
+
+function registerGetter (store, type, rawGetter, local) {
+  if (store._wrappedGetters[type]) {
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(("[vuex] duplicate getter key: " + type));
+    }
+    return
+  }
+  store._wrappedGetters[type] = function wrappedGetter (store) {
+    return rawGetter(
+      local.state, // local state
+      local.getters, // local getters
+      store.state, // root state
+      store.getters // root getters
+    )
+  };
+}
+
+function enableStrictMode (store) {
+  store._vm.$watch(function () { return this._data.$$state }, function () {
+    if (process.env.NODE_ENV !== 'production') {
+      assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
+    }
+  }, { deep: true, sync: true });
+}
+
+function getNestedState (state, path) {
+  return path.length
+    ? path.reduce(function (state, key) { return state[key]; }, state)
+    : state
+}
+
+function unifyObjectStyle (type, payload, options) {
+  if (isObject(type) && type.type) {
+    options = payload;
+    payload = type;
+    type = type.type;
+  }
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
+  }
+
+  return { type: type, payload: payload, options: options }
+}
+
+function install (_Vue) {
+  if (Vue) {
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(
+        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
+      );
+    }
+    return
+  }
+  Vue = _Vue;
+  applyMixin(Vue);
+}
+
+// auto install in dist mode
+if (typeof window !== 'undefined' && window.Vue) {
+  install(window.Vue);
+}
+
+var mapState = normalizeNamespace(function (namespace, states) {
+  var res = {};
+  normalizeMap(states).forEach(function (ref) {
+    var key = ref.key;
+    var val = ref.val;
+
+    res[key] = function mappedState () {
+      var state = this.$store.state;
+      var getters = this.$store.getters;
+      if (namespace) {
+        var module = getModuleByNamespace(this.$store, 'mapState', namespace);
+        if (!module) {
+          return
+        }
+        state = module.context.state;
+        getters = module.context.getters;
+      }
+      return typeof val === 'function'
+        ? val.call(this, state, getters)
+        : state[val]
+    };
+    // mark vuex getter for devtools
+    res[key].vuex = true;
+  });
+  return res
+});
+
+var mapMutations = normalizeNamespace(function (namespace, mutations) {
+  var res = {};
+  normalizeMap(mutations).forEach(function (ref) {
+    var key = ref.key;
+    var val = ref.val;
+
+    val = namespace + val;
+    res[key] = function mappedMutation () {
+      var args = [], len = arguments.length;
+      while ( len-- ) args[ len ] = arguments[ len ];
+
+      if (namespace && !getModuleByNamespace(this.$store, 'mapMutations', namespace)) {
+        return
+      }
+      return this.$store.commit.apply(this.$store, [val].concat(args))
+    };
+  });
+  return res
+});
+
+var mapGetters = normalizeNamespace(function (namespace, getters) {
+  var res = {};
+  normalizeMap(getters).forEach(function (ref) {
+    var key = ref.key;
+    var val = ref.val;
+
+    val = namespace + val;
+    res[key] = function mappedGetter () {
+      if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
+        return
+      }
+      if (process.env.NODE_ENV !== 'production' && !(val in this.$store.getters)) {
+        console.error(("[vuex] unknown getter: " + val));
+        return
+      }
+      return this.$store.getters[val]
+    };
+    // mark vuex getter for devtools
+    res[key].vuex = true;
+  });
+  return res
+});
+
+var mapActions = normalizeNamespace(function (namespace, actions) {
+  var res = {};
+  normalizeMap(actions).forEach(function (ref) {
+    var key = ref.key;
+    var val = ref.val;
+
+    val = namespace + val;
+    res[key] = function mappedAction () {
+      var args = [], len = arguments.length;
+      while ( len-- ) args[ len ] = arguments[ len ];
+
+      if (namespace && !getModuleByNamespace(this.$store, 'mapActions', namespace)) {
+        return
+      }
+      return this.$store.dispatch.apply(this.$store, [val].concat(args))
+    };
+  });
+  return res
+});
+
+var createNamespacedHelpers = function (namespace) { return ({
+  mapState: mapState.bind(null, namespace),
+  mapGetters: mapGetters.bind(null, namespace),
+  mapMutations: mapMutations.bind(null, namespace),
+  mapActions: mapActions.bind(null, namespace)
+}); };
+
+function normalizeMap (map) {
+  return Array.isArray(map)
+    ? map.map(function (key) { return ({ key: key, val: key }); })
+    : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
+}
+
+function normalizeNamespace (fn) {
+  return function (namespace, map) {
+    if (typeof namespace !== 'string') {
+      map = namespace;
+      namespace = '';
+    } else if (namespace.charAt(namespace.length - 1) !== '/') {
+      namespace += '/';
+    }
+    return fn(namespace, map)
+  }
+}
+
+function getModuleByNamespace (store, helper, namespace) {
+  var module = store._modulesNamespaceMap[namespace];
+  if (process.env.NODE_ENV !== 'production' && !module) {
+    console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
+  }
+  return module
+}
+
+var index = {
+  Store: Store,
+  install: install,
+  version: '2.4.0',
+  mapState: mapState,
+  mapMutations: mapMutations,
+  mapGetters: mapGetters,
+  mapActions: mapActions,
+  createNamespacedHelpers: createNamespacedHelpers
+};
+
+module.exports = index;

+ 129 - 49
dist/vuex.esm.js

@@ -1,5 +1,5 @@
 /**
 /**
- * vuex v2.3.0
+ * vuex v2.4.0
  * (c) 2017 Evan You
  * (c) 2017 Evan You
  * @license MIT
  * @license MIT
  */
  */
@@ -7,8 +7,7 @@ var applyMixin = function (Vue) {
   var version = Number(Vue.version.split('.')[0]);
   var version = Number(Vue.version.split('.')[0]);
 
 
   if (version >= 2) {
   if (version >= 2) {
-    var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1;
-    Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit });
+    Vue.mixin({ beforeCreate: vuexInit });
   } else {
   } else {
     // override init and inject vuex init procedure
     // override init and inject vuex init procedure
     // for 1.x backwards compatibility.
     // for 1.x backwards compatibility.
@@ -31,7 +30,9 @@ var applyMixin = function (Vue) {
     var options = this.$options;
     var options = this.$options;
     // store injection
     // store injection
     if (options.store) {
     if (options.store) {
-      this.$store = options.store;
+      this.$store = typeof options.store === 'function'
+        ? options.store()
+        : options.store;
     } else if (options.parent && options.parent.$store) {
     } else if (options.parent && options.parent.$store) {
       this.$store = options.parent.$store;
       this.$store = options.parent.$store;
     }
     }
@@ -160,17 +161,8 @@ Module.prototype.forEachMutation = function forEachMutation (fn) {
 Object.defineProperties( Module.prototype, prototypeAccessors$1 );
 Object.defineProperties( Module.prototype, prototypeAccessors$1 );
 
 
 var ModuleCollection = function ModuleCollection (rawRootModule) {
 var ModuleCollection = function ModuleCollection (rawRootModule) {
-  var this$1 = this;
-
   // register root module (Vuex.Store options)
   // register root module (Vuex.Store options)
-  this.root = new Module(rawRootModule, false);
-
-  // register all nested modules
-  if (rawRootModule.modules) {
-    forEachValue(rawRootModule.modules, function (rawModule, key) {
-      this$1.register([key], rawModule, false);
-    });
-  }
+  this.register([], rawRootModule, false);
 };
 };
 
 
 ModuleCollection.prototype.get = function get (path) {
 ModuleCollection.prototype.get = function get (path) {
@@ -188,16 +180,24 @@ ModuleCollection.prototype.getNamespace = function getNamespace (path) {
 };
 };
 
 
 ModuleCollection.prototype.update = function update$1 (rawRootModule) {
 ModuleCollection.prototype.update = function update$1 (rawRootModule) {
-  update(this.root, rawRootModule);
+  update([], this.root, rawRootModule);
 };
 };
 
 
 ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
 ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
     var this$1 = this;
     var this$1 = this;
     if ( runtime === void 0 ) runtime = true;
     if ( runtime === void 0 ) runtime = true;
 
 
-  var parent = this.get(path.slice(0, -1));
+  if (process.env.NODE_ENV !== 'production') {
+    assertRawModule(path, rawModule);
+  }
+
   var newModule = new Module(rawModule, runtime);
   var newModule = new Module(rawModule, runtime);
-  parent.addChild(path[path.length - 1], newModule);
+  if (path.length === 0) {
+    this.root = newModule;
+  } else {
+    var parent = this.get(path.slice(0, -1));
+    parent.addChild(path[path.length - 1], newModule);
+  }
 
 
   // register nested modules
   // register nested modules
   if (rawModule.modules) {
   if (rawModule.modules) {
@@ -215,7 +215,11 @@ ModuleCollection.prototype.unregister = function unregister (path) {
   parent.removeChild(key);
   parent.removeChild(key);
 };
 };
 
 
-function update (targetModule, newModule) {
+function update (path, targetModule, newModule) {
+  if (process.env.NODE_ENV !== 'production') {
+    assertRawModule(path, newModule);
+  }
+
   // update target module
   // update target module
   targetModule.update(newModule);
   targetModule.update(newModule);
 
 
@@ -223,30 +227,66 @@ function update (targetModule, newModule) {
   if (newModule.modules) {
   if (newModule.modules) {
     for (var key in newModule.modules) {
     for (var key in newModule.modules) {
       if (!targetModule.getChild(key)) {
       if (!targetModule.getChild(key)) {
-        console.warn(
-          "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
-          'manual reload is needed'
-        );
+        if (process.env.NODE_ENV !== 'production') {
+          console.warn(
+            "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
+            'manual reload is needed'
+          );
+        }
         return
         return
       }
       }
-      update(targetModule.getChild(key), newModule.modules[key]);
+      update(
+        path.concat(key),
+        targetModule.getChild(key),
+        newModule.modules[key]
+      );
     }
     }
   }
   }
 }
 }
 
 
+function assertRawModule (path, rawModule) {
+  ['getters', 'actions', 'mutations'].forEach(function (key) {
+    if (!rawModule[key]) { return }
+
+    forEachValue(rawModule[key], function (value, type) {
+      assert(
+        typeof value === 'function',
+        makeAssertionMessage(path, key, type, value)
+      );
+    });
+  });
+}
+
+function makeAssertionMessage (path, key, type, value) {
+  var buf = key + " should be function but \"" + key + "." + type + "\"";
+  if (path.length > 0) {
+    buf += " in module \"" + (path.join('.')) + "\"";
+  }
+  buf += " is " + (JSON.stringify(value)) + ".";
+
+  return buf
+}
+
 var Vue; // bind on install
 var Vue; // bind on install
 
 
 var Store = function Store (options) {
 var Store = function Store (options) {
   var this$1 = this;
   var this$1 = this;
   if ( options === void 0 ) options = {};
   if ( options === void 0 ) options = {};
 
 
-  assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
-  assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
+  if (process.env.NODE_ENV !== 'production') {
+    assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
+    assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
+    assert(this instanceof Store, "Store must be called with the new operator.");
+  }
 
 
-  var state = options.state; if ( state === void 0 ) state = {};
   var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
   var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
   var strict = options.strict; if ( strict === void 0 ) strict = false;
   var strict = options.strict; if ( strict === void 0 ) strict = false;
 
 
+  var state = options.state; if ( state === void 0 ) state = {};
+  if (typeof state === 'function') {
+    state = state();
+  }
+
   // store internal state
   // store internal state
   this._committing = false;
   this._committing = false;
   this._actions = Object.create(null);
   this._actions = Object.create(null);
@@ -282,7 +322,11 @@ var Store = function Store (options) {
   resetStoreVM(this, state);
   resetStoreVM(this, state);
 
 
   // apply plugins
   // apply plugins
-  plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); });
+  plugins.forEach(function (plugin) { return plugin(this$1); });
+
+  if (Vue.config.devtools) {
+    devtoolPlugin(this);
+  }
 };
 };
 
 
 var prototypeAccessors = { state: {} };
 var prototypeAccessors = { state: {} };
@@ -292,7 +336,9 @@ prototypeAccessors.state.get = function () {
 };
 };
 
 
 prototypeAccessors.state.set = function (v) {
 prototypeAccessors.state.set = function (v) {
-  assert(false, "Use store.replaceState() to explicit replace store state.");
+  if (process.env.NODE_ENV !== 'production') {
+    assert(false, "Use store.replaceState() to explicit replace store state.");
+  }
 };
 };
 
 
 Store.prototype.commit = function commit (_type, _payload, _options) {
 Store.prototype.commit = function commit (_type, _payload, _options) {
@@ -307,7 +353,9 @@ Store.prototype.commit = function commit (_type, _payload, _options) {
   var mutation = { type: type, payload: payload };
   var mutation = { type: type, payload: payload };
   var entry = this._mutations[type];
   var entry = this._mutations[type];
   if (!entry) {
   if (!entry) {
-    console.error(("[vuex] unknown mutation type: " + type));
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(("[vuex] unknown mutation type: " + type));
+    }
     return
     return
   }
   }
   this._withCommit(function () {
   this._withCommit(function () {
@@ -317,7 +365,10 @@ Store.prototype.commit = function commit (_type, _payload, _options) {
   });
   });
   this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
   this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
 
 
-  if (options && options.silent) {
+  if (
+    process.env.NODE_ENV !== 'production' &&
+    options && options.silent
+  ) {
     console.warn(
     console.warn(
       "[vuex] mutation type: " + type + ". Silent option has been removed. " +
       "[vuex] mutation type: " + type + ". Silent option has been removed. " +
       'Use the filter functionality in the vue-devtools'
       'Use the filter functionality in the vue-devtools'
@@ -333,7 +384,9 @@ Store.prototype.dispatch = function dispatch (_type, _payload) {
 
 
   var entry = this._actions[type];
   var entry = this._actions[type];
   if (!entry) {
   if (!entry) {
-    console.error(("[vuex] unknown action type: " + type));
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(("[vuex] unknown action type: " + type));
+    }
     return
     return
   }
   }
   return entry.length > 1
   return entry.length > 1
@@ -357,7 +410,9 @@ Store.prototype.subscribe = function subscribe (fn) {
 Store.prototype.watch = function watch (getter, cb, options) {
 Store.prototype.watch = function watch (getter, cb, options) {
     var this$1 = this;
     var this$1 = this;
 
 
-  assert(typeof getter === 'function', "store.watch only accepts a function.");
+  if (process.env.NODE_ENV !== 'production') {
+    assert(typeof getter === 'function', "store.watch only accepts a function.");
+  }
   return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
   return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
 };
 };
 
 
@@ -371,7 +426,12 @@ Store.prototype.replaceState = function replaceState (state) {
 
 
 Store.prototype.registerModule = function registerModule (path, rawModule) {
 Store.prototype.registerModule = function registerModule (path, rawModule) {
   if (typeof path === 'string') { path = [path]; }
   if (typeof path === 'string') { path = [path]; }
-  assert(Array.isArray(path), "module path must be a string or an Array.");
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(Array.isArray(path), "module path must be a string or an Array.");
+    assert(path.length > 0, 'cannot register the root module by using registerModule.');
+  }
+
   this._modules.register(path, rawModule);
   this._modules.register(path, rawModule);
   installModule(this, this.state, path, this._modules.get(path));
   installModule(this, this.state, path, this._modules.get(path));
   // reset store to update getters...
   // reset store to update getters...
@@ -382,7 +442,11 @@ Store.prototype.unregisterModule = function unregisterModule (path) {
     var this$1 = this;
     var this$1 = this;
 
 
   if (typeof path === 'string') { path = [path]; }
   if (typeof path === 'string') { path = [path]; }
-  assert(Array.isArray(path), "module path must be a string or an Array.");
+
+  if (process.env.NODE_ENV !== 'production') {
+    assert(Array.isArray(path), "module path must be a string or an Array.");
+  }
+
   this._modules.unregister(path);
   this._modules.unregister(path);
   this._withCommit(function () {
   this._withCommit(function () {
     var parentState = getNestedState(this$1.state, path.slice(0, -1));
     var parentState = getNestedState(this$1.state, path.slice(0, -1));
@@ -519,7 +583,7 @@ function makeLocalContext (store, namespace, path) {
 
 
       if (!options || !options.root) {
       if (!options || !options.root) {
         type = namespace + type;
         type = namespace + type;
-        if (!store._actions[type]) {
+        if (process.env.NODE_ENV !== 'production' && !store._actions[type]) {
           console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
           console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
           return
           return
         }
         }
@@ -536,7 +600,7 @@ function makeLocalContext (store, namespace, path) {
 
 
       if (!options || !options.root) {
       if (!options || !options.root) {
         type = namespace + type;
         type = namespace + type;
-        if (!store._mutations[type]) {
+        if (process.env.NODE_ENV !== 'production' && !store._mutations[type]) {
           console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
           console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
           return
           return
         }
         }
@@ -588,14 +652,14 @@ function makeLocalGetters (store, namespace) {
 function registerMutation (store, type, handler, local) {
 function registerMutation (store, type, handler, local) {
   var entry = store._mutations[type] || (store._mutations[type] = []);
   var entry = store._mutations[type] || (store._mutations[type] = []);
   entry.push(function wrappedMutationHandler (payload) {
   entry.push(function wrappedMutationHandler (payload) {
-    handler(local.state, payload);
+    handler.call(store, local.state, payload);
   });
   });
 }
 }
 
 
 function registerAction (store, type, handler, local) {
 function registerAction (store, type, handler, local) {
   var entry = store._actions[type] || (store._actions[type] = []);
   var entry = store._actions[type] || (store._actions[type] = []);
   entry.push(function wrappedActionHandler (payload, cb) {
   entry.push(function wrappedActionHandler (payload, cb) {
-    var res = handler({
+    var res = handler.call(store, {
       dispatch: local.dispatch,
       dispatch: local.dispatch,
       commit: local.commit,
       commit: local.commit,
       getters: local.getters,
       getters: local.getters,
@@ -619,7 +683,9 @@ function registerAction (store, type, handler, local) {
 
 
 function registerGetter (store, type, rawGetter, local) {
 function registerGetter (store, type, rawGetter, local) {
   if (store._wrappedGetters[type]) {
   if (store._wrappedGetters[type]) {
-    console.error(("[vuex] duplicate getter key: " + type));
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(("[vuex] duplicate getter key: " + type));
+    }
     return
     return
   }
   }
   store._wrappedGetters[type] = function wrappedGetter (store) {
   store._wrappedGetters[type] = function wrappedGetter (store) {
@@ -634,7 +700,9 @@ function registerGetter (store, type, rawGetter, local) {
 
 
 function enableStrictMode (store) {
 function enableStrictMode (store) {
   store._vm.$watch(function () { return this._data.$$state }, function () {
   store._vm.$watch(function () { return this._data.$$state }, function () {
-    assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
+    if (process.env.NODE_ENV !== 'production') {
+      assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
+    }
   }, { deep: true, sync: true });
   }, { deep: true, sync: true });
 }
 }
 
 
@@ -651,16 +719,20 @@ function unifyObjectStyle (type, payload, options) {
     type = type.type;
     type = type.type;
   }
   }
 
 
-  assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
+  if (process.env.NODE_ENV !== 'production') {
+    assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
+  }
 
 
   return { type: type, payload: payload, options: options }
   return { type: type, payload: payload, options: options }
 }
 }
 
 
 function install (_Vue) {
 function install (_Vue) {
   if (Vue) {
   if (Vue) {
-    console.error(
-      '[vuex] already installed. Vue.use(Vuex) should be called only once.'
-    );
+    if (process.env.NODE_ENV !== 'production') {
+      console.error(
+        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
+      );
+    }
     return
     return
   }
   }
   Vue = _Vue;
   Vue = _Vue;
@@ -730,7 +802,7 @@ var mapGetters = normalizeNamespace(function (namespace, getters) {
       if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
       if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
         return
         return
       }
       }
-      if (!(val in this.$store.getters)) {
+      if (process.env.NODE_ENV !== 'production' && !(val in this.$store.getters)) {
         console.error(("[vuex] unknown getter: " + val));
         console.error(("[vuex] unknown getter: " + val));
         return
         return
       }
       }
@@ -762,6 +834,13 @@ var mapActions = normalizeNamespace(function (namespace, actions) {
   return res
   return res
 });
 });
 
 
+var createNamespacedHelpers = function (namespace) { return ({
+  mapState: mapState.bind(null, namespace),
+  mapGetters: mapGetters.bind(null, namespace),
+  mapMutations: mapMutations.bind(null, namespace),
+  mapActions: mapActions.bind(null, namespace)
+}); };
+
 function normalizeMap (map) {
 function normalizeMap (map) {
   return Array.isArray(map)
   return Array.isArray(map)
     ? map.map(function (key) { return ({ key: key, val: key }); })
     ? map.map(function (key) { return ({ key: key, val: key }); })
@@ -782,7 +861,7 @@ function normalizeNamespace (fn) {
 
 
 function getModuleByNamespace (store, helper, namespace) {
 function getModuleByNamespace (store, helper, namespace) {
   var module = store._modulesNamespaceMap[namespace];
   var module = store._modulesNamespaceMap[namespace];
-  if (!module) {
+  if (process.env.NODE_ENV !== 'production' && !module) {
     console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
     console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
   }
   }
   return module
   return module
@@ -791,11 +870,12 @@ function getModuleByNamespace (store, helper, namespace) {
 var index_esm = {
 var index_esm = {
   Store: Store,
   Store: Store,
   install: install,
   install: install,
-  version: '2.3.0',
+  version: '2.4.0',
   mapState: mapState,
   mapState: mapState,
   mapMutations: mapMutations,
   mapMutations: mapMutations,
   mapGetters: mapGetters,
   mapGetters: mapGetters,
-  mapActions: mapActions
+  mapActions: mapActions,
+  createNamespacedHelpers: createNamespacedHelpers
 };
 };
 
 
-export { Store, mapState, mapMutations, mapGetters, mapActions };export default index_esm;
+export { Store, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers };export default index_esm;

+ 128 - 48
dist/vuex.js

@@ -1,5 +1,5 @@
 /**
 /**
- * vuex v2.3.0
+ * vuex v2.4.0
  * (c) 2017 Evan You
  * (c) 2017 Evan You
  * @license MIT
  * @license MIT
  */
  */
@@ -13,8 +13,7 @@ var applyMixin = function (Vue) {
   var version = Number(Vue.version.split('.')[0]);
   var version = Number(Vue.version.split('.')[0]);
 
 
   if (version >= 2) {
   if (version >= 2) {
-    var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1;
-    Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit });
+    Vue.mixin({ beforeCreate: vuexInit });
   } else {
   } else {
     // override init and inject vuex init procedure
     // override init and inject vuex init procedure
     // for 1.x backwards compatibility.
     // for 1.x backwards compatibility.
@@ -37,7 +36,9 @@ var applyMixin = function (Vue) {
     var options = this.$options;
     var options = this.$options;
     // store injection
     // store injection
     if (options.store) {
     if (options.store) {
-      this.$store = options.store;
+      this.$store = typeof options.store === 'function'
+        ? options.store()
+        : options.store;
     } else if (options.parent && options.parent.$store) {
     } else if (options.parent && options.parent.$store) {
       this.$store = options.parent.$store;
       this.$store = options.parent.$store;
     }
     }
@@ -166,17 +167,8 @@ Module.prototype.forEachMutation = function forEachMutation (fn) {
 Object.defineProperties( Module.prototype, prototypeAccessors$1 );
 Object.defineProperties( Module.prototype, prototypeAccessors$1 );
 
 
 var ModuleCollection = function ModuleCollection (rawRootModule) {
 var ModuleCollection = function ModuleCollection (rawRootModule) {
-  var this$1 = this;
-
   // register root module (Vuex.Store options)
   // register root module (Vuex.Store options)
-  this.root = new Module(rawRootModule, false);
-
-  // register all nested modules
-  if (rawRootModule.modules) {
-    forEachValue(rawRootModule.modules, function (rawModule, key) {
-      this$1.register([key], rawModule, false);
-    });
-  }
+  this.register([], rawRootModule, false);
 };
 };
 
 
 ModuleCollection.prototype.get = function get (path) {
 ModuleCollection.prototype.get = function get (path) {
@@ -194,16 +186,24 @@ ModuleCollection.prototype.getNamespace = function getNamespace (path) {
 };
 };
 
 
 ModuleCollection.prototype.update = function update$1 (rawRootModule) {
 ModuleCollection.prototype.update = function update$1 (rawRootModule) {
-  update(this.root, rawRootModule);
+  update([], this.root, rawRootModule);
 };
 };
 
 
 ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
 ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
     var this$1 = this;
     var this$1 = this;
     if ( runtime === void 0 ) runtime = true;
     if ( runtime === void 0 ) runtime = true;
 
 
-  var parent = this.get(path.slice(0, -1));
+  {
+    assertRawModule(path, rawModule);
+  }
+
   var newModule = new Module(rawModule, runtime);
   var newModule = new Module(rawModule, runtime);
-  parent.addChild(path[path.length - 1], newModule);
+  if (path.length === 0) {
+    this.root = newModule;
+  } else {
+    var parent = this.get(path.slice(0, -1));
+    parent.addChild(path[path.length - 1], newModule);
+  }
 
 
   // register nested modules
   // register nested modules
   if (rawModule.modules) {
   if (rawModule.modules) {
@@ -221,7 +221,11 @@ ModuleCollection.prototype.unregister = function unregister (path) {
   parent.removeChild(key);
   parent.removeChild(key);
 };
 };
 
 
-function update (targetModule, newModule) {
+function update (path, targetModule, newModule) {
+  {
+    assertRawModule(path, newModule);
+  }
+
   // update target module
   // update target module
   targetModule.update(newModule);
   targetModule.update(newModule);
 
 
@@ -229,30 +233,66 @@ function update (targetModule, newModule) {
   if (newModule.modules) {
   if (newModule.modules) {
     for (var key in newModule.modules) {
     for (var key in newModule.modules) {
       if (!targetModule.getChild(key)) {
       if (!targetModule.getChild(key)) {
-        console.warn(
-          "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
-          'manual reload is needed'
-        );
+        {
+          console.warn(
+            "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
+            'manual reload is needed'
+          );
+        }
         return
         return
       }
       }
-      update(targetModule.getChild(key), newModule.modules[key]);
+      update(
+        path.concat(key),
+        targetModule.getChild(key),
+        newModule.modules[key]
+      );
     }
     }
   }
   }
 }
 }
 
 
+function assertRawModule (path, rawModule) {
+  ['getters', 'actions', 'mutations'].forEach(function (key) {
+    if (!rawModule[key]) { return }
+
+    forEachValue(rawModule[key], function (value, type) {
+      assert(
+        typeof value === 'function',
+        makeAssertionMessage(path, key, type, value)
+      );
+    });
+  });
+}
+
+function makeAssertionMessage (path, key, type, value) {
+  var buf = key + " should be function but \"" + key + "." + type + "\"";
+  if (path.length > 0) {
+    buf += " in module \"" + (path.join('.')) + "\"";
+  }
+  buf += " is " + (JSON.stringify(value)) + ".";
+
+  return buf
+}
+
 var Vue; // bind on install
 var Vue; // bind on install
 
 
 var Store = function Store (options) {
 var Store = function Store (options) {
   var this$1 = this;
   var this$1 = this;
   if ( options === void 0 ) options = {};
   if ( options === void 0 ) options = {};
 
 
-  assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
-  assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
+  {
+    assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
+    assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
+    assert(this instanceof Store, "Store must be called with the new operator.");
+  }
 
 
-  var state = options.state; if ( state === void 0 ) state = {};
   var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
   var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
   var strict = options.strict; if ( strict === void 0 ) strict = false;
   var strict = options.strict; if ( strict === void 0 ) strict = false;
 
 
+  var state = options.state; if ( state === void 0 ) state = {};
+  if (typeof state === 'function') {
+    state = state();
+  }
+
   // store internal state
   // store internal state
   this._committing = false;
   this._committing = false;
   this._actions = Object.create(null);
   this._actions = Object.create(null);
@@ -288,7 +328,11 @@ var Store = function Store (options) {
   resetStoreVM(this, state);
   resetStoreVM(this, state);
 
 
   // apply plugins
   // apply plugins
-  plugins.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); });
+  plugins.forEach(function (plugin) { return plugin(this$1); });
+
+  if (Vue.config.devtools) {
+    devtoolPlugin(this);
+  }
 };
 };
 
 
 var prototypeAccessors = { state: {} };
 var prototypeAccessors = { state: {} };
@@ -298,7 +342,9 @@ prototypeAccessors.state.get = function () {
 };
 };
 
 
 prototypeAccessors.state.set = function (v) {
 prototypeAccessors.state.set = function (v) {
-  assert(false, "Use store.replaceState() to explicit replace store state.");
+  {
+    assert(false, "Use store.replaceState() to explicit replace store state.");
+  }
 };
 };
 
 
 Store.prototype.commit = function commit (_type, _payload, _options) {
 Store.prototype.commit = function commit (_type, _payload, _options) {
@@ -313,7 +359,9 @@ Store.prototype.commit = function commit (_type, _payload, _options) {
   var mutation = { type: type, payload: payload };
   var mutation = { type: type, payload: payload };
   var entry = this._mutations[type];
   var entry = this._mutations[type];
   if (!entry) {
   if (!entry) {
-    console.error(("[vuex] unknown mutation type: " + type));
+    {
+      console.error(("[vuex] unknown mutation type: " + type));
+    }
     return
     return
   }
   }
   this._withCommit(function () {
   this._withCommit(function () {
@@ -323,7 +371,10 @@ Store.prototype.commit = function commit (_type, _payload, _options) {
   });
   });
   this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
   this._subscribers.forEach(function (sub) { return sub(mutation, this$1.state); });
 
 
-  if (options && options.silent) {
+  if (
+    "development" !== 'production' &&
+    options && options.silent
+  ) {
     console.warn(
     console.warn(
       "[vuex] mutation type: " + type + ". Silent option has been removed. " +
       "[vuex] mutation type: " + type + ". Silent option has been removed. " +
       'Use the filter functionality in the vue-devtools'
       'Use the filter functionality in the vue-devtools'
@@ -339,7 +390,9 @@ Store.prototype.dispatch = function dispatch (_type, _payload) {
 
 
   var entry = this._actions[type];
   var entry = this._actions[type];
   if (!entry) {
   if (!entry) {
-    console.error(("[vuex] unknown action type: " + type));
+    {
+      console.error(("[vuex] unknown action type: " + type));
+    }
     return
     return
   }
   }
   return entry.length > 1
   return entry.length > 1
@@ -363,7 +416,9 @@ Store.prototype.subscribe = function subscribe (fn) {
 Store.prototype.watch = function watch (getter, cb, options) {
 Store.prototype.watch = function watch (getter, cb, options) {
     var this$1 = this;
     var this$1 = this;
 
 
-  assert(typeof getter === 'function', "store.watch only accepts a function.");
+  {
+    assert(typeof getter === 'function', "store.watch only accepts a function.");
+  }
   return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
   return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
 };
 };
 
 
@@ -377,7 +432,12 @@ Store.prototype.replaceState = function replaceState (state) {
 
 
 Store.prototype.registerModule = function registerModule (path, rawModule) {
 Store.prototype.registerModule = function registerModule (path, rawModule) {
   if (typeof path === 'string') { path = [path]; }
   if (typeof path === 'string') { path = [path]; }
-  assert(Array.isArray(path), "module path must be a string or an Array.");
+
+  {
+    assert(Array.isArray(path), "module path must be a string or an Array.");
+    assert(path.length > 0, 'cannot register the root module by using registerModule.');
+  }
+
   this._modules.register(path, rawModule);
   this._modules.register(path, rawModule);
   installModule(this, this.state, path, this._modules.get(path));
   installModule(this, this.state, path, this._modules.get(path));
   // reset store to update getters...
   // reset store to update getters...
@@ -388,7 +448,11 @@ Store.prototype.unregisterModule = function unregisterModule (path) {
     var this$1 = this;
     var this$1 = this;
 
 
   if (typeof path === 'string') { path = [path]; }
   if (typeof path === 'string') { path = [path]; }
-  assert(Array.isArray(path), "module path must be a string or an Array.");
+
+  {
+    assert(Array.isArray(path), "module path must be a string or an Array.");
+  }
+
   this._modules.unregister(path);
   this._modules.unregister(path);
   this._withCommit(function () {
   this._withCommit(function () {
     var parentState = getNestedState(this$1.state, path.slice(0, -1));
     var parentState = getNestedState(this$1.state, path.slice(0, -1));
@@ -525,7 +589,7 @@ function makeLocalContext (store, namespace, path) {
 
 
       if (!options || !options.root) {
       if (!options || !options.root) {
         type = namespace + type;
         type = namespace + type;
-        if (!store._actions[type]) {
+        if ("development" !== 'production' && !store._actions[type]) {
           console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
           console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
           return
           return
         }
         }
@@ -542,7 +606,7 @@ function makeLocalContext (store, namespace, path) {
 
 
       if (!options || !options.root) {
       if (!options || !options.root) {
         type = namespace + type;
         type = namespace + type;
-        if (!store._mutations[type]) {
+        if ("development" !== 'production' && !store._mutations[type]) {
           console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
           console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
           return
           return
         }
         }
@@ -594,14 +658,14 @@ function makeLocalGetters (store, namespace) {
 function registerMutation (store, type, handler, local) {
 function registerMutation (store, type, handler, local) {
   var entry = store._mutations[type] || (store._mutations[type] = []);
   var entry = store._mutations[type] || (store._mutations[type] = []);
   entry.push(function wrappedMutationHandler (payload) {
   entry.push(function wrappedMutationHandler (payload) {
-    handler(local.state, payload);
+    handler.call(store, local.state, payload);
   });
   });
 }
 }
 
 
 function registerAction (store, type, handler, local) {
 function registerAction (store, type, handler, local) {
   var entry = store._actions[type] || (store._actions[type] = []);
   var entry = store._actions[type] || (store._actions[type] = []);
   entry.push(function wrappedActionHandler (payload, cb) {
   entry.push(function wrappedActionHandler (payload, cb) {
-    var res = handler({
+    var res = handler.call(store, {
       dispatch: local.dispatch,
       dispatch: local.dispatch,
       commit: local.commit,
       commit: local.commit,
       getters: local.getters,
       getters: local.getters,
@@ -625,7 +689,9 @@ function registerAction (store, type, handler, local) {
 
 
 function registerGetter (store, type, rawGetter, local) {
 function registerGetter (store, type, rawGetter, local) {
   if (store._wrappedGetters[type]) {
   if (store._wrappedGetters[type]) {
-    console.error(("[vuex] duplicate getter key: " + type));
+    {
+      console.error(("[vuex] duplicate getter key: " + type));
+    }
     return
     return
   }
   }
   store._wrappedGetters[type] = function wrappedGetter (store) {
   store._wrappedGetters[type] = function wrappedGetter (store) {
@@ -640,7 +706,9 @@ function registerGetter (store, type, rawGetter, local) {
 
 
 function enableStrictMode (store) {
 function enableStrictMode (store) {
   store._vm.$watch(function () { return this._data.$$state }, function () {
   store._vm.$watch(function () { return this._data.$$state }, function () {
-    assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
+    {
+      assert(store._committing, "Do not mutate vuex store state outside mutation handlers.");
+    }
   }, { deep: true, sync: true });
   }, { deep: true, sync: true });
 }
 }
 
 
@@ -657,16 +725,20 @@ function unifyObjectStyle (type, payload, options) {
     type = type.type;
     type = type.type;
   }
   }
 
 
-  assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
+  {
+    assert(typeof type === 'string', ("Expects string as the type, but found " + (typeof type) + "."));
+  }
 
 
   return { type: type, payload: payload, options: options }
   return { type: type, payload: payload, options: options }
 }
 }
 
 
 function install (_Vue) {
 function install (_Vue) {
   if (Vue) {
   if (Vue) {
-    console.error(
-      '[vuex] already installed. Vue.use(Vuex) should be called only once.'
-    );
+    {
+      console.error(
+        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
+      );
+    }
     return
     return
   }
   }
   Vue = _Vue;
   Vue = _Vue;
@@ -736,7 +808,7 @@ var mapGetters = normalizeNamespace(function (namespace, getters) {
       if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
       if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
         return
         return
       }
       }
-      if (!(val in this.$store.getters)) {
+      if ("development" !== 'production' && !(val in this.$store.getters)) {
         console.error(("[vuex] unknown getter: " + val));
         console.error(("[vuex] unknown getter: " + val));
         return
         return
       }
       }
@@ -768,6 +840,13 @@ var mapActions = normalizeNamespace(function (namespace, actions) {
   return res
   return res
 });
 });
 
 
+var createNamespacedHelpers = function (namespace) { return ({
+  mapState: mapState.bind(null, namespace),
+  mapGetters: mapGetters.bind(null, namespace),
+  mapMutations: mapMutations.bind(null, namespace),
+  mapActions: mapActions.bind(null, namespace)
+}); };
+
 function normalizeMap (map) {
 function normalizeMap (map) {
   return Array.isArray(map)
   return Array.isArray(map)
     ? map.map(function (key) { return ({ key: key, val: key }); })
     ? map.map(function (key) { return ({ key: key, val: key }); })
@@ -788,7 +867,7 @@ function normalizeNamespace (fn) {
 
 
 function getModuleByNamespace (store, helper, namespace) {
 function getModuleByNamespace (store, helper, namespace) {
   var module = store._modulesNamespaceMap[namespace];
   var module = store._modulesNamespaceMap[namespace];
-  if (!module) {
+  if ("development" !== 'production' && !module) {
     console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
     console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
   }
   }
   return module
   return module
@@ -797,11 +876,12 @@ function getModuleByNamespace (store, helper, namespace) {
 var index = {
 var index = {
   Store: Store,
   Store: Store,
   install: install,
   install: install,
-  version: '2.3.0',
+  version: '2.4.0',
   mapState: mapState,
   mapState: mapState,
   mapMutations: mapMutations,
   mapMutations: mapMutations,
   mapGetters: mapGetters,
   mapGetters: mapGetters,
-  mapActions: mapActions
+  mapActions: mapActions,
+  createNamespacedHelpers: createNamespacedHelpers
 };
 };
 
 
 return index;
 return index;

文件差异内容过多而无法显示
+ 1 - 1
dist/vuex.min.js


部分文件因为文件数量过多而无法显示