Nuxt/packages/vue-app/template/store.js

143 lines
4.7 KiB
JavaScript
Raw Normal View History

2016-12-25 20:16:30 +00:00
import Vue from 'vue'
import Vuex from 'vuex'
2017-05-13 17:32:11 +00:00
2016-12-25 20:16:30 +00:00
Vue.use(Vuex)
const log = console // on server-side, consola will catch all console.log
const VUEX_PROPERTIES = ['state', 'getters', 'actions', 'mutations']
let store = {}
2019-01-06 07:56:59 +00:00
void (function updateModules() {
2019-01-29 09:31:14 +00:00
<% storeModules.some(s => {
if(s.src.indexOf('index.') === 0) { %>
store = normalizeRoot(require('@/<%= dir.store %>/<%= s.src %>'), '<%= dir.store %>/<%= s.src %>')
<% return true }}) %>
// If store is an exported method = classic mode (deprecated)
if (typeof store === 'function') {
return log.warn('Classic mode for store/ is deprecated and will be removed in Nuxt 3.')
2017-05-21 00:03:32 +00:00
}
2017-01-02 09:13:53 +00:00
// Enforce store modules
store.modules = store.modules || {}
2019-01-29 09:31:14 +00:00
<% storeModules.forEach(s => {
if(s.src.indexOf('index.') !== 0) { %>
resolveStoreModules(require('@/<%= dir.store %>/<%= s.src %>'), '<%= s.src %>')<% }}) %>
// If the environment supports hot reloading...
<% if (isDev) { %>
if (process.client && module.hot) {
// Whenever any Vuex module is updated...
2019-01-29 09:31:14 +00:00
module.hot.accept([<% storeModules.forEach(s => { %>
'@/<%= dir.store %>/<%= s.src %>',<% }) %>
], () => {
// Update `root.modules` with the latest definitions.
updateModules()
// Trigger a hot update in the store.
window.<%= globals.nuxt %>.$store.hotUpdate(store)
})
}<% } %>
2019-01-06 07:56:59 +00:00
})()
2017-05-13 17:32:11 +00:00
// createStore
export const createStore = store instanceof Function ? store : () => {
return new Vuex.Store(Object.assign({
strict: (process.env.NODE_ENV !== 'production')
}, store))
2017-05-13 17:45:42 +00:00
}
2017-05-13 17:32:11 +00:00
2019-01-29 09:31:14 +00:00
function resolveStoreModules(moduleData, filename) {
moduleData = moduleData.default || moduleData
// Remove store src + extension (./foo/index.js -> foo/index)
const namespace = filename.replace(/\.(<%= extensions %>)$/, '')
const namespaces = namespace.split('/')
let moduleName = namespaces[namespaces.length - 1]
const filePath = `<%= dir.store %>/${filename}`
moduleData = moduleName === 'state'
? normalizeState(moduleData, filePath)
: normalizeModule(moduleData, filePath)
// If src is a known Vuex property
if (VUEX_PROPERTIES.includes(moduleName)) {
const property = moduleName
const storeModule = getStoreModule(store, namespaces, { isProperty: true })
// Replace state since it's a function
mergeProperty(storeModule, moduleData, property)
return
}
2019-01-29 09:31:14 +00:00
// If file is foo/index.js, it should be saved as foo
const isIndexModule = (moduleName === 'index')
if (isIndexModule) {
namespaces.pop()
moduleName = namespaces[namespaces.length - 1]
}
2019-01-29 09:31:14 +00:00
const storeModule = getStoreModule(store, namespaces)
for (const property of VUEX_PROPERTIES) {
mergeProperty(storeModule, moduleData[property], property)
}
}
function normalizeRoot(moduleData, filePath) {
moduleData = moduleData.default || moduleData
if (moduleData.commit) {
throw new Error(`[nuxt] ${filePath} should export a method that returns a Vuex instance.`)
}
2019-01-29 09:31:14 +00:00
if (typeof moduleData !== 'function') {
// Avoid TypeError: setting a property that has only a getter when overwriting top level keys
moduleData = Object.assign({}, moduleData)
}
2019-01-29 09:31:14 +00:00
return normalizeModule(moduleData, filePath)
}
function normalizeState(moduleData, filePath) {
if (typeof moduleData !== 'function') {
log.warn(`${filePath} should export a method that returns an object`)
const state = Object.assign({}, moduleData)
return () => state
}
return normalizeModule(moduleData, filePath)
}
function normalizeModule(moduleData, filePath) {
if (moduleData.state && typeof moduleData.state !== 'function') {
2019-01-29 09:31:14 +00:00
log.warn(`'state' should be a method that returns an object in ${filePath}`)
const state = Object.assign({}, moduleData.state)
// Avoid TypeError: setting a property that has only a getter when overwriting top level keys
moduleData = Object.assign({}, moduleData, { state: () => state })
2017-05-13 17:32:11 +00:00
}
return moduleData
2016-12-26 16:19:10 +00:00
}
function getStoreModule(storeModule, namespaces, { isProperty = false } = {}) {
// If ./mutations.js
if (!namespaces.length || (isProperty && namespaces.length === 1)) {
return storeModule
2017-03-28 14:28:24 +00:00
}
const namespace = namespaces.shift()
storeModule.modules[namespace] = storeModule.modules[namespace] || {}
storeModule.modules[namespace].namespaced = true
storeModule.modules[namespace].modules = storeModule.modules[namespace].modules || {}
return getStoreModule(storeModule.modules[namespace], namespaces, { isProperty })
}
function mergeProperty(storeModule, moduleData, property) {
if (!moduleData) return
if (property === 'state') {
storeModule.state = moduleData || storeModule.state
} else {
storeModule[property] = Object.assign({}, storeModule[property], moduleData)
}
}