簡體   English   中英

在渲染中間件之前如何在nuxt中渲染vuex模塊

[英]How do I render the vuex module in nuxt before rendering the middleware

我的問題是,當頁面重新加載時,中間件首先呈現,然后是 vuex; 因此,當我想更改 vuex 中的值時,基於用戶是否經過身份驗證,中間件返回 vuex 的初始值。 這意味着,如果用戶通過身份驗證,它首先顯示 false,在渲染 vuex 之后,它再顯示 true。 但是到那時,中間件已經完成加載。 這會導致在頁面刷新時將用戶重定向到登錄頁面。 我的問題是,它們是我可以在中間件之前先加載 vuex 的一種方式嗎?

這是中間件代碼;

export default async function ({ store, redirect }) {
  // If the user is not authenticated
  const authenticated = await store.state.signup.authenticated
  if (!authenticated) {
    console.log(!authenticated)
    return redirect('/login')
  } else {
    console.log('I am logged in')
  }
}

這是vuex代碼;

import axios from 'axios'

export const state = () => ({
  authenticated: false,
  credential: null,
})

export const mutations = {
  ADD_USER(state, data) {
    state.credential = data
    state.authenticated = true
  },
  LOGOUT(state) {
    state.credential = null
    state.authenticated = false
  },
}

export const actions = {
  async addUser({ commit }, data) {
    try {
      const response = await axios.post(
        'http://localhost:8000/api/rest-auth/registration/',
        data
      )
      commit('ADD_USER', response.data)
      this.$router.push('/')
    } catch (error) {
      return console.log(error)
    }
  },

  async addUserLogin({ commit }, data) {
    try {
      const response = await axios.post(
        'http://localhost:8000/api/rest-auth/login/',
        data
      )
      commit('ADD_USER', response.data)
      this.$router.push('/')
    } catch (error) {
      return console.log(error)
    }
  },
}

export const getters = {
  loggedIn(state) {
    return !!state.credential
  },
}

這是 login.vue 代碼

<template>
  <client-only>
    <div class="container">
      <v-card max-width="500" class="margin-auto">
        <v-card-title>Sign up</v-card-title>
        <v-card-text>
          <v-form @submit.prevent="submitUser">
            <v-text-field
              v-model="data.username"
              label="Username"
              hide-details="auto"
              append-icon="account_circle"
            ></v-text-field>
            <v-text-field
              v-model="data.password"
              label="Password"
              hide-details="auto"
              type="password"
              append-icon="visibility_off"
            ></v-text-field>
            <v-card-actions>
              <v-btn color="success" type="submit" class="mt-4" dark>
                Signup
              </v-btn>
            </v-card-actions>
          </v-form>
          <p>
            Don't have an account? <nuxt-link to="/signup">Register</nuxt-link>
          </p>
        </v-card-text>
      </v-card>
    </div>
  </client-only>
</template>

<script>
export default {
  data() {
    return {
      data: {
        username: '',
        password: '',
      },
    }
  },

  methods: {
    submitUser() {
      this.$store.dispatch('signup/addUserLogin', this.data)
    },
  },
}
</script>

<style lang="scss" scoped>
.margin-auto {
  margin: 2rem auto;
}
</style>

是的,有一種方法可以做到這一點,事實上。 該商店已經在您的中間件中可用,但在您的情況下。 商店是空的! 您需要先獲取數據並填充存儲。

我建議你閱讀關於 nuxt 中間件https://nuxtjs.org/guide/routing#middleware的文檔。 它指出

中間件可以是異步的。 為此,只需返回 Promise 或使用第二個回調參數。

因此,在您的情況下,您需要在中間件中返回 Promise:此 promise 將是 axios 請求。 這是一個提議:

export default function ({ store, redirect }) {
    return new Promise(resolve => store.dispatch('signup/addUserLogin', data).then((user) => {
        if (!user) {
            // User not found
            redirect('/login');
        } else {
            // Do your stuff with the user freshly got, like commit in the store
            resolve();
        }
    })
}

在您的情況下,您應該修改操作addUserLogin :您應該只在此 function 中獲得 axios 查詢,而不是重定向。 此外,您將遇到操作中使用的數據、密碼和用戶的問題。 刷新時,您會丟失此數據。 您應該實現一個令牌系統,如 JWT,並將它們存儲在本地存儲或 cookies 中(如本例中的https://nuxtjjs.org/external )。

希望對你有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM