проблема при использовании созданной функции в двух компонентах одновременно - PullRequest
0 голосов
/ 21 февраля 2020

В моем приложении есть зарегистрированная область, когда вы успешно входите в систему, глобальная переменная "auth" примет значение loggedin, в моем основном vue компоненте приложения. vue Я загружаю компонент заголовка, который включает в себя панель навигации и представление маршрутизатора Я вызываю созданную функцию в компоненте заголовка, чтобы прочитать значение «auth», чтобы показать ссылку для входа в систему и скрыть ссылки профиля, чата и выхода из системы. Я также хочу использовать метод sema в некоторых представлениях маршрутизатора (char и profile). ), чтобы пользователь не мог получить к ним доступ и вывести маршрутизатор на страницу входа в систему, когда переменная «auth» не зарегистрирована. В этом случае приложение. vue должно запускать созданную функцию дважды, компонент заголовка правильно читает значение «auth», а представление маршрутизатора - нет. Есть ли решение для этого? или любой другой способ запретить доступ к зарегистрированной области без входа в систему?


update

Я пробовал vuex, и я получил эту ошибку (Невозможно прочитать свойство 'commit' из undefined) и store.state.auth по-прежнему имеет значение false

, это мой компонент входа в систему


<script>
/* eslint-disable */
import axios from 'axios'
import router from '../router'
import EventBus from './EventBus.vue'
  export default {
  data () {
    return {
      email: '',
      password: '',
      error: ''
    }
  },
  methods: {
    login () {
      axios.post('users/login', {
        email: this.email,
        password: this.password
      }).then(res => {
        console.log('user exist ')

        localStorage.setItem('usertoken', res.data)
        this.email = ''
        this.password = ''
        router.push({ name: 'Profile' })
        this.$store.commit('login') // sets auth to true
        this.emitMethod() 
      }).catch(err => {
        console.log(err.message)
        this.error = ('User does not exist ')
        this.email = ''
        this.password = ''
      })
    },
    onReset(evt) {
        evt.preventDefault()
        // Reset our form values
        this.email = ''
        this.password = ''

        // Trick to reset/clear native browser form validation state
        this.show = false
        this.$nextTick(() => {
          this.show = true
        })
      },
    emitMethod () {
      EventBus.$emit('logged-in', 'loggedin')

    }
  }
}
</script>

, а вот главный. js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import AllIosIcon from 'vue-ionicons/dist/ionicons-ios.js'
import Vuex from 'vuex'

/* eslint no-console: ["error", { allow: ["warn", "error"] }] */

Vue.use(Vuex)
Vue.use(AllIosIcon)

Vue.use(VueRouter)
const store = new Vuex.Store({
  state: {
      auth: false
  },
  mutations: {
      login: (state) => state.auth = true,
      logout: (state) => state.auth = false
  }
})

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/products',
    name: 'products',

    component: () => import( '../views/Products.vue')
  },{
    path: '/spareParts',
    name: 'spareParts',

    component: () => import( '../views/SpareParts.vue')
  },
  {
    path: '/contact',
    name: 'contact',

    component: () => import( '../views/Contact.vue')
  },
  {
    path: '/login',
    name: 'login',

    component: () => import( '../views/logIn.vue')
  },
  {
    path: '/About',
    name: 'About',

    component: () => import( '../views/About.vue')
  },
  {
    path: '/Profile',
    name: 'Profile',

    component: () => import( '../views/Profile.vue'),
    meta: {
      requiresAuth: true
    }
  },
  {
    path: '/Chat',
    name: 'Chat',

    component: () => import( '../views/Chat.vue'),
    meta: {
      requiresAuth: true
    }
  },
  {
    path: '/Spare1',
    name: 'Spare1',

    component: () => import( '../views/Spare1.vue')
  },
  {
    path: '/spare2',
    name: 'spare2',

    component: () => import( '../views/spare2.vue')
  },
  {
    path: '/spare3',
    name: 'spare3',

    component: () => import( '../views/spare3.vue')
  },
  {
    path: '/spare4',
    name: 'spare4',

    component: () => import( '../views/spare4.vue')
  },
  {
    path: '/spare5',
    name: 'spare5',

    component: () => import( '../views/spare5.vue')
  },
  {
    path: '/spare6',
    name: 'spare6',

    component: () => import( '../views/spare6.vue')
  },
  {
    path: '/spare7',
    name: 'spare7',

    component: () => import( '../views/spare7.vue')
  },
  {
    path: '/spare8',
    name: 'spare8',

    component: () => import( '../views/spare8.vue')
  },
  {
    path: '/spare9',
    name: 'spare9',

    component: () => import( '../views/spare9.vue')
  },
  {
    path: '/spare10',
    name: 'spare10',

    component: () => import( '../views/spare10.vue')
  },
  {
    path: '/spare11',
    name: 'spare11',

    component: () => import( '../views/spare11.vue')
  },
  {
    path: '/spare12',
    name: 'spare12',

    component: () => import( '../views/spare12.vue')
  },
  {
    path: '/spare13',
    name: 'spare13',

    component: () => import( '../views/spare13.vue')
  },
  {
    path: '/spare14',
    name: 'spare14',

    component: () => import( '../views/spare14.vue')
  },
  {
    path: '/spare15',
    name: 'spare15',

    component: () => import( '../views/spare15.vue')
  },
  {
    path: '/spare16',
    name: 'spare16',

    component: () => import( '../views/spare16.vue')
  },
  {
    path: '/spare17',
    name: 'spare17',

    component: () => import( '../views/spare17.vue')
  },
  {
    path: '/spare18',
    name: 'spare18',

    component: () => import( '../views/spare18.vue')
  },
  {
    path: '/spare19',
    name: 'spare19',

    component: () => import( '../views/spare19.vue')
  },
  {
    path: '/spare20',
    name: 'spare20',

    component: () => import( '../views/spare20.vue')
  },
  {
    path: '/spare21',
    name: 'spare21',

    component: () => import( '../views/spare21.vue')
  },
  {
    path: '/spare22',
    name: 'spare22',

    component: () => import( '../views/spare22.vue')
  },
  {
    path: '/spare23',
    name: 'spare23',

    component: () => import( '../views/spare23.vue')
  },
  {
    path: '/product1',
    name: 'product1',

    component: () => import( '../views/product1.vue')
  },
  {
    path: '/freezer',
    name: 'freezer',

    component: () => import( '../views/freezer.vue')
  },
  {
    path: '/construction',
    name: 'construction',

    component: () => import( '../views/construction.vue')
  },
  {
    path: '/product2',
    name: 'product2',

    component: () => import( '../views/product2.vue')
  },
  {
    path: '/earth',
    name: 'earth',

    component: () => import( '../views/earth.vue')
  },
  {
    path: '/crawler',
    name: 'crawler',

    component: () => import( '../views/crawler.vue')
  },
  {
    path: '/articulated',
    name: 'articulated',

    component: () => import( '../views/articulated.vue')
  },
  {
    path: '/wheel',
    name: 'wheel',

    component: () => import( '../views/wheel.vue')
  },
  {
    path: '/tractor',
    name: 'tractor',

    component: () => import( '../views/tractor.vue')
  },
  {
    path: '/telescopic',
    name: 'telescopic',

    component: () => import( '../views/telescopic.vue')
  },
  {
    path: '/loader',
    name: 'loader',

    component: () => import( '../views/loader.vue')
  },
  {
    path: '/pipe',
    name: 'pipe',

    component: () => import( '../views/pipe.vue')
  },
  {
    path: '/pontoon',
    name: 'pontoon',

    component: () => import( '../views/pontoon.vue')
  },
  {
    path: '/duty',
    name: 'duty',

    component: () => import( '../views/duty.vue')
  },
  {
    path: '/attachment',
    name: 'attachment',

    component: () => import( '../views/attachment.vue')
  },
  {
    path: '/customer',
    name: 'customer',

    component: () => import( '../views/customer.vue')
  },
  {
    path: '/side',
    name: 'side',

    component: () => import( '../views/side.vue')
  },
  {
    path: '/wine',
    name: 'wine',

    component: () => import( '../views/wine.vue')
  },
  {
    path: '/accessories',
    name: 'accessories',

    component: () => import( '../views/accessories.vue')
  },
  {
    path: '/hotel',
    name: 'hotel',

    component: () => import( '../views/hotel.vue')
  },
  {
    path: '/bakery',
    name: 'bakery',

    component: () => import( '../views/bakery.vue')
  },
  {
    path: '/retail',
    name: 'retail',

    component: () => import( '../views/retail.vue')
  },
  {
    path: '/industry',
    name: 'industry',

    component: () => import( '../views/industry.vue')
  },
  {
    path: '/mining',
    name: 'mining',

    component: () => import( '../views/mining.vue')
  },
  {
    path: '/mobile',
    name: 'mobile',

    component: () => import( '../views/mobile.vue')
  },
  {
    path: '/material',
    name: 'material',

    component: () => import( '../views/material.vue')
  },
  {
    path: '/maritime',
    name: 'maritime',

    component: () => import( '../views/maritime.vue')
  },
  {
    path: '/aero',
    name: 'aero',

    component: () => import( '../views/aero.vue')
  },
  {
    path: '/gear',
    name: 'gear',

    component: () => import( '../views/gear.vue')
  },
  {
    path: '/combust',
    name: 'combust',

    component: () => import( '../views/combust.vue')
  },
  {
    path: '/hotelgroup',
    name: 'hotelgroup',

    component: () => import( '../views/hotelgroup.vue')
  },
  {
    path: '/deep',
    name: 'deep',

    component: () => import( '../views/deep.vue')
  },
  {
    path: '/tower',
    name: 'tower',

    component: () => import( '../views/tower.vue')
  },
  {
    path: '/concrete',
    name: 'concrete',

    component: () => import( '../views/concrete.vue')
  },
  {
    path: '/problem',
    name: 'problem',

    component: () => import( '../views/problem.vue')
  }
]

const router = new VueRouter({
  routes // short for routes: routes
})


router.beforeEach((to, from, next) => {
  console.error(store.state.auth)
  if (to.meta.requiresAuth && !store.state.auth) {

    // this route requires auth, check if logged in
    // if not, redirect to login page.


      next({ name: 'login' })

  } else {
    next() // does not require auth, make sure to always call next()!
  }
})



export default router; store

обновлено

main. js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import BootstrapVue from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import AllIosIcon from 'vue-ionicons/dist/ionicons-ios.js'
import i18n from './i18n'
import store from './router'

Vue.use(AllIosIcon)

Vue.use(BootstrapVue)


Vue.config.productionTip = false

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

теперь я получил эту ошибку _this. $ Store.commit не является функцией

1 Ответ

1 голос
/ 21 февраля 2020

На мой взгляд, лучший способ справиться с этим - использовать vuex для управления состоянием и vue-router навигационные средства защиты.

Посмотрите на код ниже, чтобы понять, как это можно сделать.

main. js

import Vue from 'vue'
import Vuex from 'vuex'
import VueRouter from 'vue-router'

Vue.use(Vuex)
Vue.use(VueRouter)

const store = new Vuex.Store({
    state: {
        auth: false
    },
    mutations: {
        login: (state) => state.auth = true,
        logout: (state) => state.auth = false
    }
})

const router = new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/dashboard',
            component: Dashboard,
            name: 'dashboard',
            meta: {
                requiresAuth: true
            }
        },
        {
            path: '/login',
            component: Login,
            name: 'login',
        },
    ]
})

router.beforeEach((to, from, next) => {
    if (to.meta.requiresAuth && !store.state.auth) {
        next({
            path: '/login',
            query: {
                redirectTo: to.path
            }
        })
    }

    next()
})

const app = new Vue({
    el: '#app',
    store,
    router
})

То, что мы здесь делаем, - это установка центрального источника правды для статуса авторизации пользователя. Навигационная охрана beforeEach запускается до ввода маршрута. В этом случае мы проверяем, требует ли маршрут аутентификации (используя метаданные requiresAuth). Если для маршрута требуется аутентификация, и вы не вошли в систему, он перенаправит вас на страницу входа.

Ваша страница входа в систему должна иметь logi c, который регистрирует пользователя и устанавливает состояние аутентификации на true.

Вход. vue

<template>
  // ...
</template>

<script>
export default {
    methods: {
        login() {
            // login logic here
            // after successful login
            this.$store.commit('login') // sets auth to true
        }
    }
}
</script>

Это может потребовать больше усилий, но в итоге вы получите лучшие результаты.

...