У меня есть действие под названием fetchUserPermissions
, которое возвращает набор разрешений от конечной точки api через ax ios. Это действие запускается через другое действие, называемое init, которое запускается автоматически через утилиту dispatchActionForAllModules
, которая в основном ищет действие init во всех модулях / подмодулях и запускает его. Кажется, эта часть работает нормально, но похоже, что конечная точка возвращает html (?) Вместо ответа JSON. Возвращенный ответ выглядит примерно так:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Title</title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <script type="text/javascript" src="http://0.0.0.0:8080/bundle.js" ></script> </body> </html>
Важно знать, что я запускаю от Vue до Django с использованием пакета webpack_loader
. Приведенный выше html - это индекс. html, который обслуживает Vue.
Однако, когда я отправляю действие в ловушку created()
компонента, оно работает должным образом и возвращает что-то вроде { "id": 1, "is_staff": true, "is_superuser": true, "permissions": [ "view_user" ], "group_permissions": [ "has_users_export" ] }
.
Утилита dispatchActionForAllModules
в основном копирует и вставляет из репозитория vue -enterprise-bolierplate.
Как я могу убедиться, что он возвращает ожидаемый ответ JSON?
состояние / магазин. js
import Vue from 'vue'
import Vuex from 'vuex'
import dispatchActionForAllModules from '@/utils/dispatch-action-for-all-modules'
import modules from './modules'
Vue.use(Vuex)
const store = new Vuex.Store({
modules,
strict: process.env.NODE_ENV !== 'production',
})
export default store
// automatically run the `init` action for every module,
// if one exists.
dispatchActionForAllModules('init')
состояние / модули / индекс. js
import camelCase from 'lodash/camelCase'
const modulesCache = {}
const storeData = { modules: {} }
;(function updateModules() {
const requireModule = require.context(
// Search for files in the current directory.
'.',
// Search for files in subdirectories.
true,
// Include any .js files that are not this file or a unit test.
/^((?!index|\.unit\.).)*\.js$/
)
// For every Vuex module...
requireModule.keys().forEach((fileName) => {
const moduleDefinition =
requireModule(fileName).default || requireModule(fileName)
// Skip the module during hot reload if it refers to the
// same module definition as the one we have cached.
if (modulesCache[fileName] === moduleDefinition) return
// Update the module cache, for efficient hot reloading.
modulesCache[fileName] = moduleDefinition
// Get the module path as an array.
const modulePath = fileName
// Remove the "./" from the beginning.
.replace(/^\.\//, '')
// Remove the file extension from the end.
.replace(/\.\w+$/, '')
// Split nested modules into an array path.
.split(/\//)
// camelCase all module namespaces and names.
.map(camelCase)
// Get the modules object for the current path.
const { modules } = getNamespace(storeData, modulePath)
// Add the module to our modules object.
modules[modulePath.pop()] = {
// Modules are namespaced by default.
namespaced: true,
...moduleDefinition,
}
})
// If the environment supports hot reloading...
if (module.hot) {
// Whenever any Vuex module is updated...
module.hot.accept(requireModule.id, () => {
// Update `storeData.modules` with the latest definitions.
updateModules()
// Trigger a hot update in the store.
require('../store').default.hotUpdate({ modules: storeData.modules })
})
}
})()
// Recursively get the namespace of a Vuex module, even if nested.
function getNamespace(subtree, path) {
if (path.length === 1) return subtree
const namespace = path.shift()
subtree.modules[namespace] = {
modules: {},
namespaced: true,
...subtree.modules[namespace],
}
return getNamespace(subtree.modules[namespace], path)
}
export default storeData.modules
состояние / модули / пользователи. js
import axios from 'axios'
export const state = {
requestUserPermissions: [],
}
export const mutations = {
'FETCH_USER_PERMISSIONS' (state, permissions) {
state.requestUserPermissions = permissions
},
}
export const actions = {
init: ({ dispatch }) => {
dispatch('fetchUserPermissions')
},
fetchUserPermissions: ({ commit }) => {
axios.get('user/permissions/').then(result => {
console.log(result.data)
commit('FETCH_USER_PERMISSIONS', result.data)
}).catch(error => {
throw new Error(`API ${error}`)
})
},
}
utils / dispatch-action-for-all.modules. js
import allModules from '@/state/modules'
import store from '@/state/store'
export default function dispatchActionForAllModules(actionName, { modules = allModules, modulePrefix = '', flags = {} } = {}) {
// for every module
for (const moduleName in modules) {
const moduleDefinition = modules[moduleName]
// if the action is defined on the module
if (moduleDefinition.actions && moduleDefinition.actions[actionName]) {
// dispatch the action if the module is namespaced, if not
// set a flag to dispatch action globally at the end
if (moduleDefinition.namespaced) {
store.dispatch(`${modulePrefix}${moduleName}/${actionName}`)
} else {
flags.dispatchGlobal = true
}
}
// if there are nested submodules
if (moduleDefinition.modules) {
// also dispatch action for these sub-modules
dispatchActionForAllModules(actionName, {
modules: moduleDefinition.modules,
modulePrefix: modulePrefix + moduleName + '/',
flags,
})
}
}
// if this is at the root ant at least one non-namespaced module
// was found with the action
if (!modulePrefix && flags.dispatchGlobal) {
// dispatch action globally
store.dispatch(actionName)
}
}
Вычисляемое свойство в компоненте получает данные напрямую из хранилища, например:
permissions() {
return this.$store.state.users.requestUserPermissions
}