在渲染中间件之前如何在nuxt中渲染vuex模块
How do I render the vuex module in nuxt before rendering the middleware
我的问题是,当页面重新加载时,先渲染中间件,再渲染vuex;所以,当我想根据用户是否通过身份验证来更改 vuex 中的值时,中间件 returns 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。它指出
A middleware can be asynchronous. To do this, simply return a Promise or use the 2nd callback argument.
所以在你的情况下,你需要在你的中间件中 return 一个承诺:这个承诺将是 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
:您应该只在此函数中获取 axios 查询,而不是重定向。
此外,操作、密码和用户中使用的数据也会有问题。刷新时,您会丢失此数据。您应该实现一个令牌系统,如 JWT,并将它们存储在本地存储或 cookie 中(如本例 https://nuxtjs.org/examples/auth-external-jwt/)。
希望对你有帮助!
我的问题是,当页面重新加载时,先渲染中间件,再渲染vuex;所以,当我想根据用户是否通过身份验证来更改 vuex 中的值时,中间件 returns 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。它指出
A middleware can be asynchronous. To do this, simply return a Promise or use the 2nd callback argument.
所以在你的情况下,你需要在你的中间件中 return 一个承诺:这个承诺将是 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
:您应该只在此函数中获取 axios 查询,而不是重定向。
此外,操作、密码和用户中使用的数据也会有问题。刷新时,您会丢失此数据。您应该实现一个令牌系统,如 JWT,并将它们存储在本地存储或 cookie 中(如本例 https://nuxtjs.org/examples/auth-external-jwt/)。
希望对你有帮助!