Javascript NuxtJS/Vuex | nuxtServerInit和fetchData操作未填充用户打开状态

Javascript NuxtJS/Vuex | nuxtServerInit和fetchData操作未填充用户打开状态,javascript,node.js,vue.js,vuex,nuxt.js,Javascript,Node.js,Vue.js,Vuex,Nuxt.js,使用NodeJS、Express和MongoDB构建API,使用JWT和Cookies进行用户身份验证。 使用store(vuex)通过axios服务从API获取用户数据。在存储文件夹中创建auth.js,创建从后端获取数据的fetchData操作(axios.get(apiRoute))并将用户设置为状态。 想要使用nuxtServerInit实现这一点,所以我在store文件夹中创建了index.js文件。添加了空状态和操作。操作包含nuxtServerInit,它使用dispatch()调

使用NodeJS、Express和MongoDB构建API,使用JWT和Cookies进行用户身份验证。 使用store(vuex)通过axios服务从API获取用户数据。在存储文件夹中创建auth.js,创建从后端获取数据的fetchData操作(axios.get(apiRoute))并将用户设置为状态。 想要使用nuxtServerInit实现这一点,所以我在store文件夹中创建了index.js文件。添加了空状态和操作。操作包含nuxtServerInit,它使用dispatch()调用auth.js中的fetchData方法

然而,在所有这些之后,它根本不起作用。例如:用户已登录,但帐户页未呈现用户数据(姓名、电子邮件、图像等)

我尝试在auth.js中从fetchData操作返回一个承诺,但没有成功。 此外,我还尝试在index.js文件的insite中设置fetchData操作,并直接对其调用dispatch

store/auth.js

// Importing Files
import axios from 'axios';

// State
export const state = () => ({
    user: null
});

// Mutations
export const mutations = {
    SET_USER (store, data) {
        store.user = data
    },
    RESET_USER (store) {
        store.user = null
    }
};

// Actions
export const actions = {
    // Fetch User Account
    async fetchData ({ commit }) {
        try {
           const response = await axios.get('http://localhost:3000/api/v1/users/account');
            commit('SET_USER', response.data.doc);
            return response;
        } catch (err) {
            commit('RESET_USER');
        }
    }
};
// State
export const state = () => ({

});

// Actions
export const actions = {
    async nuxtServerInit({ dispatch }) {
        console.log('Testing');
        const res = dispatch('auth/fetchData');
        return res;
    }
};
store/index.js

// Importing Files
import axios from 'axios';

// State
export const state = () => ({
    user: null
});

// Mutations
export const mutations = {
    SET_USER (store, data) {
        store.user = data
    },
    RESET_USER (store) {
        store.user = null
    }
};

// Actions
export const actions = {
    // Fetch User Account
    async fetchData ({ commit }) {
        try {
           const response = await axios.get('http://localhost:3000/api/v1/users/account');
            commit('SET_USER', response.data.doc);
            return response;
        } catch (err) {
            commit('RESET_USER');
        }
    }
};
// State
export const state = () => ({

});

// Actions
export const actions = {
    async nuxtServerInit({ dispatch }) {
        console.log('Testing');
        const res = dispatch('auth/fetchData');
        return res;
    }
};
组件/设置.vue

<template>
  <section class="data-block-wrap" v-if="user">
     <BlockHeader :blockHeaderName="`Welcome Back, ${user.name.split(' ')[0]}`" btnText="More Details" />
     <img :src="getPhotoUrl(user.photo)" alt="User Photo" class="user-data__image">
     <p class="user-data__short-bio">{{ user.shortBio }}</p>
  </section>
</template>

<script>
 export default {
    // Computed
    computed: {
        user() {
            return this.$store.state.auth.user;
        }
    }
    ...
 };
</script>
<template>
  <div class="container">
    <TopNav />
    <SideNav />
    <nuxt />
  </div>
</template>

// Importing Components
import TopNav from '@/components/navigation/TopNav';
import SideNav from '@/components/navigation/SideNav';
import axios from 'axios';

import { mapActions } from 'vuex';

export default {
  components: {
    TopNav,
    SideNav
  },
  methods: {
  // Map Actions
  ...mapActions('auth', ['fetchData']),
    async checkUser() {
      const user = await this.fetchData();
    },
  },
   // Lifecycle Method - Created
   created() {
    this.checkUser();
  }
}
</script>

{{user.shortBio}

导出默认值{ //计算 计算:{ 用户(){ 返回此。$store.state.auth.user; } } ... };
我希望在Vue组件上正确呈现用户数据,但目前它根本不起作用。渲染是静态的,没有显示来自数据库/api的数据

编辑/更新

在default.vue文件(“所有组件的父”文件)中调用created()hook上的fetchData时,应用程序正确呈现用户数据

default.vue

<template>
  <section class="data-block-wrap" v-if="user">
     <BlockHeader :blockHeaderName="`Welcome Back, ${user.name.split(' ')[0]}`" btnText="More Details" />
     <img :src="getPhotoUrl(user.photo)" alt="User Photo" class="user-data__image">
     <p class="user-data__short-bio">{{ user.shortBio }}</p>
  </section>
</template>

<script>
 export default {
    // Computed
    computed: {
        user() {
            return this.$store.state.auth.user;
        }
    }
    ...
 };
</script>
<template>
  <div class="container">
    <TopNav />
    <SideNav />
    <nuxt />
  </div>
</template>

// Importing Components
import TopNav from '@/components/navigation/TopNav';
import SideNav from '@/components/navigation/SideNav';
import axios from 'axios';

import { mapActions } from 'vuex';

export default {
  components: {
    TopNav,
    SideNav
  },
  methods: {
  // Map Actions
  ...mapActions('auth', ['fetchData']),
    async checkUser() {
      const user = await this.fetchData();
    },
  },
   // Lifecycle Method - Created
   created() {
    this.checkUser();
  }
}
</script>

//导入组件
从“@/components/navigation/TopNav”导入TopNav;
从“@/components/navigation/SideNav”导入SideNav;
从“axios”导入axios;
从“vuex”导入{mapActions};
导出默认值{
组成部分:{
TopNav,
侧导航
},
方法:{
//映射动作
…映射操作('auth',['fetchData']),
异步checkUser(){
const user=wait this.fetchData();
},
},
//生命周期方法-已创建
创建(){
this.checkUser();
}
}

这里似乎发生了一些非常有趣的事情。问题是调用
axios.get('http://localhost:3000/api/v1/users/account)
从nuxtServerInit()中

这导致了本质上的无限递归。nuxtServerInit调用
http://localhost:3000
,它命中同一台服务器,再次运行nuxtServerInit,并调用
http://localhost:3000
,依此类推,直到javascript堆内存不足

为此,请使用以下方法,而不是使用nuxtServerInit:

fetch方法用于在呈现页面之前填充存储, 它与asyncData方法类似,只是它不设置组件 数据

注意:您无权访问fetch中的Nuxt组件,因此必须使用该对象而不是“this”

一般来说:

  • 使用fetch填充服务器或客户端上的存储数据
  • 使用asyncData填充服务器或客户端上的组件数据
  • 使用nuxtServerInit可以在请求对象上设置具有值的存储,如会话、头、cookie等,这是服务器端所必需的
这个问题的解决方案是在store.js中以这种方式使用NuxtServerInt操作
1.您需要运行npm安装cookieparser和npm安装js cookie
const cookieparser=process.server?require('cookieparser'):未定义
导出常量状态=()=>{
返回{
auth:null,
}
}
导出常量突变={
设置身份验证(状态,身份验证){
state.auth=auth
},
}
导出常量操作={
nuxtServerInit({commit},{req}){
设auth=null
if(请求头文件cookie){
试一试{
const parsed=cookieparser.parse(req.headers.cookie)
auth=parsed.auth
}捕捉(错误){
console.log('error',err)
}
}
提交('SET_AUTH',AUTH)
},
}
然后在登录页面组件中,调用后端API,如下所示
从“@/ApiServices/AuthServices.js”导入AuthServices
从“sweetalert”导入swal
const Cookie=process.client?require('js-cookie'):未定义
异步onSubmit(){
试一试{
常数体={
电子邮件:this.email,
密码:this.password,
}
const res=await AuthServices.loginUrl(正文)
console.log('res',res)
console.log('res',res.data.message)
设置超时(()=>{
//我们模拟了带有超时的异步请求。
常数auth={
accessToken:res.data.payload.token,//从api调用中,您可以获得用户令牌
userData:res.data.payload.user,
}
swal('Logged in'、`${res.data.message}`、'success')
this.email=this.password=''
这是。$refs.loginForm.reset()
此.$store.commit('setAuth',auth)//为客户端呈现而变异为存储
set('auth',auth)//在Cookie中保存令牌以用于服务器呈现
这是。$router.push(“/”)
}, 1000)
}捕获(错误){
console.log('error',error)
swal('Error!'、`${Error.message}`、'Error')
}
},
您的AuthServices.js如下所示
从“axios”导入axios
const apiClient=axios.create({
基本URL:`http://localhost:3000`,
})
导出默认值{
罗吉努尔(身体){
返回apiClient.post('/login',body{
标题:{
“内容类型”:“应用程序/json”,
},
})
}
}
然后,您可以使用导航栏中的computed(计算)或dashboard(仪表板)获取用户数据,例如说Hi,Xavier
在您想要放置用户数据的内部,只需添加以下内容
你好,{{user.firstnam}

导出默认值{ //计算