Nuxt3 基于H3做后台接口

2023-11-24 10:04:06 浏览数 (1)

Nuxt3实现接口

Nuxt3 是使用node做ssr页面渲染的, 自带了H3 可以对接口进行处理。

Nuxt3 自动扫描 ~/server/api,~/server/routes,~/server/middleware目录中的文件,进行注册对应的接口

目录结构

即目录结构为↓,访问/api/login 就是接口的返回内容

这里需要注意,如果我们即使用代理,又要使用nuxt3来写接口的话,在代理时不可以使用api作为代理名称,否则访问就会被代理到对应地址。

代码语言:txt复制
|-- server
    |-- api //默认名称不可以更改
        |-- login.post.ts //文件名称后面的post和get 代表了接收什么类型的请求
        |-- userInfo.get.ts // 这里代表了是get请求
        |-- detail
            |--[id].get.ts  //以动态路由 的传参方式介绍参数

userInfo.get.ts

代码语言:txt复制
// 固定返回一个defineEventHandler方法
export default defineEventHandler(event => {
    // 接受的event 包含了node 的req 和res方法
  const query = getQuery(event) // getQuery是全局的方法,可以直接调用
  const { id } = query
  return {
    msg: `请求的是 ${id}的个人信息`
  }
})

这时在运行起来的项目 直接打开 http://localhost:3000/api/userInfo?id=23页面内容就是

代码语言:txt复制
{
    msg: `请求的是 23的个人信息`
}

login.post.ts

代码语言:txt复制
// 固定返回一个defineEventHandler方法
export default defineEventHandler(async event => {
  const body = await readBody(event) //readBody是全局封装好的获取body的方法
  const { username, password } = body
  //判断传递参数 数据为空报错
  if (!username || !password) {
    // createError可以直接抛出错误
    throw createError({
      statusCode: 400,
      statusMessage: '用户名密码不可以为空'
    })
  }
  //数据库操作
  return {
    mes: `已将${username}的数据存储成功,登录成功`
  }
})

page/login.vue

这里在同一个项目写的登录页面来验证一些 这个请求功能

(项目中已经在plugin中注册了elementplus)可以直接使用。

代码语言:txt复制
<template>
  <div class="mod-login">
    <el-form
      ref="ruleFormRef"
      :model="ruleForm"
      :rules="rules"
      label-width="120px"
      class="demo-ruleForm"
      :size="formSize"
      status-icon
    >
      <el-form-item label="User Name" prop="name">
        <el-input v-model="ruleForm.name" placeholder="Please User Name" />
      </el-form-item>
      <el-form-item label="Password" prop="name">
        <el-input
          v-model="ruleForm.password"
          type="password"
          placeholder="Please input password"
          show-password
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm(ruleFormRef)"> Create </el-button>
        <el-button @click="resetForm(ruleFormRef)">Reset</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'

interface RuleForm {
  name: string
  password: string
}

const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<RuleForm>({
  name: '',
  password: ''
})

const rules = reactive<FormRules<RuleForm>>({
  name: [
    { required: true, message: 'Please input username', trigger: 'blur' },
    { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' }
  ],
  password: [
    { required: true, message: 'Please input password', trigger: 'blur' },
    { min: 8, max: 15, message: 'Length should be 8 to 15', trigger: 'blur' }
  ]
})

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      const { data } = await useLazyFetch('/api/login', {
        method: 'post',
        body: JSON.stringify({
          //post请求参数
          username: ruleForm.name,
          password: ruleForm.password
        })
      })
    } else {
      console.log('error submit!', fields)
    }
  })
}

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}
</script>

<style lang="scss">
.mod-login {
  padding: 300px;
}
</style>

这里打印出的返回内容就是接口请求回来的内容。

代码语言:txt复制
{
    "__v_isShallow": false,
    "__v_isRef": true,
    "_rawValue": {
        "mes": "已将sejas的数据存储成功,登录成功"
    },
    "_value": {
        "mes": "已将sejas的数据存储成功,登录成功"
    }
}

[id].get.js

这里 如果我们请求需要为 http://localhost:3000/api/detail/8788

代码语言:txt复制
export default defineEventHandler(event => {
  // 这里通过 event.context.params.id来获取到id 的值
  const id = event.context.params?.id
  return {
    msg: `请求的是 ${id}的详情信息`
  }
})

node出了可以直接链接数据库做后台接口,还可以使用node作为中间层,在服务端请求别的接口,处理数据后返回给页面

在服务端发起请求使用的是$fetch而不是useLazyFetch

代码语言:txt复制
// 固定的导出一个defineEventHandle方法

export default defineEventHandler(async event => {
  // 这里通过 event.context.params.id来获取到id 的值
  const id = event.context.params?.id
  // 我这这里调用了 刚刚写的userInfo 接口,这时返回的内容就是 
  //  msg: `请求的是 23的个人信息`
  // 可以使用 parseCookies直接获取到客户端的cookie
  const cookie = parseCookies(event)
  const res = await $fetch(`/api/userInfo?id=${id}`)
  return res
})

服务端获取参数方法(全部是nuxt封装好了的) 在 defineEventHandler 的方法中使用

此中event 是defineEventHandler的参数

名称

作用

getQuery(event)

get 方法接受query参数

readBody(event)

post方法获取请求参数body

const id = event.context.params?.id

获取动态路传递的param参数,id与文件名称对应

parseCookies(event)

服务端获取cookie

0 人点赞