如何从我的Vue路由器中的商店/州访问此变量?

时间:2019-03-21 11:01:37

标签: javascript vue.js vuejs2 vue-router

我已经设置了route.js文件,以便从商店中导入我的状态。当我console.log(state)将商店成功输出到控制台时,它就起作用了:

enter image description here

然后,我将路线定义如下:

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:

我按照你的建议做了。我在console.log(之前放置了); ./ components / ProductServiceAnalysis / $ {state.taskURL} .vue const routes = [ ...,它可以正确访问taskURL属性并将其打印到控制台。但是,当它尝试从路由本身内部访问同一属性时,即使它在const routes = [外部进行访问,它仍然会失败,并显示“状态未定义”:

enter image description here

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

3 个答案:

答案 0 :(得分:2)

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

这是一个非常有趣的问题...我已经对其进行了研究,可以得出结论,在webpack + babel的编译过程中存在一种错误。让我解释一下:

如果检查包,您会发现动态concat行中有一个奇怪的未转译的import表达式,如下所示:("./".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。如果我的解释不够清楚,请随时在评论中提问。

答案 1 :(得分:0)

编辑后的答案,注释中的引用。

我确定问题与可变范围和实际名称JavaRDD<Row> rows = vertexRDD.map(line -> line.split("\t")) 有关,我无法进行调试以找出此信息。但我可以肯定地为您提供替代解决方案。这是您需要逐步进行的操作。

步骤1:state之前的store.js

export const state = {

步骤2:在顶部的export const TASK_INFO = { taskURL: 'define-product-service' }

routes.js

步骤3:实际位置

import { TASK_INFO } from './store/store';

这应该可以按预期工作。

答案 2 :(得分:0)

您只需要像这样导入它:

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

然后您可以像使用它一样

store.commit('increaseCounter')