Vue-Router 경로 정의 시 Vuex 상태 액세스
다음과 같은 Vuex 스토어(main.js)가 있다.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//init store
const store = new Vuex.Store({
state: {
globalError: '',
user: {
authenticated: false
}
},
mutations: {
setGlobalError (state, error) {
state.globalError = error
}
}
})
//init app
const app = new Vue({
router: Router,
store,
template: '<app></app>',
components: { App }
}).$mount('#app')
또한 Vue 라우터(routes.js)에 대해 정의된 다음과 같은 경로가 있다.
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//define routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
그렇게 만들려고 하는거야, 만약 Vuex가user
목적어, 그리고 그것은authenticated
로 설정된 재산.false
는 라우터가 사용자를 로그인 페이지로 리디렉션하도록 한다.
난 이걸 가지고 있다:
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLogin) && ???) {
// set Vuex state's globalError, then redirect
next("/Login")
} else {
next()
}
})
문제는 부익스 스토어에 어떻게 접속해야 하는지 모른다는 겁니다.user
내부에서 반대하다beforeEach
기능을 발휘하다
다음을 사용하여 라우터 가드 로직을 구성 요소 내부에 포함할 수 있다는 것을 알고 있다.BeforeRouteEnter
그러나 그것은 각각의 요소들을 복잡하게 만들 것이다.대신 라우터 수준에서 중앙에서 정의하고 싶다.
여기서 제안한 대로, 당신이 할 수 있는 일은 당신의 상점이 있는 파일에서 당신의 상점을 내보내고 그것을 routes.js로 가져오는 것이다.그것은 다음과 같은 것이 될 것이다.
가게가 하나 있잖아.js:
import Vuex from 'vuex'
//init store
const store = new Vuex.Store({
state: {
globalError: '',
user: {
authenticated: false
}
},
mutations: {
setGlobalError (state, error) {
state.globalError = error
}
}
})
export default store
이제 routes.js에서 다음을 수행하십시오.
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from ./store.js
Vue.use(VueRouter)
//define routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLogin) && ???) {
// You can use store variable here to access globalError or commit mutation
next("/Login")
} else {
next()
}
})
main.js에서는 또한 가져올 수 있다.store
:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import store from './store.js'
//init app
const app = new Vue({
router: Router,
store,
template: '<app></app>',
components: { App }
}).$mount('#app')
라우터가 주입된 루트 Vue 인스턴스에 액세스한 다음 다음 다음 를 통해 정기적으로 스토어에 액세스하십시오.router.app.$store
.
const router = new Router({
routes,
})
router.beforeEach((to, from, next) => {
// access store via `router.app.$store` here.
if (router.app.$store.getters('user')) next();
else next({ name: 'login' });
})
부에 3
그router.app
Vue 3에서 제거되었지만 마이그레이션 안내서에 설명된 대로 라우터를 사용할 때 이 라우터를 추가할 수 있음:
app.use(router)
router.app = app
나는 결국 main.js에서 store/index.js로 저장소를 옮기고 라우터.js 파일로 가져오기:
import store from './store'
//routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
//guard clause
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLogin) && store.state.user.authenticated == false) {
store.commit("setGlobalError", "You need to log in before you can perform this action.")
next("/Login")
} else {
next()
}
})
나머지 애플리케이션 상태와 별도로 위치 상태를 관리하면 이러한 상황이 필요 이상으로 어려워질 수 있다.Redex와 Vuex에서 모두 유사한 문제를 처리한 후, 나는 다음을 사용하여 Vuex 스토어 내의 위치 상태를 관리하기 시작했다.router
모듈그 방법을 사용하는 것에 대해 생각해 보는 것이 좋을 것이다.
구체적인 경우, Vuex 스토어 자체 내에서 위치가 변경되는 시점을 주시하고 다음과 같은 적절한 "리디렉션" 조치를 발송할 수 있다.
dispatch("router/push", {path: "/login"})
위치 상태를 Vuex 모듈로 관리하는 것은 생각보다 쉽다.내 것을 시험해 보고 싶다면 내 것을 출발점으로 삼을 수 있다.
https://github.com/geekytime/vuex-router
@Saurabh 제안대로 스토어를 가져오는 것이 효과가 있다.그러나 IMHO 그것은 당신의 코드에 어떤 해결책 냄새를 가져온다.
그것은 효과가 있다, 왜냐하면 Vuex 상점은 싱글톤이기 때문이다.이를 가져오면 구성 요소, 라우터 및 저장소 간에 하드 링크된 종속성이 생성된다.적어도 단위 테스트는 어렵게 만든다.Vue-router가 디커플링되어 이와 같이 동작하는 이유가 있으며, 제안된 패턴을 따르고 라우터를 실제 스토어 인스턴스에서 디커플링된 상태로 유지하는 것이 결실을 맺을 수 있다.
부루터의 근원을 살펴보면, 라우터에서 스토어에 접속할 수 있는 보다 우아한 방법이 있다는 것이 명백해진다.beforeRouteEnter
가드:
beforeRouteEnter: (to, from, next) => {
next(vm => {
// access any getter/action here via vm.$store
// avoid importing the store singleton and thus creating hard dependencies
})
}
10시에 편집하십시오.2020년 9월 (그런 점을 지적해줘서 @Andi 고마워)
beforeRouteEnter
경비는 구체적인 사건에 달려있다.배트 밖에는 다음과 같은 옵션이 보인다.
- Global Guard에서 필요한 구성요소를 필터링하지 않고 혼합된 구성요소에 가드를 선언하고 필요한 구성요소에 선택적으로 사용
- 글로벌 믹싱으로 가드 선언(예: 선언 특성 확인 후 선언 필요)
Vue.use(VueRouter);
: 여기와 여기)
나는 라우터에서 그 상점을 이용할 수 없다는 것을 알았다.py 가드 라우터를 사용할 때.before각각, 그러나 가드를 라우터.beforeResolve로 변경함으로써 스토어를 사용할 수 있게 되었다.
나는 또한 각각보다 이전에 가드 라우터에서 상점의 가져오기를 기다림으로써 나는 성공적으로 각보다 먼저 라우터를 사용할 수 있다는 것을 알았다.나는 그것의 예를 라우터 아래에 제공한다.Resolve 코드보다.
그래서 수술실 질문에 대한 나의 예를 그대로 유지한다면, 다음은 수술실이 나에게 어떻게 작용했을까 입니다.나는 vue-roouter 3.0.2와 vuex 3.1.0을 사용하고 있다.
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store'; //or use a full path to ./store
Vue.use(VueRouter)
//define routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
const router = new VueRouter({
routes //es6
})
router.beforeResolve((to, from, next) => {
const user = store.state.user.user; //store with namespaced modules
if (to.matched.some(record => record.meta.requiresLogin) && user.isLoggedIn) {
next() //proceed to the route
} else next("/login") //redirect to login
})
export default router;
나는 또한 라우터를 얻을 수 있다는 것을 알게 되었다.각각은 각 경비대에 상점의 로드를 기다림으로써 일을 할 수 있다.
router.beforeEach(async (to, from, next) => {
const store = await import('@/store'); //await the store
const user = store.state.user.user; //store with namespaced modules
if (to.matched.some(record => record.meta.requiresLogin) && user.isLoggedIn) {
.... //and continue as above
});
이것이 내가 할 수 있는 방법이다.
App.vue에서는 인증 세부사항을 저장하는 쿠키에 감시자를 두겠다. (확실히 인증 후 인증 세부사항이 포함된 토큰을 쿠키로 저장하겠다.)
이제 이 쿠키가 비어 있을 때마다 사용자를 /login 페이지로 라우팅할 것이다.로그아웃하면 쿠키가 삭제된다.이제 사용자가 로그아웃한 후 다시 히트할 경우 쿠키가 존재하지 않기 때문에(사용자를 로그인해야 함) 사용자는 로그인 페이지로 라우팅된다.
나는 vuex-router-sync가 가장 쉬운 해결책이라는 것을 알았다.해당 사이트의 경우:
현재 경로를 나타내는 상태를 포함하는 경로 모듈을 스토어에 추가한다.
참조URL: https://stackoverflow.com/questions/42603909/accessing-vuex-state-when-defining-vue-router-routes
'programing' 카테고리의 다른 글
64비트 Windows에서 긴 비트 크기 (0) | 2022.05.15 |
---|---|
동적으로 생성된 구성 요소의 vuex 저장소 분리 (0) | 2022.05.15 |
부에가 있는 칸에 캔버스를 넣으려면 어떻게 해야 할까? (0) | 2022.05.15 |
Vuex에서 상태 어레이를 업데이트하는 방법? (0) | 2022.05.15 |
일반 자바스크립트의 VueJS (0) | 2022.05.15 |