1
0

module-collection.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import Module from './module'
  2. import { assert, forEachValue } from '../util'
  3. export default class ModuleCollection {
  4. constructor (rawRootModule) {
  5. // register root module (Vuex.Store options)
  6. this.register([], rawRootModule, false)
  7. }
  8. get (path) {
  9. return path.reduce((module, key) => {
  10. return module.getChild(key)
  11. }, this.root)
  12. }
  13. getNamespace (path) {
  14. let module = this.root
  15. return path.reduce((namespace, key) => {
  16. module = module.getChild(key)
  17. return namespace + (module.namespaced ? key + '/' : '')
  18. }, '')
  19. }
  20. update (rawRootModule) {
  21. update([], this.root, rawRootModule)
  22. }
  23. register (path, rawModule, runtime = true) {
  24. if (process.env.NODE_ENV !== 'production') {
  25. assertRawModule(path, rawModule)
  26. }
  27. const newModule = new Module(rawModule, runtime)
  28. if (path.length === 0) {
  29. this.root = newModule
  30. } else {
  31. const parent = this.get(path.slice(0, -1))
  32. parent.addChild(path[path.length - 1], newModule)
  33. }
  34. // register nested modules
  35. if (rawModule.modules) {
  36. forEachValue(rawModule.modules, (rawChildModule, key) => {
  37. this.register(path.concat(key), rawChildModule, runtime)
  38. })
  39. }
  40. }
  41. unregister (path) {
  42. const parent = this.get(path.slice(0, -1))
  43. const key = path[path.length - 1]
  44. if (!parent.getChild(key).runtime) return
  45. parent.removeChild(key)
  46. }
  47. }
  48. function update (path, targetModule, newModule) {
  49. if (process.env.NODE_ENV !== 'production') {
  50. assertRawModule(path, newModule)
  51. }
  52. // update target module
  53. targetModule.update(newModule)
  54. // update nested modules
  55. if (newModule.modules) {
  56. for (const key in newModule.modules) {
  57. if (!targetModule.getChild(key)) {
  58. if (process.env.NODE_ENV !== 'production') {
  59. console.warn(
  60. `[vuex] trying to add a new module '${key}' on hot reloading, ` +
  61. 'manual reload is needed'
  62. )
  63. }
  64. return
  65. }
  66. update(
  67. path.concat(key),
  68. targetModule.getChild(key),
  69. newModule.modules[key]
  70. )
  71. }
  72. }
  73. }
  74. function assertRawModule (path, rawModule) {
  75. ['getters', 'actions', 'mutations'].forEach(key => {
  76. if (!rawModule[key]) return
  77. forEachValue(rawModule[key], (value, type) => {
  78. assert(
  79. typeof value === 'function',
  80. makeAssertionMessage(path, key, type, value)
  81. )
  82. })
  83. })
  84. }
  85. function makeAssertionMessage (path, key, type, value) {
  86. let buf = `${key} should be function but "${key}.${type}"`
  87. if (path.length > 0) {
  88. buf += ` in module "${path.join('.')}"`
  89. }
  90. buf += ` is ${JSON.stringify(value)}.`
  91. return buf
  92. }