Делаю простое приложение по серии уроков из
https://youtu.be/DlXSA3_lSX4.
Дошел до момента, когда в роутинге проверяем залогинен ли пользователь и отправляем в соответствующие страницы:
router/index.jsimport Vue from 'vue'
import VueRouter from 'vue-router'
// Routes
import Home from '@/views/Home'
import TasksPage from '@/views/TasksPage'
import Login from '@/views/Auth/Login'
import Registration from '@/views/Auth/Registration'
import store from '../store'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
beforeEnter(to, from, next) {
store.getters.checkUser ? next() : next('/login')
}
},
{
path: '/tasks',
name: 'tasks',
component: TasksPage,
beforeEnter(to, from, next) {
store.getters.checkUser ? next() : next('/login')
}
},
{
path: '/login',
name: 'login',
component: Login,
beforeEnter(to, from, next) {
!store.getters.checkUser ? next() : next('/')
}
},
{
path: '/registration',
name: 'registration',
component: Registration,
beforeEnter(to, from, next) {
!store.getters.checkUser ? next() : next('/')
}
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
beforeEnter проверяет checkUser, который в свое время в модуле стора выглядит по дефолту так:
store/user.jsimport firebase from 'firebase/app'
import User from './user_help'
export default {
state: {
user: null
},
mutations: {
setUser(state, payload) {
state.user = payload
}
},
actions: {
async registerUser({commit}, {email, password}) {
commit('clearError')
commit('setLoading', true)
try {
const user = await firebase.auth().createUserWithEmailAndPassword(email, password)
commit('setUser', new User(user.user.uid))
commit('setLoading', false)
} catch (err) {
commit('setLoading', false)
commit('setError', err.message)
throw err
}
},
async loginUser({commit}, {email, password}) {
commit('clearError')
commit('setLoading', true)
try {
const user = await firebase.auth().signInWithEmailAndPassword(email, password)
commit('setUser', new User(user.user.uid))
commit('setLoading', false)
} catch (err) {
commit('setLoading', false)
commit('setError', err.message)
throw err
}
},
loggedUser({commit}, payload) {
commit('setUser', new User(payload.uid))
},
logoutUser({commit}) {
firebase.auth().signOut()
commit('setUser', null)
}
},
getters: {
user(state) {
return state.user
},
checkUser(state) {
return state.user !== null
}
}
}
Для изменения user в стейте есть мутация setUser и тот класс User, что она использует так же импортирован:
export default class User {
constructor(id) {
this.id = id
}
}
В main.js перед всем этим делом по сути должен отрабатывать метод created():
main.jsnew Vue({
router,
store,
render: h => h(App),
created() {
const firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
}
firebase.initializeApp(firebaseConfig)
firebase.auth().onAuthStateChanged( user => {
if (user) {
this.$store.dispatch('loggedUser', user)
}
})
}
}).$mount('#app')
Суть ошибки заключается в том, что теперь когда я обновляю страницу с веб приложением будучи авторизованым пользователем, beforeEnter не дожидаясь пока firebase проверит меня на авторизацию использует дефолтное значение null и перекидывает меня на страницу логина. та же самая история происходит с навигацией которую я реализовал следующим образом:
Navbar.vue...
computed: {
checkUser() {
return this.$store.getters.checkUser
},
linkMenu() {
if (this.checkUser) {
return [
{ name: 'Home', url: '/' },
{ name: 'Tasks', url: '/tasks' }
]
}
return [
{ name: 'Login', url: '/login' },
{ name: 'Registration', url: '/registration' }
]
}
}
...
То есть сначала checkUser получает дефолтное false, отрабатывает его по текущему значению и потом исправляется реактивно, после того как firebase подтвердил авторизацию.