Vue路由器和vuex基于值重定向的问题

Posted

技术标签:

【中文标题】Vue路由器和vuex基于值重定向的问题【英文标题】:Vue router and vuex issue with redirecting based on a value 【发布时间】:2020-04-25 12:40:58 【问题描述】:

我有一个 Vue 应用程序,我试图让它在用户没有付款并且试用期结束时被重定向到 /billing 并显示一条错误消息。我也希望这样,如果他们已经付款或仍处于试用期,他们就可以使用该应用程序。

我的 store.js 中的 storeUser 代码

storeUser(state, user) 
      state.user = user
      state.isPaid = user.isPaid
      state.isTrial = user.isTrial
 ,

作为“用户”传入 storeUser 的数据


  name: "Joe",
  isPaid: false,
  isTrial: false


使用 chrome vui 扩展在我的 vuex 商店中显示的数据


  name: "Joe",
  isPaid: null,
  isTrial: null

不知道为什么数据输入错误,因为我可以在 storeUser 函数中控制台记录正确的数据。但是,如果我查看用户部分,我可以将其视为正确的错误值。当我尝试在下面的代码中为 vue 路由器指定它时,它说无法读取它,因为它是空的。我认为这只是一个异步问题。

store.js 中的状态

state: 
    token: null,
    isPaid: null, 
    isTrial: null,
    error: 
      registerErrorMessage: '',
      loginErrorMessage: '',
      resetError: ''
    ,
    user: null
  

main.js 包含我的 vue 路由器

 else if(to.path != '/billing' && !(store.state.isPaid && store.state.isTrial)) 
    next(
      path: '/billings',
      query: 
         paid: false,
      
  )

任何人都可以发现潜在问题或解决我的问题的方法吗?此代码应该足以重现该问题,但如果缺少我可以提供更多,没有公共 repo 可以显示其余代码。

编辑** 所以发生了一些奇怪的事情。我现在看到的数据比以前更正确(isPaid 和 isTrial 是有效的)但是我现在仍然无法去其他路线。 在我的 beforeEach 开头添加 store.state 的输出


  token: 'random string',
  isPaid: true,
  isTrial: false,
  error: ,
  user: 
    name: "Joe",
    isPaid: true,
    isTrial: false
  


编辑 2**

storeUser(commit, state) 
      if(!state.token) return
      axios.get('/user/userInfo')
        .then(res => 
          if(res.data.success) 
            commit('storeUser', 
              name: res.data.user.name,
              isPaid: res.data.user.company.stripe.isPaid,
              isTrial: res.data.user.company.stripe.isTrial
            )
          
        )
        .catch(err => 
          console.log(err)
        )
    ,

编辑 3** 这是我来自 main.js 的整个 vue 路线

router.beforeEach((to, from, next) => 
  store.dispatch('tryAutoLogin')
  console.log(store.state) // this is test only not for prod
  if(!store.state.token && (to.path == '/login' 
    || to.path == '/signup' 
    || to.path == '/forgot' 
    || to.path == '/resend' 
    || to.path.includes('/confirmation/'))) 
  
    return next()
   else if (to.path == '/signup') 
    return next( query: plan: from.query.plan )
   else if(to.path != '/billing' && !(store.state.isPaid && store.state.isTrial)) 
    next(
      path: '/billing',
      query: 
         paid: false,
      
  )
   else if(store.state.token) 
    return next()
   else 
    return next('/login')
  
)

您可以看到我进行了自动登录,它只是检查令牌是否存在。与问题无关。

编辑 4**

我有一个想法,但不确定如何实现它。使用 Promise 确保数据正确。我对承诺部分的困惑是让他们一起工作。所以我认为authUser 突变然后以某种方式使storeUser 行动成为我可以在我的 beforeEach 中解决的承诺

动作

tryAutoLogin(commit, dispatch) 
   const token = localStorage.getItem('token')
   if(!token) return
   commit('authUser',
     token
   )
   dispatch('storeUser')
,


storeUser(commit, state) 
      if(!state.token) return
      axios.get('/user/userInfo')
        .then(res => 
          if(res.data.success) 
            commit('storeUser', 
              name: res.data.user.name,
              companyName: res.data.user.company.companyName,
              role: res.data.user.role,
              isPaid: res.data.user.company.stripe.isPaid,
              isTrial: res.data.user.company.stripe.isTrial
            )
          
        )
        .catch(err => 
          console.log(err)
        )
    ,


突变

authUser(state, userData) 
  state.token = userData.token
,
storeUser(state, user) 
  state.user = user
  state.isPaid = user.isPaid
  state.isTrial = user.isTrial
,

【问题讨论】:

这个错误具体指的是什么?是说无法读取 store.state.x 吗? 如果你正在使用,你能发布突变和动作的结构吗? @AlexanderStaroselsky 这只是说它无法读取 store.state.user 说它是 null 由我正在使用的 chrome 扩展支持 好的,您可以从您正在执行路由逻辑的地方控制台日志存储并在您的问题中分享吗?听起来 store 甚至没有 state 属性,所以我很想知道 store 中实际有什么,以及它是如何被导入/定义的。 @JesusGalvan 不确定您的意思?我正在使用大量数据,但只有我提供的数据真正涉及到我正在尝试使用的数据。 【参考方案1】:

看起来你有很多重复和混乱的代码。

为什么状态中有isPaidisTrial中的2个?

您也没有使用您提供给commit 函数的name 属性。

提交

commit('storeUser', 
    name: res.data.user.name,
    isPaid: res.data.user.company.stripe.isPaid,
    isTrial: res.data.user.company.stripe.isTrial
);
const store = new Vuex.Store(
    state: 
        userName: '',
        isPaid: false,
        isTrial: false,
    ,
    mutations: 
        storeUser(state, data) 
            state.userName = data.name;
            state.isPaid = data.isPaid;
            state.isTrial = data.isTrial;
        ,
    ,
);

现在您可以访问状态 store.state.isPaidstore.state.isTrial

您可以在jsfiddle 看到一个工作示例。如果您打开控制台,您可以看到当前状态是如何记录的。

【讨论】:

重复 isPaid/isTrial 的原因是我看看它是否对用户 state.user 有影响。我可以删除第一个但不能在用户下删除,因为这是输入数据的方式。我了解访问商店的前提,我认为拥有此副本不会导致我遇到的问题。至于使用名称与用户名,这只是我当时选择的,所以我没有理由改变它,因为那部分工作正常。似乎不起作用的是与状态相关的路由器内容。问题可能出在我的代码的 beforeEach 部分 @joshk132 你可以在jsfiddle看到一个工作示例 这似乎并没有解决作为本文重点的 beforeEach 问题。我看到它显示了值的变化,我有时会得到 - 奇怪的是相同的代码可以工作 1/2 次 - 但是路由器问题仍然存在。 @joshk132 状态可能还不可用(取决于您如何设置初始状态)。这可能是在状态加载之前完成检查的竞争条件。您可以延迟一切,直到您加载了初始状态。有点像旋转装载机。没有实际代码很难说。用你的实际行为创建一个 jsfiddle,我可以看看。 我做了一些 console.log 语句,看起来 beforeEach 有点奇怪(也许不是,只是异步弄乱了东西),所以如果在 beforeEach 的顶部,我放置一个console.log它显示状态但是如果我将isPaid和isTrial的console.log放在else中,如果我评估它们,我会得到null这两个值。至于创建一个 jsfiddle,如果不公开我的 API,我认为我无法做到这一点

以上是关于Vue路由器和vuex基于值重定向的问题的主要内容,如果未能解决你的问题,请参考以下文章

Vue + VueX + Typescript + Vue 路由器。组件未销毁

使用 vuex 和 vue 路由器的实例上未定义属性或方法“X”

在 Vue 路由解析之前访问 Vuex

Vue路由器条件重定向?

vue用了vuex和路由的缓存,出问题了一个页面添加按钮进去后一直都有上一次添加的数据参数在上面如何修改?

如果用户未在 vuex 中登录,如何使路由重定向到登录