ASync / Await работает не так, как ожидалось в маршрутизаторе.Перед каждой защитой в vue?

#vue.js #vuex #router

#vue.js #vuex #маршрутизатор

Вопрос:

это мой защитник маршрутизатора :

 router.beforeEach(async (to,from,next)=>{   
  await store.dispatch('GetPermission'); 
  if(to.matched.some(record => record.meta.requireAuth)){
    let permissions=store.state.permissions; //getting empty 
    console.log(permissions);
    if(permissions.filter(per => (per.name === 'read_list').length!=0)){
      next({
        path:'/dashboard/create'
      }) 
    }
    else{
        next()  
    }
  
  }
  // else if(to.matched.some(record => record.meta.requireAuth)){
  //     if(store.token!=null){
  //     next({
  //       path:'/dashboard'
  //     }) 
  //   }
  //   else{
  //     next()
  //   }
  // }
  else{
    next()
  }

});
 

проблема здесь, хотя я использую await в методе отправки, я не получаю значение состояния разрешений, которое изначально пусто
, вот код хранилища vuex:

 GetPermission(context){
            axios.defaults.headers.common['Authorization']='Bearer '   context.state.token
            axios.get('http://127.0.0.1:8000/api/user').then((response)=>{
                console.log(response)
                context.commit('Permissions',response.data.permission)
            })
//mutation:
Permissions(state,payload){
            state.permissions=payload
        }
//state
state:{
        error:'',
        token:localStorage.getItem('token') || null,
        permissions:'',
        success:'',
        isLoggedin:'',
        LoggedUser:{}
    }
 

помогите мне решить эту проблему, пожалуйста??

Комментарии:

1. я смог решить это, просто используя return в vuex action таким образом GetPermission(context){ axios.defaults.headers.common['Authorization']='Bearer ' context.state.token return axios.get('http://127.0.0.1:8000/api/user').then((response)=>{ console.log(response) context.commit('Permissions',response.data.permission) }) } , но теперь я получаю много ошибок запроса, что там не так?

Ответ №1:

действия в Vuex являются асинхронными. Единственный способ сообщить вызывающей функции (инициатору действия), что действие завершено, — это вернуть обещание и разрешить его позже.

Вот пример: MyAction возвращает обещание, выполняет http-вызов и разрешает или отклоняет обещание позже — все асинхронно

 actions: {
myAction(context, data) {
    return new Promise((resolve, reject) => {
        // Do something here... lets say, a http call using vue-resource
        this.$http("/api/something").then(response => {
            // http success, call the mutator and change something in state
            resolve(response);  // Let the calling function know that http is done. You may send some data back
        }, error => {
            // http failed, let the calling function know that action did not work out
            reject(error);
        })
    })
}
 

}

Теперь, когда ваш компонент Vue инициирует MyAction, он получит этот объект Promise и сможет узнать, удалось ли это или нет. Вот несколько примеров кода для компонента Vue:

 export default {
mounted: function() {
    // This component just got created. Lets fetch some data here using an action
    this.$store.dispatch("myAction").then(response => {
        console.log("Got some data, now lets show something in this component")
    }, error => {
        console.error("Got nothing from server. Prompt user to check internet connection and try again")
    })
}
 

}

Кроме того, вы вызываете тот же маршрут, когда разрешение не совпадает, в этом случае он всегда вызывает ваш тот же маршрут и создает бесконечный цикл. Перенаправление на страницу, доступ к которой запрещен, если в разрешении отказано.