云计算百科
云计算领域专业知识百科平台

Nuxt.js 3【详解】服务器 Server

Nuxt.js 是一个全栈框架,可以在一个项目中,同时完成前端和后端的开发。

服务器架构

在这里插入图片描述 Nuxt.js 的服务端由 Nitro 实现,Nitro 由基于 H3 实现。

  • Nitro 官网 https://nitro.build/guide
  • H3 官网 https://h3.unjs.io/guide

接口路由

  • 基于文件目录自动生成
  • 方法名取自文件后缀名

server/api

根据文件目录自动生成带 /api 前缀的接口

api/
test.ts > /api/test
user/
// 动态接口,可得到接口参数 Param ,如 id 为 1
[id].ts > /api/user/1

// server/api/test.ts
export default defineEventHandler(() => {
return { hello: "你好" };
});

启动项目后,浏览器访问 http://localhost:3030/api/test

在这里插入图片描述

server/routes

根据文件目录自动生成无 /api 前缀的接口

routes/
hello.ts > GET /hello
hello.get.ts > GET /hello
hello.post.ts > POST /hello

参数解析

从网络请求的事件中,可以解析出必要的参数,内置的 API 如下:

export default defineEventHandler(event => {
// 获取接口中的参数,如 /api/user/1 中的 1
const id = getRouterParam(event, 'id')

// 获取接口的 URL ,如 http://localhost:3030/api/user/1
const url = getRequestURL(event)
const age = getRouterParam(event, 'age')

return `Hello ${name}! You are ${age} years old.`
})

getRouterParam

获取 get 请求中的接口参数

// 获取接口中的参数,如 /api/user/1 中的 1
const id = getRouterParam(event, 'id')

  • 参数1:网络请求事件 event
  • 参数2:请求参数的key
  • 返回值:参数的值

getQuery

获取 get 请求中的查询参数

const query = getQuery(event);

  • 参数:网络请求事件 event
  • 返回值:查询参数对象

如 http://localhost:3030/api/user/1?name=joy 会得到

{
"name": "joy"
}

readBody

获取 post 请求中的 body 信息

// routes/users.post.ts
export default defineEventHandler(async event => {
const body = await readBody(event)
})

getRequestURL

const urlObj = getRequestURL(event)

  • 参数为网络请求事件 event
  • 返回一个URL对象,通过其属性,可以获取到其他 URL 信息 以 ‘http://localhost:3030/api/user/1?name=joy’ 为例 {
    href: 'http://localhost:3030/api/user/1?name=joy',
    origin: 'http://localhost:3030',
    protocol: 'http:',
    username: '',
    password: '',
    host: 'localhost:3030',
    hostname: 'localhost',
    port: '3030',
    pathname: '/api/user/1',
    search: '?name=joy',
    searchParams: URLSearchParams { 'name' => 'joy' },
    hash: ''
    }

接口的配置

nitro.config.ts 中

export default defineNitroConfig({
routeRules: {
"/blog/**": { swr: true },
"/blog/api1": { swr: 600 },
"/blog/api2": { static: true },
"/blog/api3": {
cache: {
/* cache options*/
},
},
"/assets/**": { headers: { "cache-control": "s-maxage=0" } },
"/api/v1/**": {
cors: true,
headers: { "access-control-allow-methods": "GET" },
},
"/old-page": { redirect: "/new-page" },
"/old-page/**": { redirect: "/new-page/**" },
"/proxy/example": { proxy: "https://example.com" },
"/proxy/**": { proxy: "/api/**" },
},
});

内置存储 useStorage

通过 useStorage() 可获取到一个内置存储的实例,可在内存中存储和读取数据。(通过 unstorage 实现,官网为 https://unstorage.unjs.io/guide)

const currentUser = { name: body.name };
// 存数据 useStorage().setItem
await useStorage().setItem("user", currentUser);

// 取数据 useStorage().getItem
const user = await useStorage().getItem("user");
if (!user) {
throw createError({
statusCode: 401,
statusMessage: "未登录",
});
}

改用 redis

  • 本地安装 redis,见教程

  • 添加配置 nuxt.config.ts

    nitro: {
    storage: {
    redis: {
    driver: "redis",
    port: 6379,
    host: "127.0.0.1",
    password: "",
    db: 0, // Defaults to 0
    },
    },
    },

  • 存数据 useStorage 的参数 redis 与 nuxt.config.ts 中的配置 storage 属性 redis 对应

    await useStorage("redis").setItem(
    "currentUser",
    currentUser,
    // ttl 配置 redis的过期时间,单位s,此处为 10s 后过期
    { ttl: 10 }
    );

  • 取数据

    const isLogin = await useStorage("redis").hasItem("currentUser");
    if (!isLogin) {
    throw createError({
    statusCode: 401,
    statusMessage: "未登录",
    });
    }

  • 中间件 server/middleware

    server/middleware 目录中的文件为服务器的中间件,在请求接口前,都会依次执行!

    默认执行顺序为按文件名排序。

    可通过添加数字前缀,自定义执行顺序。

    在这里插入图片描述

    若想只在目标路由执行中间件,则需添加判断

    export default defineEventHandler((event) => {
    // 仅在请求 /auth 接口时执行
    if (getRequestURL(event).pathname.startsWith('/auth')) {
    event.context.user = { name: 'Nitro' }
    }
    })

    工具函数 server/utils

    server/utils 目录中的工具函数,会自动导入

    • 若用默认导出 export default ,则自动导入的函数名为文件名
    • 若用具名导出 export function useSum ,则自动导入的函数名为函数定义的名称。

    server/utils/sum.ts

    export function useSum(a: number, b: number) {
    return a + b;
    }

    在接口文件中直接使用即可

    // routes/index.ts
    export default defineEventHandler(() => {
    const sum = useSum(1, 2) // auto-imported
    return { sum }
    })

    若 server/utils/sum.ts 为

    export default function useSum(a: number, b: number) {
    return a + b;
    }

    在接口文件中直接使用即可

    // routes/index.ts
    export default defineEventHandler(() => {
    const sumResult = sum(1, 2) // auto-imported
    return { sumResult }
    })

    封装统一接口方法

    server/utils/authHandler.ts

    import type { EventHandler } from "h3";
    export const defineAuthResponseEventHandler = (handler: EventHandler) => {
    return defineEventHandler(async (event) => {
    const user = await useStorage().getItem("user");
    if (!user) {
    throw createError({
    statusCode: 401,
    statusMessage: "未登录",
    });
    }

    const response = await handler(event);
    return response;
    });
    };

    插件 server/plugins

    插件会在服务启动时执行,可以访问生命周期

    范例:将 useStorage 改用 redis 存储 server/plugins/storage.ts

    import redisDriver from "unstorage/drivers/redis";

    export default defineNitroPlugin((app) => {
    const storage = useStorage();
    const { redis } = useRuntimeConfig();
    const driver = redisDriver({
    host: redis.host,
    port: redis.port,
    });
    storage.mount("redis", driver);
    });

    .env

    NUXT_REDIS_HOST=127.0.0.1
    NUXT_REDIS_PORT=6379

    nuxt.config.ts

    runtimeConfig: {
    redis: {
    host: "",
    port: 0,
    },
    },

    连接数据库

    安装依赖

    npx nuxi@latest module add nuxt-mongoose

    成功后,可见 nuxt.config.ts 的 modules 中添加了 “nuxt-mongoose”

    在 .env 中添加配置( 本地 mongoDB 数据库的名称为 test )

    MONGODB_URI=mongodb://localhost:27017/test

    操作数据

    创建 models

    会自动注册

    server/models/user.ts

    import { defineMongooseModel } from "#nuxt/mongoose";

    interface UserProps {
    name: string;
    age: number;
    }

    export const UserSchema = defineMongooseModel<UserProps>(
    "User",
    {
    name: { type: String, unique: true, required: true },
    age: { type: Number, min: 0, max: 160 },
    },
    {
    timestamps: true,
    toJSON: {
    // 过滤掉敏感字段
    transform(doc, ret) {
    delete ret.__v;
    delete ret.password;
    },
    },
    }
    );

    查询数据

    server/api/user/index.ts

    export default defineEventHandler(async (event) => {
    const userList = await UserSchema.find({})
    .select(["name", "age"])
    .limit(10)
    .lean();

    return { data: userList };
    });

    访问接口 http://localhost:3030/api/user 得到

    {
    "data": [
    {
    "_id": "653bc7cc0b10e8b08834b3ff",
    "name": "dos"
    }
    ]
    }

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Nuxt.js 3【详解】服务器 Server
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!