这更多的是一个架构/设计问题,而不是"为什么这不起作用"。
我正在编写一个由外部API(ExpressJS)驱动的Nuxt.js SSR Web应用程序。 API负责身份验证(通过nuxt-auth
- JWT)并检索用户数据等。据我所知,SSR代码在客户端设置cookie并使用它来检索JWT以便通过API进行身份验证服务器,代表浏览器。
我为数据库中的每个模型编写了一些帮助方法,如下所示(简化):
// services/UserService.js
export default class UserService {
constructor(ctx) {
this.$axios = ctx.$axios
}
getUsers () {
return this.$axios.get('/api/users')
}
createUser (params) {
return this.$axios.post('/api/users', params)
}
updateUser (params) {
return this.$axios.put('/api/users/' + params.id, params)
}
getUser (id) {
return this.$axios.get('/api/users/' + id)
}
}
这适用于SSR,因为我可以在我的Nuxt页面中执行此操作:
<template>{{user.display_name}}</template>
<script>
import UserService from '@/services/UserService'
export default {
asyncData ({ params, $axios }) {
const api = new ApiService({ $axios })
return api.Users.getUser(params).then(user => {
return { user, api } // this makes them available in the vue instance
})
}
}
</script>
现在,一旦渲染并发送到浏览器,下面可能会有一个表格被反应。当用户提交该表单以更新其个人资料时,我突然无法访问UserService
个实例。
这是因为它在asyncData
调用中定义,只能在SSR上下文中使用。
我通过从api
方法返回asyncData
以及user
来解决此问题,然后将Nuxt放入vue实例。但是,这感觉非常错误。这是正确的方法吗?你怎么这么做的?或者不是吗?
这感觉特别糟糕,因为Vue会在data
中观看所有内容,而我真的不需要它来跟踪api实例......
我对Vue和Nuxt很陌生,所以如果我忽略了一些事情请说,但我的问题是:
我应该如何将其设计为在SSR上下文和浏览器中工作?
谢谢!
答案 0 :(得分:5)
我花了一些时间在这上面并提出了一个解决方案。
我已经创建了一个插件来处理api
对象的构造,然后将其添加到Nuxt上下文中,该上下文可用于SSR代码和浏览器:
// plugins/api.js
import ApiService from '@/services/ApiService'
export default (ctx, inject) => {
const api = new ApiService({ $axios: ctx.app.$axios })
ctx.$api = api
inject('api', api)
}
// nuxt.config.js
module.exports = {
plugins: [
'~/plugins/global.js',
'~/plugins/datetimepicker.js',
'~/plugins/axios.js',
'~/plugins/api.js' // our plugin
],
modules: [
'bootstrap-vue/nuxt',
'@nuxtjs/axios',
'@nuxtjs/auth',
]
}
现在我的网页很多更清洁:
<template></template>
<script>
export default {
asyncData ({ params, $api }) {
return $api.Users.getUser(params).then(user => {
return { user }
})
}),
watch {
someValue (newVal) {
// run in the browser
this.$api.Users.doSomethingWith(val)
}
}
}
</script>
我没有从中获得任何代码味道,但如果有一个Nuxt向导阅读并发现了某些内容,请告诉我!