├── .gitignore ├── src ├── index.js ├── vuex-alt-plugin.test.js ├── vuex-alt-helpers.js └── vuex-alt-plugin.js ├── .babelrc ├── rollup.config.js ├── .circleci └── config.yml ├── LICENSE ├── package.json ├── README.md └── dist └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export { mapState, mapGetters, mapActions } from './vuex-alt-helpers'; 2 | export { VuexAltPlugin } from './vuex-alt-plugin'; -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "presets": [ 5 | ["@babel/preset-env"] 6 | ] 7 | } 8 | }, 9 | "presets": [ 10 | ["@babel/preset-env", { 11 | "modules": false, 12 | "targets": { 13 | "chrome": 40, 14 | "ie": 10 15 | } 16 | }] 17 | ] 18 | } -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | // rollup.config.js 2 | import resolve from 'rollup-plugin-node-resolve'; 3 | import commonjs from 'rollup-plugin-commonjs'; 4 | 5 | export default { 6 | input: 'src/index.js', 7 | output: { 8 | file: 'dist/index-not-transpiled.js', 9 | format: 'cjs' 10 | }, 11 | plugins: [ 12 | resolve(), 13 | commonjs() 14 | ] 15 | }; -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/node:7.10 6 | working_directory: ~/repo 7 | 8 | steps: 9 | - checkout 10 | 11 | # Download and cache dependencies 12 | - restore_cache: 13 | keys: 14 | - v1-dependencies-{{ checksum "package.json" }} 15 | # fallback to using the latest cache if no exact match is found 16 | - v1-dependencies- 17 | 18 | - run: npm install 19 | 20 | - save_cache: 21 | paths: 22 | - node_modules 23 | key: v1-dependencies-{{ checksum "package.json" }} 24 | 25 | # run test and verify bundle 26 | - run: npm run test 27 | - run: npm run bundle 28 | 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Evan Francis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuex-alt", 3 | "version": "0.0.8", 4 | "description": "An alternative approach to Vuex helpers for accessing state, getters and actions that doesn't rely on string constants.", 5 | "main": "dist/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/ejfrancis/Vuex-Alt.git" 9 | }, 10 | "scripts": { 11 | "test": "jest", 12 | "build": "npm run test && npm run bundle", 13 | "bundle": "rimraf dist/ && rollup --config rollup.config.js && babel dist/index-not-transpiled.js --out-file dist/index.js && rimraf dist/index-not-transpiled.js", 14 | "prepush": "npm run test && npm run build" 15 | }, 16 | "keywords": [ 17 | "Vue", 18 | "Vuex", 19 | "action", 20 | "actions", 21 | "plugin" 22 | ], 23 | "author": "Evan Francis", 24 | "license": "MIT", 25 | "devDependencies": { 26 | "@babel/cli": "^7.1.5", 27 | "@babel/core": "^7.1.6", 28 | "@babel/preset-env": "^7.1.6", 29 | "babel-core": "^7.0.0-bridge.0", 30 | "babel-jest": "^23.6.0", 31 | "husky": "^1.1.4", 32 | "jest": "^23.6.0", 33 | "rimraf": "^2.6.1", 34 | "rollup": "^0.67.1", 35 | "rollup-plugin-commonjs": "^9.2.0", 36 | "rollup-plugin-node-resolve": "^3.4.0" 37 | }, 38 | "dependencies": { 39 | "camelcase": "^4.1.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/vuex-alt-plugin.test.js: -------------------------------------------------------------------------------- 1 | const VuexAltPlugin = require('./vuex-alt-plugin').VuexAltPlugin; 2 | 3 | describe('VuexAltPlugin', () => { 4 | describe('actions', () => { 5 | it('adds _actionsNestedObject to Vue', () => { 6 | class VueMock {}; 7 | const storeMock = { 8 | _actions: {}, 9 | getters: {} 10 | } 11 | VuexAltPlugin.install(VueMock, { store: storeMock }); 12 | const instance = new VueMock(); 13 | expect(typeof instance._actionsNestedObject === 'object').toEqual(true); 14 | }); 15 | it('creates proper nested actions object', () => { 16 | class VueMock {}; 17 | const someActionMock = jest.fn(); 18 | const anotherActionMock = jest.fn(); 19 | const storeMock = { 20 | _actions: { 21 | 'moduleA/someAction': [someActionMock], 22 | 'moduleB/subModuleB/anotherAction': [anotherActionMock] 23 | }, 24 | getters: {} 25 | } 26 | VuexAltPlugin.install(VueMock, { store: storeMock }); 27 | const instance = new VueMock(); 28 | instance._actionsNestedObject.moduleA.someAction(); 29 | instance._actionsNestedObject.moduleB.subModuleB.anotherAction(); 30 | expect(someActionMock.mock.calls.length).toEqual(1); 31 | expect(anotherActionMock.mock.calls.length).toEqual(1); 32 | }); 33 | }); 34 | describe('getters', () => { 35 | it('adds _gettersNestedObject to Vue', () => { 36 | class VueMock {}; 37 | const storeMock = { 38 | _actions: {}, 39 | getters: {} 40 | } 41 | VuexAltPlugin.install(VueMock, { store: storeMock }); 42 | const instance = new VueMock(); 43 | expect(typeof instance._gettersNestedObject === 'object').toEqual(true); 44 | }); 45 | it('creates proper nested getters object', () => { 46 | class VueMock {}; 47 | const storeMock = { 48 | _actions: {}, 49 | getters: { 50 | 'moduleA/someGetter': 'someGetter', 51 | 'moduleB/subModuleB/anotherGetter': 'anotherGetter' 52 | } 53 | } 54 | VuexAltPlugin.install(VueMock, { store: storeMock }); 55 | const instance = new VueMock(); 56 | expect(instance._gettersNestedObject.moduleA.someGetter()).toEqual('someGetter'); 57 | expect(instance._gettersNestedObject.moduleB.subModuleB.anotherGetter()).toEqual('anotherGetter'); 58 | }); 59 | }); 60 | }); -------------------------------------------------------------------------------- /src/vuex-alt-helpers.js: -------------------------------------------------------------------------------- 1 | export const mapState = normalizeNamespace((namespace, states) => { 2 | const res = {} 3 | normalizeMap(states).forEach(({ key, val }) => { 4 | res[key] = function mappedState() { 5 | let state = this.$store.state 6 | let getters = this.$store.getters 7 | if (namespace) { 8 | const module = getModuleByNamespace(this.$store, 'mapState', namespace) 9 | if (!module) { 10 | return 11 | } 12 | state = module.context.state 13 | getters = module.context.getters 14 | } 15 | return typeof val === 'function' 16 | ? val.call(this, state, getters) 17 | : state[val] 18 | } 19 | // mark vuex getter for devtools 20 | res[key].vuex = true 21 | }) 22 | return res 23 | }) 24 | 25 | export const mapGetters = function (gettersMap) { 26 | const res = {}; 27 | const keys = Object.keys(gettersMap); 28 | for (let i = 0; i < keys.length; i++) { 29 | const thisGetterKey = keys[i]; 30 | const thisGetterMappingFn = gettersMap[thisGetterKey]; 31 | res[thisGetterKey] = function (...args) { 32 | return thisGetterMappingFn(this._gettersNestedObject)(); 33 | } 34 | } 35 | return res; 36 | } 37 | 38 | export const mapActions = function (actionsMap) { 39 | const res = {}; 40 | const keys = Object.keys(actionsMap); 41 | for (let i = 0; i < keys.length; i++) { 42 | const thisActionKey = keys[i]; 43 | const thisActionMappingFn = actionsMap[thisActionKey]; 44 | res[thisActionKey] = function (...args) { 45 | return thisActionMappingFn(this._actionsNestedObject)(...args); 46 | } 47 | } 48 | return res; 49 | } 50 | 51 | function normalizeMap(map) { 52 | return Array.isArray(map) 53 | ? map.map(key => ({ key, val: key })) 54 | : Object.keys(map).map(key => ({ key, val: map[key] })) 55 | } 56 | 57 | function normalizeNamespace(fn) { 58 | return (namespace, map) => { 59 | if (typeof namespace !== 'string') { 60 | map = namespace 61 | namespace = '' 62 | } else if (namespace.charAt(namespace.length - 1) !== '/') { 63 | namespace += '/' 64 | } 65 | return fn(namespace, map) 66 | } 67 | } 68 | 69 | function getModuleByNamespace(store, helper, namespace) { 70 | const module = store._modulesNamespaceMap[namespace] 71 | if (process.env.NODE_ENV !== 'production' && !module) { 72 | console.error(`[vuex] module namespace not found in ${helper}(): ${namespace}`) 73 | } 74 | return module 75 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vuex-Alt 2 | An alternative, opinionated approach to Vuex helpers for accessing state, getters and actions that doesn't rely on string constants. 3 | 4 | ## Installation 5 | 6 | First install the npm package with 7 | 8 | ```npm install --save vuex-alt``` 9 | 10 | Then use the plugin, passing in the Vuex Store. 11 | 12 | ```javascript 13 | import Vuex from 'vuex'; 14 | import { VuexAltPlugin } from 'vuex-alt'; 15 | 16 | // use Vuex as usual 17 | Vue.use(Vuex); 18 | 19 | // create your store 20 | const store = new Vuex.Store({ ... }); 21 | 22 | // use the VuexAltPlugin, and pass it 23 | // the new Vuex Store 24 | Vue.use(VuexAltPlugin, { store }); 25 | ``` 26 | 27 | ## Prerequisites 28 | Vuex-Alt makes two intentional, opinionated assumptions about your Vuex code: 29 | 30 | 1. Mutations are only commited from within actions. Components never directly commit mutations. Every mutation has an accompanying action. 31 | 2. All Vuex state, getters and actions are organized into [Vuex modules](https://vuex.vuejs.org/en/modules.html). 32 | 33 | These two rules lead to more scalable state management code, and more predictable state changes. 34 | 35 | ## API Usage 36 | Vuex-Alt provides an alternative approach to the Vuex helpers for `mapState`, `mapActions`, and `mapGetters`. 37 | 38 | The main difference between the Vuex-Alt helpers and the original Vuex helpers is that instead of accepting strings to specify the namespace and action/getter you want, access is done via functions and nested objects. 39 | 40 | ### mapState() 41 | Provide an object that maps local Vuex instance properties to Vuex module properties. 42 | 43 | For example, if you have a state property called `count` on a Vuex store module called `counter` you would access it like this: 44 | 45 | ```javascript 46 | computed: { 47 | ...mapState({ 48 | count: (state) => state.counter.count 49 | }) 50 | } 51 | ``` 52 | 53 | ### mapActions() 54 | Provide an object that maps local Vuex instance methods to Vuex module methods. 55 | 56 | For example, if you have an action called `increment()` on a Vuex store module called `counter` you would access it like this: 57 | 58 | ```javascript 59 | methods: { 60 | ...mapActions({ 61 | increment: (actions) => actions.counter.increment 62 | }) 63 | } 64 | ``` 65 | 66 | Now you can access it in your component via `this.increment(10)`. 67 | 68 | ### mapGetters() 69 | Provide an object that maps local Vuex instance properties to Vuex module getters. 70 | 71 | For example, if you have a getter called `countPlusTen()` on a Vuex store module called `counter` you would access it like this: 72 | 73 | ```javascript 74 | computed: { 75 | ...mapGetters({ 76 | countPlusTen: (getters) => getters.counter.countPlusTen 77 | }) 78 | } 79 | ``` -------------------------------------------------------------------------------- /src/vuex-alt-plugin.js: -------------------------------------------------------------------------------- 1 | import camelCase from 'camelcase'; 2 | 3 | const isNamespaced = (actionName) => actionName.indexOf('/') !== -1; 4 | 5 | const splitNamespacedName = (actionName) => { 6 | const splitActionName = actionName.split('/'); 7 | const namespaces = splitActionName.slice(0, splitActionName.length -1); 8 | const name = splitActionName.slice(-1)[0]; 9 | return { 10 | name, 11 | namespaces 12 | } 13 | } 14 | 15 | const VuexAltPlugin = { 16 | install: (Vue, options) => { 17 | const actions = options.store && options.store._actions; 18 | const actionsNestedObject = {}; 19 | 20 | Object.keys(actions).forEach((thisActionName) => { 21 | const thisActionFunctions = actions[thisActionName]; 22 | const thisActionFunction = thisActionFunctions[0]; 23 | 24 | const actionFn = function(...args) { 25 | if (!thisActionFunction) { 26 | return; 27 | } 28 | return thisActionFunction.apply(this, args); 29 | }; 30 | 31 | if (isNamespaced(thisActionName)) { 32 | const { name, namespaces } = splitNamespacedName(thisActionName); 33 | 34 | // ensure each nested namespace exists as an object nested properly 35 | let currentParent = actionsNestedObject; 36 | namespaces.forEach((thisNamespace) => { 37 | currentParent[thisNamespace] = currentParent[thisNamespace] || {}; 38 | currentParent = currentParent[thisNamespace] 39 | }); 40 | 41 | // store this action on proper parent obj, and convert to camelCase as well 42 | currentParent[name] = actionFn; 43 | currentParent[camelCase(name)] = actionFn; 44 | } else { 45 | // store action on root scope, and convert to camelCase as well 46 | actionsNestedObject[thisActionName] = actionFn; 47 | actionsNestedObject[camelCase(thisActionName)] = actionFn; 48 | } 49 | }); 50 | 51 | const getters = options.store && options.store.getters; 52 | const gettersNestedObject = {}; 53 | 54 | Object.keys(getters).forEach((thisGetterName) => { 55 | const thisGetter = getters[thisGetterName]; 56 | 57 | const thisGetterFn = function() { 58 | return getters[thisGetterName]; 59 | } 60 | 61 | if (isNamespaced(thisGetterName)) { 62 | const { name, namespaces } = splitNamespacedName(thisGetterName); 63 | 64 | // ensure each nested namespace exists as an object nested properly 65 | let currentParent = gettersNestedObject; 66 | namespaces.forEach((thisNamespace) => { 67 | currentParent[thisNamespace] = currentParent[thisNamespace] || {}; 68 | currentParent = currentParent[thisNamespace] 69 | }); 70 | 71 | // store this action on proper parent obj, and convert to camelCase as well 72 | currentParent[name] = thisGetterFn; 73 | currentParent[camelCase(name)] = thisGetterFn; 74 | } else { 75 | // store action on root scope, and convert to camelCase as well 76 | gettersNestedObject[thisGetterName] = thisGetterFn; 77 | gettersNestedObject[camelCase(thisGetterName)] = thisGetterFn; 78 | } 79 | }); 80 | 81 | Vue.prototype._actionsNestedObject = actionsNestedObject; 82 | Vue.prototype._gettersNestedObject = gettersNestedObject; 83 | } 84 | } 85 | 86 | export { 87 | VuexAltPlugin 88 | } 89 | 90 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true 5 | }); 6 | var mapState = normalizeNamespace(function (namespace, states) { 7 | var res = {}; 8 | normalizeMap(states).forEach(function (_ref) { 9 | var key = _ref.key, 10 | val = _ref.val; 11 | 12 | res[key] = function mappedState() { 13 | var state = this.$store.state; 14 | var getters = this.$store.getters; 15 | 16 | if (namespace) { 17 | var module = getModuleByNamespace(this.$store, 'mapState', namespace); 18 | 19 | if (!module) { 20 | return; 21 | } 22 | 23 | state = module.context.state; 24 | getters = module.context.getters; 25 | } 26 | 27 | return typeof val === 'function' ? val.call(this, state, getters) : state[val]; 28 | }; // mark vuex getter for devtools 29 | 30 | 31 | res[key].vuex = true; 32 | }); 33 | return res; 34 | }); 35 | 36 | var mapGetters = function mapGetters(gettersMap) { 37 | var res = {}; 38 | var keys = Object.keys(gettersMap); 39 | 40 | var _loop = function _loop(i) { 41 | var thisGetterKey = keys[i]; 42 | var thisGetterMappingFn = gettersMap[thisGetterKey]; 43 | 44 | res[thisGetterKey] = function () { 45 | return thisGetterMappingFn(this._gettersNestedObject)(); 46 | }; 47 | }; 48 | 49 | for (var i = 0; i < keys.length; i++) { 50 | _loop(i); 51 | } 52 | 53 | return res; 54 | }; 55 | 56 | var mapActions = function mapActions(actionsMap) { 57 | var res = {}; 58 | var keys = Object.keys(actionsMap); 59 | 60 | var _loop2 = function _loop2(i) { 61 | var thisActionKey = keys[i]; 62 | var thisActionMappingFn = actionsMap[thisActionKey]; 63 | 64 | res[thisActionKey] = function () { 65 | return thisActionMappingFn(this._actionsNestedObject).apply(void 0, arguments); 66 | }; 67 | }; 68 | 69 | for (var i = 0; i < keys.length; i++) { 70 | _loop2(i); 71 | } 72 | 73 | return res; 74 | }; 75 | 76 | function normalizeMap(map) { 77 | return Array.isArray(map) ? map.map(function (key) { 78 | return { 79 | key: key, 80 | val: key 81 | }; 82 | }) : Object.keys(map).map(function (key) { 83 | return { 84 | key: key, 85 | val: map[key] 86 | }; 87 | }); 88 | } 89 | 90 | function normalizeNamespace(fn) { 91 | return function (namespace, map) { 92 | if (typeof namespace !== 'string') { 93 | map = namespace; 94 | namespace = ''; 95 | } else if (namespace.charAt(namespace.length - 1) !== '/') { 96 | namespace += '/'; 97 | } 98 | 99 | return fn(namespace, map); 100 | }; 101 | } 102 | 103 | function getModuleByNamespace(store, helper, namespace) { 104 | var module = store._modulesNamespaceMap[namespace]; 105 | 106 | if (process.env.NODE_ENV !== 'production' && !module) { 107 | console.error("[vuex] module namespace not found in ".concat(helper, "(): ").concat(namespace)); 108 | } 109 | 110 | return module; 111 | } 112 | 113 | function preserveCamelCase(str) { 114 | var isLastCharLower = false; 115 | var isLastCharUpper = false; 116 | var isLastLastCharUpper = false; 117 | 118 | for (var i = 0; i < str.length; i++) { 119 | var c = str[i]; 120 | 121 | if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) { 122 | str = str.substr(0, i) + '-' + str.substr(i); 123 | isLastCharLower = false; 124 | isLastLastCharUpper = isLastCharUpper; 125 | isLastCharUpper = true; 126 | i++; 127 | } else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) { 128 | str = str.substr(0, i - 1) + '-' + str.substr(i - 1); 129 | isLastLastCharUpper = isLastCharUpper; 130 | isLastCharUpper = false; 131 | isLastCharLower = true; 132 | } else { 133 | isLastCharLower = c.toLowerCase() === c; 134 | isLastLastCharUpper = isLastCharUpper; 135 | isLastCharUpper = c.toUpperCase() === c; 136 | } 137 | } 138 | 139 | return str; 140 | } 141 | 142 | var camelcase = function camelcase(str) { 143 | if (arguments.length > 1) { 144 | str = Array.from(arguments).map(function (x) { 145 | return x.trim(); 146 | }).filter(function (x) { 147 | return x.length; 148 | }).join('-'); 149 | } else { 150 | str = str.trim(); 151 | } 152 | 153 | if (str.length === 0) { 154 | return ''; 155 | } 156 | 157 | if (str.length === 1) { 158 | return str.toLowerCase(); 159 | } 160 | 161 | if (/^[a-z0-9]+$/.test(str)) { 162 | return str; 163 | } 164 | 165 | var hasUpperCase = str !== str.toLowerCase(); 166 | 167 | if (hasUpperCase) { 168 | str = preserveCamelCase(str); 169 | } 170 | 171 | return str.replace(/^[_.\- ]+/, '').toLowerCase().replace(/[_.\- ]+(\w|$)/g, function (m, p1) { 172 | return p1.toUpperCase(); 173 | }); 174 | }; 175 | 176 | var isNamespaced = function isNamespaced(actionName) { 177 | return actionName.indexOf('/') !== -1; 178 | }; 179 | 180 | var splitNamespacedName = function splitNamespacedName(actionName) { 181 | var splitActionName = actionName.split('/'); 182 | var namespaces = splitActionName.slice(0, splitActionName.length - 1); 183 | var name = splitActionName.slice(-1)[0]; 184 | return { 185 | name: name, 186 | namespaces: namespaces 187 | }; 188 | }; 189 | 190 | var VuexAltPlugin = { 191 | install: function install(Vue, options) { 192 | var actions = options.store && options.store._actions; 193 | var actionsNestedObject = {}; 194 | Object.keys(actions).forEach(function (thisActionName) { 195 | var thisActionFunctions = actions[thisActionName]; 196 | var thisActionFunction = thisActionFunctions[0]; 197 | 198 | var actionFn = function actionFn() { 199 | if (!thisActionFunction) { 200 | return; 201 | } 202 | 203 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 204 | args[_key] = arguments[_key]; 205 | } 206 | 207 | return thisActionFunction.apply(this, args); 208 | }; 209 | 210 | if (isNamespaced(thisActionName)) { 211 | var _splitNamespacedName = splitNamespacedName(thisActionName), 212 | name = _splitNamespacedName.name, 213 | namespaces = _splitNamespacedName.namespaces; // ensure each nested namespace exists as an object nested properly 214 | 215 | 216 | var currentParent = actionsNestedObject; 217 | namespaces.forEach(function (thisNamespace) { 218 | currentParent[thisNamespace] = currentParent[thisNamespace] || {}; 219 | currentParent = currentParent[thisNamespace]; 220 | }); // store this action on proper parent obj, and convert to camelCase as well 221 | 222 | currentParent[name] = actionFn; 223 | currentParent[camelcase(name)] = actionFn; 224 | } else { 225 | // store action on root scope, and convert to camelCase as well 226 | actionsNestedObject[thisActionName] = actionFn; 227 | actionsNestedObject[camelcase(thisActionName)] = actionFn; 228 | } 229 | }); 230 | var getters = options.store && options.store.getters; 231 | var gettersNestedObject = {}; 232 | Object.keys(getters).forEach(function (thisGetterName) { 233 | var thisGetter = getters[thisGetterName]; 234 | 235 | var thisGetterFn = function thisGetterFn() { 236 | return getters[thisGetterName]; 237 | }; 238 | 239 | if (isNamespaced(thisGetterName)) { 240 | var _splitNamespacedName2 = splitNamespacedName(thisGetterName), 241 | name = _splitNamespacedName2.name, 242 | namespaces = _splitNamespacedName2.namespaces; // ensure each nested namespace exists as an object nested properly 243 | 244 | 245 | var currentParent = gettersNestedObject; 246 | namespaces.forEach(function (thisNamespace) { 247 | currentParent[thisNamespace] = currentParent[thisNamespace] || {}; 248 | currentParent = currentParent[thisNamespace]; 249 | }); // store this action on proper parent obj, and convert to camelCase as well 250 | 251 | currentParent[name] = thisGetterFn; 252 | currentParent[camelcase(name)] = thisGetterFn; 253 | } else { 254 | // store action on root scope, and convert to camelCase as well 255 | gettersNestedObject[thisGetterName] = thisGetterFn; 256 | gettersNestedObject[camelcase(thisGetterName)] = thisGetterFn; 257 | } 258 | }); 259 | Vue.prototype._actionsNestedObject = actionsNestedObject; 260 | Vue.prototype._gettersNestedObject = gettersNestedObject; 261 | } 262 | }; 263 | exports.mapState = mapState; 264 | exports.mapGetters = mapGetters; 265 | exports.mapActions = mapActions; 266 | exports.VuexAltPlugin = VuexAltPlugin; 267 | --------------------------------------------------------------------------------