Как получить доступ к этой переменной из моего хранилища / состояния в моем маршрутизаторе Vue? - PullRequest
1 голос
/ 21 марта 2019

Я настроил свой файл 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);
					})
				})
			},
	}

});

my 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 ]

2 голосов
/ 22 марта 2019

Прежде всего, ваша конфигурация и весь ваш импорт верны.

Это очень интересный вопрос ... Я исследовал его и могу сделать вывод, что в процессе трансплантации webpack + babel есть какая-то ошибка. Позвольте мне объяснить:

Если вы проверите свой пакет, вы увидите, что в вашей динамической строке import есть странное нетранслируемое concat выражение, что-то вроде этого: ("./".concat(state.taskURL,".vue")) - но state следует обернуть помощниками веб-пакета, но это не так t ... Похоже, что разрешение модуля было пропущено для import интерполяции строки оператора.

Самое простое решение - просто назначить импортированный модуль какой-либо переменной и использовать эту переменную в операторе import ( Я рекомендую использовать полностью настроенное хранилище вместо состояния ):

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

В этом случае модуль будет корректно обработан веб-пакетом.

P.S. Я создал чистый проект с помощью всего лишь веб-пакета и попытался поиграть с динамическим импортом, и они были успешно решены ... Так что я полагаю, что проблема в другом слое транспорта, может быть, babel.

P.P.S. Если мое объяснение недостаточно четкое, пожалуйста, не стесняйтесь спрашивать в комментариях.

0 голосов
/ 21 марта 2019

Вам просто нужно импортировать его как:

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

Тогда вы можете использовать его как:

store.commit('increaseCounter')
0 голосов
/ 21 марта 2019

Отредактированный ответ, ссылка в комментариях.

Я уверен, что проблема как-то связана с областями переменных и фактическим именем state, я не могу выполнить отладку вузнать с этой информацией.Но я могу с уверенностью предложить вам альтернативное решение.Вот что вам нужно сделать шаг за шагом.

Шаг 1: В вашем store.js прямо перед export const state = {

export const TASK_INFO = {
    taskURL: 'define-product-service'
}

Шаг 2: В вашем routes.js наверху

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

Шаг 3: На самом деле

component:  () => import(`./components/ProductServiceAnalysis/${TASK_INFO.taskURL}.vue`),

И это должно сработать, как мы надеемся.

...