从Vuex操作和组件更改路由

时间:2017-06-28 11:37:27

标签: vuejs2 vue-router vuex

用户通过登录表单成功登录我的应用程序后。我想检查一下他们是否有个人资料。如果他们我想将他们发送到新闻页面。如果他们有一套,我希望它将它们重定向到“设置”页面。我如何使用Vuex做到这一点?

我想有几个选择:

1。负责重定向的组件? (感觉不对)

Login.vue

handleFormSubmit () {
this.$store.dispatch('loginFormSubmit', formData)
    .then(() => {
      // This feels a bit gross
      this.$store.dispatch('getUserProfile')
        .then(() => this.$router.push('/news'))
        .catch(() => this.$router.push('/settings'))
    })
    .catch(() => {
      this.loginError = true
    })
}

2。我会在行动中承担责任吗?

用户actions.js

export const getUserProfile = ({commit}) => {
  commit(types.USER_PROFILE_REQUEST)
  const options = {
    url: `${API_URL}/profile`,
    method: 'GET'
  }

  return request(options)
    .then((profileSettings) => {
      // Would I change the router to News here??

      commit(types.USER_PROFILE_SUCCESS, profileSettings)
      return Promise.resolve(profileSettings)
    })
    .catch((error) => {
      // Would I change the router to Settings here??

      commit(types.UI_MENU_HIDE)
      return Promise.reject(error)
    })
}

export const loginFormSubmit = ({dispatch, commit}, { email, password }) => {
  console.log(email, password)
  commit(types.USER_LOGIN_REQUEST)
  const options = {
    url: `${API_URL}/token`
  }
  return request(options)
    .then((response) => {
      dispatch('getUserProfile')
      commit(types.USER_LOGIN_SUCCESS, response.token)
      return Promise.resolve(response.token)
    })
    .catch((error) => {
      commit(types.USER_LOGIN_FAILURE, error)
      return Promise.reject(error)
    })
}

3。也许它应该与守卫一起保存在路由器中?

Login.vue

handleFormSubmit () {
this.$store.dispatch('loginFormSubmit', formData)
    .then(() => this.$router.push('/news'))
    .catch(() => {
      this.loginError = true
    })
}

然后在我的路由器中:

const routes = [
      {
        path: 'news',
        alias: '',
        component: NewsView,
        name: 'News',
        meta: { description: 'News feed page' },
        beforeEnter: (to, from, next) => {
          store.dispatch('getUserProfile')
-          .then((resp) => {
-            // Profile set
-            next()
-          })
-          .catch(() => {
-            // No profile set
-            next({ name: 'settings' })
-          })
        }
      },
]

4。聆听商店变更,然后改变路线

  computed: {
    isAuthenticated () {
      return this.$store.getters.isAuthenticated
    }
  },

  watch: {
    isAuthenticated () {
      this.$router.push('/calendar')
    }
  },
  methods: {
    handleSubmit (formData) {
      // Updates isAuthenticated on success
      this.$store.dispatch('requestAuthToken', formData)
    }
  }

也许三号或四号最好?感觉最干净,但很想知道你们的想法:D

感谢您提前抽出时间!

2 个答案:

答案 0 :(得分:0)

我认为您想要版本2的想法。为什么不这样:

  1. 您在handleFormSubmit()中呼叫Login.vue,这将调度loginFormSubmit()的动作。也许此时可以在Login.vue中为UX启用加载状态。
  2. 如果用户可以登录,请致电getUserProfile(),否则在Login.vue中显示错误
  3. getUserProfile()从API获取
  4. 您可以在操作内通过API测试response,也可以将response传递给一个单独的突变来实现此目的。
  5. 如果用户拥有个人资料数据,请更新staterouter.push('/pathToNews'),否则更新router.push('/pathToSettings')

以下是简化的伪代码来说明概念:

// store

  state: {
    userProfile: {}
  },

  mutations: {
    setUserProfile (state, payload) {
      state.userProfile = payload
    }
  },

  actions: {
    getUserProfile() {
      let self = this
      axios.get('${API_URL}/token')
      .then(function (response) {
        // test response against what is expected for a populated profile
        if (response.data is a populated user profile) {
          self.commit('setUserProfile', response.data)
          self.router.push('/news')
        } else {
          self.router.push('/settings')
        }
      })
      .catch(function (error) {
        console.error(error);
        // handle your error
      })
      .finally(function () {
        // always executed
      })
    }
  }

答案 1 :(得分:-1)

我的流程:

  1. 组件 (this.$store.dispatch('getProfile'...)
  2. 操作-服务器(const response = await fetch ...) 对突变做出反应
  3. 变异将信息保存到商店
  4. 商店(唯一包含所有信息的地方)
  5. 组件(从this。$ store.state.user.hasProfile中获取数据并做出决定)

摘要:您发送请求{登录名,密码},然后收到来自服务器的响应,例如     {hasProfile:是/否}

    if(hasProfile) {
      // router to
    } else  {
      // router to
    }