如何从我的 vue 路由器中的商店/状态访问此变量?

How to access this variable from my store / state in my vue router?

我已经设置了我的 routes.js 文件以从我的商店导入我的状态。当我 console.log(state) 它成功地将我的商店输出到控制台时,这是有效的:

然后我定义我的路线如下:

routes.js

   
import { state } from './store/store';
// import { mapState, mapGetters } from "vuex";

console.log(state)

const routes = [
{
  path: '/',
  name: 'home',
  component: Home
},
{
  path: '/dashboard',
  name: 'dashboard',
  component: Dashboard,
},
{
  path: '/project/:id',
  name: 'project',
  component: Project,
  props: true,
  meta: {
    requiresAuth: true,
  },

  children: [
        {
          path: 'module/:module',
          name: 'module',
          component: Tasks,
          props: true,

          children: [
                  {
                    path: 'task/:url',
                    name: 'task',
                    component:  () => import(`./components/ProductServiceAnalysis/${$state.taskURL}.vue`),
                    props: true,

我收到错误: app.js:59653 [vue-router] Failed to resolve async component default: ReferenceError: state is not defined 与我尝试访问 state.taskURL 变量的倒数第二行有关。

为什么会出现这个错误?我如何从我的路由器访问我商店中的 taskURL 变量?

如果我处理不当,请提出建议。

这是我的store.js:

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios'

Vue.use(Vuex);
axios.defaults.baseURL = 'http://buildmybusiness.test/api'

Vue.config.devtools = true;

export const state = {
 token: localStorage.getItem('access_token') || null,
 requiredTask: 'This is my current task',
 currentModule: '1',
 currentModuleName: 'Product & Service Analysis',
 currentTask: '1',
 modules:[],
 tasks:[],
 taskName:[],
 actions:[],
 userId: localStorage.getItem('loggedin_user') || null,
 userName: localStorage.getItem('loggedin_username') || null,
 projects:[],
 currentProjectId: '',
 currentProjectName: '',
 taskURL: 'define-product-service'
}

export const store = new Vuex.Store({

 state,

 mutations: {
  SET_MODULES: (state, payload) => {
   state.modules = payload;
  },

  SET_TASKS: (state, tasks) => {
   state.tasks = tasks;
  },

  SET_MODULE_TITLE: (state, moduleTitle) => {
   state.currentModuleName = moduleTitle
  },

  SET_ACTIONS: (state, payload) => {
   state.actions = payload;
  },

  RETRIEVE_TOKEN: (state, token) => {
   state.token = token;
  },
  DESTROY_TOKEN: (state) => {
   state.token = null;
  },
  SET_USERID: (state, userid) => {
   state.userId = userid;
  },
  DESTROY_USERID: (state) => {
   state.userId = null;
  },


  SET_USERNAME: (state, username) => {
   state.userName = username;
  },
  DESTROY_USERNAME: (state) => {
   state.userName = '';
  },


  SET_PROJECTS: (state, projects) => {
   state.projects = projects;
  },
  DESTROY_PROJECTS: (state) => {
   state.projects = [];
  },


  SET_PROJECT_ID: (state, projectId) => {
   state.currentProjectId = projectId;
  },
  SET_PROJECT_NAME: (state, projectName) => {
   state.currentProjectName = projectName;
  },


  SET_ACTION_URL: (state, taskURL) => {
   state.taskURL = taskURL;
  },

 },

 getters: {

  loggedIn(state){
   return state.token !== null;
  },

  SelectedTaskURL(state) {
   return state.taskURL;
  }
 },

 actions: {

  setActionsURL(context, taskURL){

   context.commit("SET_ACTION_URL", taskURL);

  },

  setProject(context, projectDetails){

   const projectId = projectDetails.projectId;
   const projectName = projectDetails.projectName;

   context.commit("SET_PROJECT_ID", projectId);
    context.commit("SET_PROJECT_NAME", projectName);

  },

  fetchProjects(context) {

    axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token;
    return axios.get('/project').then(response => {

      const projectNames = response.data.map(project => project);
      context.commit("SET_PROJECTS", projectNames);

    });
  },

  getUserDetails(context) {

    axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token;
    return axios.get('/user').then(response => {


     const userid = response.data.id
      localStorage.setItem('loggedin_user', userid)
      context.commit("SET_USERID", userid);

     const username = response.data.name
      localStorage.setItem('loggedin_username', username)
      context.commit("SET_USERNAME", username);
     });
  },

  register(context, data) {
   return new Promise ((resolve, reject) => {
    axios.post('/register', {
     name: data.name,
     email: data.email,
     password: data.password,
    })
    .then(response => {

     resolve(response)

    })
    .catch(error => {

     reject(error);
    })
   })
  },

  destroyToken(context){
   axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token

   if (context.getters.loggedIn){
    return new Promise ((resolve, reject) => {
     axios.post('/logout')
     .then(response => {

      localStorage.removeItem('access_token')
      context.commit("DESTROY_TOKEN")
      context.commit("DESTROY_USERID")
      context.commit("DESTROY_USERNAME")
      context.commit("DESTROY_PROJECTS")
      resolve(response)

     })
     .catch(error => {
      localStorage.removeItem('access_token')
      context.commit("DESTROY_TOKEN")
      context.commit("DESTROY_USERID")
      context.commit("DESTROY_USERNAME")
      context.commit("DESTROY_PROJECTS")
      reject(error);
     })
    })

   }
  },

   loadModules(context) {

     axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token
       return axios.get('/modules').then(response => {

           context.commit("SET_MODULES", response.data);
           });
   },

   getTasks(context, moduleDetails){


    var moduleTitle = moduleDetails.moduleName;
    var moduleTitle = (moduleTitle === undefined) ? moduleTitle = 'Product & Service Analysis' : moduleTitle;
    //console.log(moduleTitle);

    var moduleId = moduleDetails.moduleId;
    var moduleId = (moduleId === undefined) ? moduleId = 1 : moduleId;

     return axios.get(`project/${context.state.currentProjectId}/module/${moduleId}`)
      .then(response => {
       context.commit("SET_TASKS", response.data);

       context.commit("SET_MODULE_TITLE", moduleTitle);
      });
   },

   loadTasks(context, tasks){

   },

   loadActions(context){


   },

   retrieveToken(context, credentials){
    return new Promise ((resolve, reject) => {
     axios.post('/login', {
      username: credentials.username,
      password: credentials.password,
     })
     .then(response => {
      const token = response.data.access_token

      localStorage.setItem('access_token', token)
      context.commit("RETRIEVE_TOKEN", token)
      resolve(response)

     })
     .catch(error => {
      console.log(error);
      reject(error);
     })
    })
   },
 }

});

我的app.js

// main.js

require('./bootstrap');

import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';
import VueAxios from 'vue-axios';
import axios from 'axios';
import routes from './routes';
import BootstrapVue from 'bootstrap-vue'
import { store } from './store/store';
import Vuex from 'vuex'


Vue.config.productionTip = false;

Vue.use(VueRouter);
Vue.use(VueAxios, axios);
Vue.use(BootstrapVue);
Vue.use(Vuex);

const router = new VueRouter({
  
  store,
  routes,
  mode: 'history'
})

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!store.getters.loggedIn) {
      next({
        name: 'login',
      })
    } else {
      next()
    }
  } else if (to.matched.some(record => record.meta.requiresVisitor)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (store.getters.loggedIn) {
      next({
        name: 'dashboard',
      })
    } else {
      next()
    }
  } else {
    next() // make sure to always call next()!
  }
})

new Vue({
    store: store,
    router,
    render: h => h(App)
}).$mount('#app');

import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';

如果引用@shazyriver:

我已经按照你说的做了。我在 const routes = [ ... 之前放了一个 console.log(./components/ProductServiceAnalysis/${state.taskURL}.vue); 可以正确访问 taskURL 属性 并打印它安慰。但是,当它尝试从路由本身内部访问相同的 属性 时,它仍然会失败并显示 'state undefined' - 即使它在 const routes = [:

之外访问时仍然有效

有关详细信息,请参阅控制台日志

你只需要像这样导入它:

import store from './store/store.js'

然后你可以像这样使用它:

store.commit('increaseCounter')

首先,您的配置和所有导入都是正确的。

很有意思的问题。。。我研究了一下,得出的结论是webpack+babel的转译过程中存在一种bug。让我解释一下:

如果您检查您的包,您会发现在您的动态 import 行中有奇怪的未转译的 concat 表达式,类似于:("./".concat(state.taskURL,".vue")) - 但 state应该用 webpack 助手包装,但它不是......看起来模块解析被跳过 import 语句字符串插值。

最简单的解决方案是将导入的模块分配给某个变量并在 import 语句中使用该变量(我建议使用完全配置的存储而不是状态) :

import { store } from './store/store';
let storeVar = store;
//...
//...below
    component:  () => import(`./components/ProductServiceAnalysis/${storeVar.state.taskURL}.vue`),

在这种情况下,模块将被 webpack 正确处理。

P.S。我只用 webpack 创建了一个干净的项目,并尝试使用动态导入,它们被成功解决了……所以我想这个问题在另一个转译层,也许是 babel。

P.P.S。如果我的解释不够清楚,请随时在评论中提问。