/** * vuex v2.1.2 * (c) 2017 Evan You * @license MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.Vuex = factory()); }(this, (function () { 'use strict'; 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); }); } var applyMixin = function (Vue) { var version = Number(Vue.version.split('.')[0]); if (version >= 2) { var usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1; Vue.mixin(usesInit ? { init: vuexInit } : { 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 = options.store; } else if (options.parent && options.parent.$store) { this.$store = options.parent.$store; } } }; 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] }; }); 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 (!(val in this.$store.getters)) { console.error(("[vuex] unknown getter: " + val)); return } return this.$store.getters[val] }; }); 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 }); 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 (!module) { console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace)); } return module } /** * 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} 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 prototypeAccessors$1 = { state: {},namespaced: {} }; prototypeAccessors$1.state.get = function () { return this._rawModule.state || {} }; 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) { var this$1 = this; // 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); }); } }; 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; var parent = this.get(path.slice(0, -1)); var newModule = new Module(rawModule, runtime); 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 (targetModule, newModule) { // update target module targetModule.update(newModule); // update nested modules if (newModule.modules) { for (var key in newModule.modules) { if (!targetModule.getChild(key)) { console.warn( "[vuex] trying to add a new module '" + key + "' on hot reloading, " + 'manual reload is needed' ); return } update(targetModule.getChild(key), newModule.modules[key]); } } } var Vue; // bind on install var Store = function Store (options) { var this$1 = this; 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."); var state = options.state; if ( state === void 0 ) state = {}; var plugins = options.plugins; if ( plugins === void 0 ) plugins = []; var strict = options.strict; if ( strict === void 0 ) strict = false; // 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.concat(devtoolPlugin).forEach(function (plugin) { return plugin(this$1); }); }; var prototypeAccessors = { state: {} }; prototypeAccessors.state.get = function () { return this._vm.$data.state }; prototypeAccessors.state.set = function (v) { 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) { 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 (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) { 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; 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.state = state; }); }; Store.prototype.registerModule = function registerModule (path, rawModule) { if (typeof path === 'string') { path = [path]; } assert(Array.isArray(path), "module path must be a string or an Array."); 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]; } 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.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 (namespace) { 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 (!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 (!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(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({ 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]) { 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('state', function () { 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; } 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) { 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 index = { Store: Store, install: install, version: '2.1.2', mapState: mapState, mapMutations: mapMutations, mapGetters: mapGetters, mapActions: mapActions }; return index; })));