为 Nuxt.js 编写客户端 API 库

Posted

技术标签:

【中文标题】为 Nuxt.js 编写客户端 API 库【英文标题】:Writing client-side API libraries for Nuxt.js 【发布时间】:2018-07-25 19:44:31 【问题描述】:

这更像是一个架构/设计问题,而不是“为什么这不起作用”。

我正在编写一个由外部 API (ExpressJS) 提供支持的 Nuxt.js s-s-r Web 应用程序。 API 负责身份验证(通过nuxt-auth - JWT)和检索用户数据等。据我了解,s-s-r 代码在客户端上设置了一个 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)
  

这对 s-s-r 非常有效,因为我可以在我的 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 调用中定义的,只能在 s-s-r 上下文中使用。

我通过从 asyncData 方法返回 api 以及 user 来解决此问题,然后 Nuxt 将其放入 vue 实例。然而,这感觉非常错误。这是正确的方法吗?你应该怎么做?你不是吗?

这感觉特别糟糕,因为 Vue 会监视 data 中的所有内容,而我真的不需要它来跟踪 api 实例...

我对 Vue 和 Nuxt 还很陌生,所以如果我忽略了一些事情,请说,但我的问题是:

我应该如何设计它以在 s-s-r 上下文和浏览器中都工作?

谢谢!

【问题讨论】:

【参考方案1】:

我在这方面花了更多时间并想出了一个解决方案。

我创建了一个插件来处理 api 对象的构造,然后将其添加到 Nuxt 上下文中,该上下文可供 s-s-r 代码和浏览器使用:

// 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 向导阅读此内容并发现了什么,请告诉我!

【讨论】:

用户类的最后一种形式是什么?我不清楚您如何将 axios 实例注入 Users 类? @WebMan 我的 ApiService 构造函数将 axios 注入所有其他类并将它们设置为自身的属性。希望这是有道理的

以上是关于为 Nuxt.js 编写客户端 API 库的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 和 Nuxt.js

如何在 Vue.js/Nuxt.js 中为 RepositoryFactory 编写测试

如何在nuxt中获取axios baseUrl?

在 Nuxt JS 中为 Axios 配置本地 php 端点

Nuxt.js - 如何将图像上传到 cloudinary?

Nuxt.js 错误:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配