😼使用Next.js搭建一个全栈前端知识库项目

最近在做一个全栈项目,前端知识非常琐碎,所以想把前端知识点汇总到一起,无论是以后想查询某个知识点,还是学习到新的知识,都可以快速的查询和记录

全部代码已开源到GitHub;先赞后看,年入百万!

技术栈使用React的Next.js框架和Tailwind CSS,大纲如下

为什么是Next.js

Next.js是一个基于React的服务端渲染框架。 这是一个用于 生产环境的 React 框架

Next.js 提供了许多优点和功能:

  1. 服务端渲染 (SSR) 和预渲染 (SSG) :Next.js 支持服务端渲染和预渲染,这意味着页面在服务器端生成,而不是在客户端。这有助于提高网页的加载速度和搜索引擎优化(SEO),同时也提供更好的首次渲染体验。

  2. 快速加载时间:由于 Next.js 支持预渲染和服务端渲染,用户可以更快地看到页面内容,因为大部分工作在服务器端完成,减少了客户端加载所需的时间。

  3. 热模块替换 (HMR) :Next.js 支持热模块替换,这意味着在进行开发时,您可以在保持应用程序运行的同时修改代码,并立即看到变化,无需刷新页面。

  4. 简单的部署:Next.js 的默认配置使得应用程序的部署非常简单。您可以使用 Vercel、Netlify 等平台将应用程序快速部署到云端,或者将其部署到自己的服务器上。

  5. 丰富的生态系统:Next.js 是一个非常受欢迎的框架,拥有庞大的社区和丰富的插件,扩展和工具支持。这使得开发人员能够轻松解决常见问题,并快速构建复杂的 web 应用程序。

  6. 自动优化:Next.js 内置了许多优化功能,包括自动压缩和缓存等,这些功能有助于提高应用程序的性能和用户体验。

  7. 支持多种数据获取方法 :Next.js 提供了多种数据获取方式,如 getServerSidePropsgetStaticProps,使得获取数据变得简单和灵活。

初始化项目

使用的node版本 是 16.x

创建项目

js 复制代码
npx create-next-app frontend-knowledge

没有使用TS,也没有用src目录

Next的Tailwind CSS内置 postcssautoprefixer

Tailwind CSS使用教程可以看这篇文章👉Tailwind css 在项目中的使用与问题

项目结构目录

  • app文件夹用于定义路由,layout.tsxpage.tsx文件。当用户访问应用程序的根目录 /时,访问到的就是 app下的page.jsx.

每个文件夹表示一个路由,映射到一个URL

  • pages/api 用于编写next后端接口

前端页面

app文件路由

Next 中 app里的每一个文件就是一个路由

  • 根目录 http://localhost:3000/,对应 app下的page.jsx

Layout.jsx 是一个用于组织页面结构和共享组件的重要概念。Layout 可以看作是一个组件包裹器,它包含了页面共享的部分,例如页眉(Header)、页脚(Footer)和导航栏(Navigation)或者 page.jsxlayout.jsx相当于page的布局组件.

前端知识库 无论是首页还是子路由都需要有一个左侧导航栏,所以可以把导航栏放到Layout.jsx页面,page页面会映射到 children 里

jsx 复制代码
import '@/styles/globals.css';
import SlideBar from '@/components/SlideBar';

function RootLayout({ children }) {
    return (
      <html lang='en'>
        <body >
            <main className='app'>
              <SlideBar />
              <div className='w-full h-full'>{children}</div>
            </main>
        </body>
      </html>
    )
  }
  
  • 二级目录 http://localhost:3000/category,对应 app/category下的page.jsx

"use client"

"use client" 指令是声明服务器和客户端组件模块图之间边界的约定。

NextJS 13默认情况下,App 文件夹内的 所有组件都是服务器组件。并且 服务器组件 不能使用 useState、useEffect 等客户端特性。

jsx 复制代码
'use client'
import { useState, useEffect } from "react";
import Image from 'next/image';

const Home = () => {
  return (
    <div>
      <h1>Welcome to Next.js</h1>
      <p>This is the home page content.</p>
      {/* 使用 Next Image 组件 */}
      <Image
        src="/path/to/your/image.jpg"
        alt="Description of the image"
        width={300}
        height={200}
      />
    </div>
  );
};

export default Home;

组件引入

引入路由 Link

jsx 复制代码
import React from 'react';
import Link from 'next/link';

const Home = () => {
  return (
    <div>
      <h1>Welcome to Next.js</h1>
      <p>This is the home page content.</p>
      {/* 使用 Link 组件实现导航链接 */}
      <Link href="/category">
        跳转路由
      </Link>
    </div>
  );
};
export default Home;

Link 组件使用客户端导航而不是传统的页面刷新。当用户点击链接时,只有目标页面的内容会被加载,而不会重新加载整个应用程序

Image 图片引入

Image 组件中,您需要提供以下属性:

  • src:图像的路径。它可以是本地路径或远程 URL。
  • alt:图像的替代文本,用于辅助技术和当图像无法加载时显示。
  • width:图像的宽度,应以像素为单位提供。
  • height:图像的高度,应以像素为单位提供。
jsx 复制代码
import React from 'react';
import Image from 'next/image';
const Home = () => {
  return (
    <div>
      <h1>Welcome to Next.js</h1>
      <p>This is the home page content.</p>
      {/* 使用 Next Image 组件 */}
      <Image
        src="/path/to/your/image.jpg"
        alt="Description of the image"
        width={300}
        height={200}
      />
    </div>
  );
};

export default Home;

Notion数据库

Notion 不仅是一款个人笔记软件,还可以当作数据库使用 Notion在线笔记

可以通过安装 Notion API SDK 来进行连接数据库,获取数据

创建数据库

创建一个DATABASE数据库 然后再创建各个字段

创建应用集成,获取密钥

去Notion创建一个应用集成,获取 API Key👉Notion Developers

数据库就创建好了,接下来就可以再Next里连接数据库进行获取数据了

连接数据库

创建Notion服务

安装Notion API 客户端

js 复制代码
npm install @notionhq/client

创建一个 NotionServer 服务,将请求数据库的方法进行封装

lib/NotionServer.js

js 复制代码
import { Client } from "@notionhq/client";
const auth = process.env.NOTION_AUTH;
const database = process.env.NOTION_DATABASE_ID;
export default class NotionService {
  constructor() {
    this.client = new Client({ auth });
  }
  async query() {
    const response = await this.client.databases.query({
      database_id: database,
    });

    return  response.results;
  }
}

NOTION_AUTH是数据库集成的密钥

NOTION_DATABASE_ID是notion链接上面的 id

再新建一个pages/api/question.js路由,调用NotionServer查询服务

js 复制代码
import NotionServer from "../../lib/NotionServer";
const notionServer = new NotionServer();

export default async function handler( req, res ) {
  const data = await notionServer.query();
  res.status(200).json(data);
}

在浏览器中输入 localhost:3000/api/question 就可以看到获取的数据,此时数据还比较杂乱,可以处理一下,返回自己想要的数据

展示到前端页面

在首页的 page.jsx页面里使用 fetch方法获取数据,前端页面

jsx 复制代码
"use client";
import { useState, useEffect } from "react";
import QuestionCard from "@/components/QuestionCard"


function Home() {
  const [questionList, setQuestionList] = useState([]);
  const [jsList, setJsList] = useState([]);

  const getQuestionList = () => {
    fetch('/api/question')
      .then((res) => res.json())
      .then((res) => {
        if (res) {
          setQuestionList(res.sort((a, b) => a.id - b.id));
        }
      })
      .catch((error) => {
        console.error(error);
      });
  };

  useEffect(() => {
    getQuestionList();
  }, []);
  useEffect(() => {
    const jsItems = questionList.filter(item => item.tags === "JavaScript");
    setJsList(jsItems);
  }, [questionList]);
  return (
    <div className="w-full h-full  overflow-auto">
      <section className=" gap-4 p-6 space-y-4 md:columns-2">
        <QuestionCard questionList={jsList} type="JavaScript" />
      </section>
    </div>
  )
}
export default Home

Markdown数据渲染

数据存储采用的是Markdown格式,所以就需要第三方的Markdown插件进行展示

markdown-it 数据展示

安装 markdown-it

js 复制代码
npm install markdown-it
jsx 复制代码
'use client'
import { useState,useEffect } from 'react'
// 1. 引入markdown-it库
import markdownIt from 'markdown-it'
// 2. 生成实例对象
const md = new markdownIt();

function DialogCard({data,closeDialog}) {
    const [htmlString, setHtmlString] = useState('')  // 存储解析后的html字符串

    // 3. 解析markdown语法
    const parse = (data) => setHtmlString(md.render(data.explanation));
    useEffect(()=>{
        parse(data)
    },[])

  return (
    <div className='show w-full mt-1 flex-grow overflow-auto '>
          <div 
              className='w-full'
              dangerouslySetInnerHTML={{ __html: htmlString }} // 将html字符串解析成真正的html标签
          />
    </div>
  )
}

export default DialogCard

Tailwind css 默认将所有的 h1-h6和ul,li 基础样式重写,所以markdown展示的样式和普通文本没有区别

官方的Tailwind CSS Typgraphy插件提供了一组 prose 类,可以使用它们为任何不受控制的普通HTML 添加漂亮的排版默认值,例如从Markdown呈现的HTML或从CMS中提取的HTML。

安装:

js 复制代码
npm install -D @tailwindcss/typography

然后将插件添加到 tailwind.config.js 文件中:

js 复制代码
/** @type {import('tailwindcss').Config} */
module.exports = {
  plugins: [
    require("@tailwindcss/typography")
  ],
}

最后在 div 添加 prose

js 复制代码
 <div  className='prose w-full'
  dangerouslySetInnerHTML={{ __html: htmlString }} // 将html字符串解析成真正的html标签
/>

代码高亮

markdown-it 默认的代码块格式没有样式,可以安装highlight 插件进行添加代码块样式

js 复制代码
npm install highlight.js 

然后引入样式文件,在生成实例时,进行初始化

js 复制代码
import hljs from "highlight.js";
import 'highlight.js/styles/monokai-sublime.css'
// 2. 生成实例对象
const md = new markdownIt({
 highlight: function (str, lang) {
   if (lang && hljs.getLanguage(lang)) {
     try {
       return hljs.highlight(str, { language: lang }).value;
     } catch (_) {}
   }
   return ""; // 使用额外的默认转义
 },
});

写到这里项目也算是完成了,源码放到了GitHub上👨‍🦼‍➡️frontend-konwledge 欢迎大家 star🌟🌟🌟

部署到Vercel

使用github账号登录到 Vercel

找到项目,选择导入

添加环境变量名和值,相当于.env里的值

部署成功后就可以访问了

更新新代码时,不用再次部署,它会自动更新到最新代码。只不过国内访问可能会被🧱墙

在线预览地址🏂 前端知识点 (frontend-konwledge.vercel.app)

最后

本文只介绍了项目中使用到的Next技巧,和其他的一些使用教程

像一些SSR,动态路由,元数据等使用方式,准备在项目优化时配合着真实的案例再记录

Tailwind css教程可以看这篇文章👀Tailwind css 在项目中的使用与问题

项目源码放到了GitHub上👨‍🦼‍➡️frontend-konwledge

在线预览地址🏂 前端知识点 (frontend-konwledge.vercel.app)

相关推荐
weixin_382395234 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__4 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.5 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~6 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华6 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子9 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅9 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni9 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学10 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端