1 | import Vue from 'vue'
|
2 | import Vuex from 'vuex'
|
3 |
|
4 | Vue.use(Vuex)
|
5 |
|
6 | <%
|
7 | const willResolveStoreModules = storeModules.some(s => s.src.indexOf('index.') !== 0)
|
8 | if (willResolveStoreModules) { %>
|
9 | const VUEX_PROPERTIES = ['state', 'getters', 'actions', 'mutations']
|
10 | <% } %>
|
11 | let store = {};
|
12 |
|
13 | (function updateModules () {
|
14 | <% storeModules.some(s => {
|
15 | if(s.src.indexOf('index.') === 0) { %>
|
16 | store = normalizeRoot(require('<%= relativeToBuild(srcDir, dir.store, s.src) %>'), '<%= dir.store %>/<%= s.src %>')
|
17 | <% return true }}) %>
|
18 |
|
19 |
|
20 | <% if (isDev) { %>
|
21 | if (typeof store === 'function') {
|
22 | <%= isTest ? '// eslint-disable-next-line no-console' : '' %>
|
23 | return console.warn('Classic mode for store/ is deprecated and will be removed in Nuxt 3.')
|
24 | }<% } %>
|
25 |
|
26 |
|
27 | store.modules = store.modules || {}
|
28 |
|
29 | <% storeModules.forEach(s => {
|
30 | if(s.src.indexOf('index.') !== 0) { %>
|
31 | resolveStoreModules(require('<%= relativeToBuild(srcDir, dir.store, s.src) %>'), '<%= s.src %>')<% }}) %>
|
32 |
|
33 |
|
34 | <% if (isDev) { %>
|
35 | if (process.client && module.hot) {
|
36 |
|
37 | module.hot.accept([<% storeModules.forEach(s => { %>
|
38 | '<%= relativeToBuild(srcDir, dir.store, s.src) %>',<% }) %>
|
39 | ], () => {
|
40 | // Update `root.modules` with the latest definitions.
|
41 | updateModules()
|
42 | // Trigger a hot update in the store.
|
43 | window.<%= globals.nuxt %>.$store.hotUpdate(store)
|
44 | })
|
45 | }<% } %>
|
46 | })()
|
47 |
|
48 | // createStore
|
49 | export const createStore = store instanceof Function ? store : () => {
|
50 | return new Vuex.Store(Object.assign({
|
51 | strict: (process.env.NODE_ENV !== 'production')
|
52 | }, store))
|
53 | }
|
54 |
|
55 | function normalizeRoot (moduleData, filePath) {
|
56 | moduleData = moduleData.default || moduleData
|
57 |
|
58 | if (moduleData.commit) {
|
59 | throw new Error(`[nuxt] ${filePath} should export a method that returns a Vuex instance.`)
|
60 | }
|
61 |
|
62 | if (typeof moduleData !== 'function') {
|
63 | // Avoid TypeError: setting a property that has only a getter when overwriting top level keys
|
64 | moduleData = Object.assign({}, moduleData)
|
65 | }
|
66 | return normalizeModule(moduleData, filePath)
|
67 | }
|
68 |
|
69 | function normalizeModule (moduleData, filePath) {
|
70 | if (moduleData.state && typeof moduleData.state !== 'function') {
|
71 | <%= isTest ? '// eslint-disable-next-line no-console' : '' %>
|
72 | console.warn(`'state' should be a method that returns an object in ${filePath}`)
|
73 |
|
74 | const state = Object.assign({}, moduleData.state)
|
75 | // Avoid TypeError: setting a property that has only a getter when overwriting top level keys
|
76 | moduleData = Object.assign({}, moduleData, { state: () => state })
|
77 | }
|
78 | return moduleData
|
79 | }
|
80 |
|
81 | <% if (willResolveStoreModules) { %>
|
82 | function resolveStoreModules (moduleData, filename) {
|
83 | moduleData = moduleData.default || moduleData
|
84 | // Remove store src + extension (./foo/index.js -> foo/index)
|
85 | const namespace = filename.replace(/\.(<%= extensions %>)$/, '')
|
86 | const namespaces = namespace.split('/')
|
87 | let moduleName = namespaces[namespaces.length - 1]
|
88 | const filePath = `<%= dir.store %>/${filename}`
|
89 |
|
90 | moduleData = moduleName === 'state'
|
91 | ? normalizeState(moduleData, filePath)
|
92 | : normalizeModule(moduleData, filePath)
|
93 |
|
94 | // If src is a known Vuex property
|
95 | if (VUEX_PROPERTIES.includes(moduleName)) {
|
96 | const property = moduleName
|
97 | const propertyStoreModule = getStoreModule(store, namespaces, { isProperty: true })
|
98 |
|
99 | // Replace state since it's a function
|
100 | mergeProperty(propertyStoreModule, moduleData, property)
|
101 | return
|
102 | }
|
103 |
|
104 | // If file is foo/index.js, it should be saved as foo
|
105 | const isIndexModule = (moduleName === 'index')
|
106 | if (isIndexModule) {
|
107 | namespaces.pop()
|
108 | moduleName = namespaces[namespaces.length - 1]
|
109 | }
|
110 |
|
111 | const storeModule = getStoreModule(store, namespaces)
|
112 |
|
113 | for (const property of VUEX_PROPERTIES) {
|
114 | mergeProperty(storeModule, moduleData[property], property)
|
115 | }
|
116 |
|
117 | if (moduleData.namespaced === false) {
|
118 | delete storeModule.namespaced
|
119 | }
|
120 | }
|
121 |
|
122 | function normalizeState (moduleData, filePath) {
|
123 | if (typeof moduleData !== 'function') {
|
124 | <%= isTest ? '// eslint-disable-next-line no-console' : '' %>
|
125 | console.warn(`${filePath} should export a method that returns an object`)
|
126 | const state = Object.assign({}, moduleData)
|
127 | return () => state
|
128 | }
|
129 | return normalizeModule(moduleData, filePath)
|
130 | }
|
131 |
|
132 | function getStoreModule (storeModule, namespaces, { isProperty = false } = {}) {
|
133 | // If ./mutations.js
|
134 | if (!namespaces.length || (isProperty && namespaces.length === 1)) {
|
135 | return storeModule
|
136 | }
|
137 |
|
138 | const namespace = namespaces.shift()
|
139 |
|
140 | storeModule.modules[namespace] = storeModule.modules[namespace] || {}
|
141 | storeModule.modules[namespace].namespaced = true
|
142 | storeModule.modules[namespace].modules = storeModule.modules[namespace].modules || {}
|
143 |
|
144 | return getStoreModule(storeModule.modules[namespace], namespaces, { isProperty })
|
145 | }
|
146 |
|
147 | function mergeProperty (storeModule, moduleData, property) {
|
148 | if (!moduleData) {
|
149 | return
|
150 | }
|
151 |
|
152 | if (property === 'state') {
|
153 | storeModule.state = moduleData || storeModule.state
|
154 | } else {
|
155 | storeModule[property] = Object.assign({}, storeModule[property], moduleData)
|
156 | }
|
157 | }
|
158 | <% } %>
|
159 |
|
\ | No newline at end of file |