为Nuxt.js编写客户端API库

dev*_*ius 6 server-side-rendering axios nuxt.js

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

我正在编写一个由外部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)
  }
}
Run Code Online (Sandbox Code Playgroud)

这适用于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>
Run Code Online (Sandbox Code Playgroud)

现在,一旦渲染并发送到浏览器,下面可能会有一个表格被反应.当用户提交该表单以更新其配置文件时,我突然无法访问该UserService实例.

这是因为它在asyncData调用中定义,只能在SSR上下文中使用.

我通过api从asyncData方法返回来修复此问题,user然后将Nuxt放到vue实例上.但是,这感觉非常错误.这是正确的方法吗?你怎么这么做的?或者不是吗?

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

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

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

谢谢!

dev*_*ius 7

我花了一些时间在这上面,并提出了一个解决方案.

我已经创建了一个插件来处理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)
}
Run Code Online (Sandbox Code Playgroud)
// 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',
  ]
}
Run Code Online (Sandbox Code Playgroud)

现在我的页面更干净了:

<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>
Run Code Online (Sandbox Code Playgroud)

我没有从中获得任何代码味道,但如果有一个Nuxt向导阅读并发现某些内容,请告诉我!