阅读 715

[重学 Next.js] — 你应该知道的 Next.js 高级技巧 10 点 (下)

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

前言

上一篇文章 [重学 Next.js] — 你应该知道的 Next.js 高级技巧 10 点 (上) 进行了 Next.js 高级用法的前五点,今天我们来说说剩下的五点,可谓是一个比一个有用,以后在 Next.js 开发过程中都会有极大的帮助。

原文链接

VI - Absolute Imports and Module Path Aliases - 模块路径导入

这一点毋庸置疑,大部分人平时在自己搭建项目的时候,也会通过各种复杂的配置比如 Webpack alias/Babel 等进行配置,配置的好处就是:

  • 原来的代码
import Button from "../../../components/button";
import request from "../../../utils/request";
复制代码
  • 新的代码
import Button from "@/components/button";
import request from "@/utils/request";
复制代码

这样做并不是强制性的,看开发者的个人习惯,但是这样做有两点好处:

  • 使用简单,再也不用去费劲吧啦的去数相对路径有几层了

  • 如果某天你的相对路径层级发生了变化,也不需要去手动修复,因为它看起来就和绝对路径一样

示例代码

那么在 Next.js 里,这个功能是如何简单的进行配置实现呢?

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
复制代码

上面两个配置就是核心的配置,真的是非常简单,配置过后的效果,如下图所示:

image.png

如果你使用的是 TS,那么对应修改的就是 tsconfig.json, 如果你使用的是 JS,那么对应修改的就是 jsconfig.json

VII - CRUD API Routes —— 动态 API 路由

【版本】: >= Next.js Version 9.1.4

【功能】: 动态 API 路由。

【解释】: 动态 API 路由扩展了 Next.js 框架自身的能力,更为方便的做 node 层处理以及不需要任何改造就能实现一个全栈框架。

动态路由 API 的出现,算是 Next.js 浓墨重彩的一笔,官方给的是名称是 Dynamic API Route,但是其实如果你是一个 Next.js 的入门使用者,你其实可能也不知道这东西到底能干啥,这里使用的词是 CURD API Routes,就从 CURD 这个角度,来给大家简单看看这个功能的强大之处。

示例代码1 - 最简单的 GET 数据

这里没有链接数据库,简单的构造了一下数据:

const users = [];

for (let i = 0; i < 126; i++) users.push(i);

const data = Array.from(users, (item) => ({
  id: item,
  age: Math.random() * 60,
  name: `luffy-${++item}`,
  email: `luffy-${++item}@126.com`,
}));

export default data;
复制代码

然后使用 Next.js API 路由来编写一个接口:

// src/pages/api/user/list

import type { NextApiRequest, NextApiResponse } from 'next'
import users from '@/data/user';

type IUserData = {
  id: number,
  age: number,
  name: string,
  email: string,
}


function sleep(time: number) {
  return new Promise(resolve => setTimeout(resolve, time))
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<IUserData[]>
) {
  await sleep(3000);
  res.status(200).json(users);
}

复制代码

非常简单就是把我们的构造数据返回,我们可以来调用一下:

image.png

可以看到,接口正常返回数据了,然后我们在页面里获取一下然后渲染。

import { Table } from 'antd';
import swr from 'swr';

const columns = [
  {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
  },
  {
    title: '姓名',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '年龄',
    dataIndex: 'age',
    key: 'age',
  },
  {
    title: '邮箱',
    dataIndex: 'email',
    key: 'email',
  },
];

const fetcher = (url: string) => fetch(url).then(res => res.json()).then(data => data);

export default function UserList() {
  const { data, error } = swr('/api/user/list', fetcher)
  return (
    <Table
      rowKey="id"
      loading={!data}
      dataSource={data}
      columns={columns}
    />
  )
}
复制代码

一个非常简单的页面,展示用户列表,看一下实际效果:

2021-08-25 16.14.05.gif

上面就是一个简单的数据流程,mock api -> 获取数据 -> 渲染页面,最主要的是这一切都闭环在 Next.js 项目里,你不需要去其他网站或者平台,真的很方便。

示例代码2 - CURD

上面是一个简单的 GET api 请求,既然是 CURD,那么肯定是不仅仅一个 GET 这么简单,这里再通过一小段代码,来给大家看看强大的 Next.js CURD API Routes。


// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
import users from '@/data/user';

type IUserData = {
  id: number,
  age: number,
  name: string,
  email: string,
}

function sleep(time: number) {
  return new Promise(resolve => setTimeout(resolve, time))
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<IUserData[] | any>
) {
  if (req.method === 'PUT') {
    console.log('req.body: ', req.body);
    res.status(200).json({ message: `PUT 请求接受成功,请求的 body 数据是 ${JSON.stringify(req.body)}` });
  }

  if (req.method === 'GET') {
    await sleep(1000);
    console.log('req.query: ', req.query);
    res.status(200).json(users.find(item => item.id === +req.query.id));
  }

  if (req.method === 'POST') {
    console.log('req.body: ', req.body);
    res.status(200).json({ message: `POST 请求接受成功,请求的 body 数据是 ${req.body}` });
  }

  if (req.method === 'DELETE') {
    console.log('req.body: ', req.body);
    res.status(200).json({ message: `DELETE 请求接受成功,想要删除的数据是 ${req.body}` });
  }
}

复制代码

上面就是一个简单的增删改查 CURD API ROUTES,是不是非常的简单?也来看一下效果如何:

2021-08-25 19.40.00.gif

从上面两个例子相信大家很容易就能发现这个功能的强大之处,Next.js CURD API 我这边简单总结的话有如下几点好处:

  • 开发中可以模拟真实的数据交互流程而不用自己虚假的构造数据

  • Mock 数据打通 API 接口很方便,场景也更真实

  • 有了这个 API,Next.js 基本上是无缝切换全栈

  • 更多需要大家使用过程中自己去体会...

VIII - Setting Response HTTP Caching Headers —— 设置 HTTP 请求缓存头

这个理解起来就很简单了,Next.js 其实一直在做的就是静态增量,对于静态页面以及资源来说,Vercel Edge Network 将自动 缓存 静态资产,以便尽快提供数据。不过当需要使用 API 路由或服务器端渲染页面时,开发者需要手动设置一个Cache-Control头部来缓存这些资源。

示例代码

下面代码,将对应的 json 响应换存在 Vercel 服务器一天。

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<IUserData[]>
) {
  res.setHeader(
    'Cache-Control',
    's-maxage=86400'
  );
  res.status(200).json(users);
}
复制代码

如果大家平时自己使用 Next.js 开发,更建议大家用 Vercel 部署,毕竟生态都是一体的,优化得更好。

IX - Shared Component Attributes —— 共享组件属性

关于这个概念,其实很多框架都在做,也确实是方便了开发者,举个最简单的例子来说明共享组件属性

示例代码

  • 没有/不使用共享组件之前
// pages/list.tsx

import Head from 'next/head';

export default function List() {
  return (
    <>
      <Head>
        <title>列表页</title>
        <meta name="description" content="我是列表页的描述" />
      </Head>
      我是列表页面,路径是 /list
    </>
  );
}

复制代码
  • 使用共享组件后
// pages/list.tsx

export default function List() {
  return (
    <>
      我是列表页面,路径是 /list
    </>
  );
}

List.title = '列表页';
List.description = '我是列表页的描述';
复制代码
// pages/_app.tsx

import type { AppProps} from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <>
      <Head>
        <title>{Component.title || 'Next App'}</title>
        <meta name="description" content={Component.description || ''} />
      </Head>
      <Component {...pageProps} />
    </>
  )
}
export default MyApp

复制代码

仔细一看,感觉没方便啥样,但是我举的例子只是一个组件,当你的系统有几十个几百个页面的时候,这种方式的便利性就体现出来了,大家可以仔细对比思考一下。最后效果就是如下图所示:

image.png

X - Next.js Mobile Applications? —— 基于 Next.js 的移动端应用

是的你没看错,就是带着一个问号,但是我觉得已经是一个肯定的结论了,在跨端框架盛行的今天,RN、Flutter 等框架为前端赋能,同时 Next.js 也在跨端这条路上开始行自己的路了,比如接下来要介绍的 —— CapacitorJS,感谢 Ionic 团队,他们创建了 CapacitorJS 让我们可以使用 Next.js 构建类似移动端应用的体验,这是一个可以在手机上为您提供原生体验的库。

因为我也没有过多的研究过,所以在这里就简单的照葫芦画瓢给大家跑一个 Demo 看看。

示例代码

官方仓库

# 打包编译
yarn install
yarn build
yarn export

# 运行 IOS APP
npx cap sync
npx cap run ios

复制代码

我这边是运行的是 IOS APP,选择的模拟器是 iPhone11,启动项目后效果如下:

2021-08-25 20.51.06.gif

官方的架构原理图:

image.png

总的来说,开发模式基本上就是 Next.js 的开发模式,使用体验上也还 OK,个人觉得可以尝试玩玩。

总结

算是个人重新开始用 Next.js 的第一次输出文章,后面决定深入 Next.js,希望能跟大家分享更多关于 Next.js 的文章,感兴趣可以加交流群,随时沟通,有问必答~

image.png

文章分类
前端
文章标签