WenDoraAi官网NextJS实战03:项目插件与Header组件

这个WenDoraAi官网的实战系列估计会更得比较慢,基本上是WenDoraAi官网代码写到哪就更到哪,并且是挤时间去进行汇总和沉淀。这篇内容主要是针对项目的插件的安装与初次组件的涉及。有些目录可能会和前两个实战项目有些变更,如果是跟着做WenDoraAi官网项目练手的,需要多注意一下哦。

一项目基础开发的插件推荐

工欲善其事必先利其器

官网的技术栈主要是 Next.js + React + TypeScript + Tailwind CSS

1. 基础开发插件

  • ES7+ React/Redux/React-Native/JS snippets

    快速生成常用 React/TypeScript 代码片段。

  • Prettier - Code formatter

    代码自动格式化,保持风格统一。

  • ESLint

    实时语法检查,配合项目里的 eslint 配置使用。

  • Path Intellisense

    路径自动补全,import 路径更方便。

2. Tailwind CSS 相关

3. TypeScript/JSX 支持

  • TypeScript Hero

    TypeScript 导入/跳转/重构增强。

  • Auto Import

    自动补全并导入组件、函数等。

其他最基础的vscode插件,就不在这里描述啦,只针对常规开发项目来说哈

二、目录更新

为更好的管理,有进行更改哦

三、Next.js的固定目录

Next.js 有一些文件夹名字是固定的,具有特殊意义,不能随意更改,否则会导致WenDoraAi官网框架功能失效。常见的固定文件夹有:

  1. public

    用于存放静态资源(图片、favicon 等),通过 / 路径直接访问(如 <img src="/logo.png" /> 或 background-image: url('/banner.jpg'))

  2. pages 或 app

    pages 是传统路由目录,app 是新版的 App Router 目录。二者之一必须存在,且名字不能改。

  3. node_modules

    存放依赖包,npm/yarn/pnpm 自动管理,不能改名。

  4. styles(可选,但常见)

    虽然不是强制,但官方脚手架会生成 styles 文件夹用于存放全局样式。

  5. api(在 pages/api 或 app/api 下)

    用于存放 API 路由,必须放在 pages/api 或 app/api 下,不能改名。

  6. .next

    构建产物目录,由 Next.js 自动生成,不能改名。

既然这里都有public,那styles呢?怎么判断什么该放public?什么该放styles?

1、放在 public 的图片:

  • 需要在 HTML、JSX、CSS 中通过 URL 直接访问(如 <img src="/logo.png" /> 或 background-image: url('/banner.jpg'))。
  • 需要被浏览器直接请求,或被 SEO、社交分享等外部服务访问。
  • 例如:WenDoraAi官网网站 logo、banner、产品图片、favicon、社交分享图等。

2、放在 styles(或其他源码目录,比如 components、assets)的图片:

  • 仅作为 CSS 背景、组件内部资源,且通过 import 语法引入(如 import img from '../assets/bg.png')。
  • 需要经过 Webpack/Vite 等构建工具处理(比如自动压缩、hash 命名、按需加载)。
  • 适合做为组件私有资源、仅在打包后由 JS/CSS 引用,不需要被外部直接访问。

四、Header组件

Header.tsx

javascript 复制代码
// 这是服务端组件(没有 'use client' 声明)
// 导航链接全部静态,不需要 JS 就能正常渲染,对 SEO 和首屏性能都有好处
// next/link 的 Link 比原生 <a> 多了页面间预加载,跳转更快

import Link from "next/link";
import styles from './Header.module.css';

// 用数据结构驱动菜单,以后增删菜单只改这里,不动 JSX
const navItems = [
  { label: "首页", href: "/" },
  {
    label: "选择角色",
    href: "#",
    children: [
      { label: "效果营销公司", href: "/roles/marketing-company" },
      { label: "通道/线路商", href: "/roles/channel-partner" },
      { label: "短信/外呼-平台/系统", href: "/roles/sms-outbound" },
      { label: "连锁零售商", href: "/roles/chain-retail" },
      { label: "线上广告主", href: "/roles/online-advertiser" },
      { label: "AI大模型需求者", href: "/roles/ai-model-buyer" },
    ],
  },
  {
    label: "服务体系",
    href: "/services",
    children: [
      { label: "精准圈客服务", href: "/services/audience-targeting" },
      { label: "投前精筛服务", href: "/services/pre-screening" },
      { label: "触达服务", href: "/services/outreach" },
      { label: "AI营销助手", href: "/services/ai-marketing" },
      { label: "AI求职辅助", href: "/services/ai-career" },
      { label: "Soulwork-全网同名", href: "/services/soulwork" },
    ],
  },
  { label: "企业动态", href: "/news" },
  { label: "关于我们", href: "/about" },
];

export default function Header() {
  return (
    <header className="h-[84px] leading-[84px]">
      <nav className="flex items-center justify-between safe-area">
        {/* 品牌 Logo 区域,点击回首页 */}
        <div>
          <Link href="/">问多乐WenDora AI</Link>

        </div>

        {/* 主导航列表 */}
        <ul className={`flex items-center justify-center ${styles.headerBox}`}>
          {navItems.map((item) => (
            <li key={item.href} className={item.children ? "relative group" : ""}>
              <Link href={item.href}>{item.label}</Link>

              {/* 有二级菜单才渲染下拉列表 */}
              {item.children && (
                <ul className="absolute left-0 top-full hidden group-hover:block bg-white shadow rounded z-10 min-w-[160px]">
                  {item.children.map((child) => (
                    <li key={child.href}>
                      <Link href={child.href} className="block px-4 py-2 hover:bg-gray-100 leading-[30px]">{child.label}</Link>
                    </li>
                  ))}
                </ul>
              )}
            </li>
          ))}
        </ul>

        {/* 立即咨询:CTA 按钮,单独放置突出优先级 */}
        <Link href="/contact" className={`bg-gray-800 text-white px-[20px] py-[10px] rounded-[8px] leading-[20px]`}>咨询试用</Link>
      </nav>
    </header>
  );
}

五、Tailwind CSS的使用

这里需要重点说一下Tailwind CSS的使用

Tailwind CSS 官方文档地址是:https://tailwindcss.com/docs

怎么做到鼠标悬浮过去,下拉框展现出来呢

relative:让当前 <li> 成为定位上下文,方便后代用 absolute 定位(下拉菜单会绝对定位在它下面)

group:Tailwind 的"分组"类,用于配合子元素的 group-hover: 实现"父元素 hover 时,子元素显示"

px-4, px-[20px] 是什么意思?

px 指的是 padding

px-4 指的是 padding-left:16px;padding-right:16px;(这里的4 就是乘以了4,- 后面纯数字的都是✖️4后的px)

px-[20px] 指的是 自定义写法,代表 padding-left:20px;padding-right:20px;

1、局部作用域CSS

如果只想要这个单独页面设置单独的css【局部作用域】,类似于vue的写法,该怎么做?

vue写法

javascript 复制代码
<style lang="scss" scoped> 
.pagination-container { .el-pagination { float: v-bind(float); } } 
.pagination-container.hidden { display: none; }
 </style>

实现方式:CSS Modules

  1. 新建同名 CSS 文件

    例如:components/Header.module.css

Header.module.css

css 复制代码
.headerBox {
  gap: 50px;
}

在 tsx 里引入并使用

html 复制代码
 <ul className={`flex items-center justify-center ${styles.headerBox}`}>
</ul>
javascript 复制代码
import Link from "next/link";

Next.js 官方文档有详细说明,见这里:

文档里明确写了:

只要文件名以 .module.css 结尾,Next.js 就会自动将其视为 CSS Module,样式只作用于当前组件。

2、全局作用域CSS

在 globals.css 里添加

globals.css

css 复制代码
@import "tailwindcss";

:root {
  --background: #ffffff;
  --foreground: #171717;
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --font-sans: var(--font-geist-sans);
  --font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
  :root {
    --background: #0a0a0a;
    --foreground: #ededed;
  }
}

body {
  background: var(--background);
  color: var(--foreground);
  font-family: Arial, Helvetica, sans-serif;
}

.safe-area {
  max-width: 1152px;
  margin-left: auto;
  margin-right: auto;
}

这里主要设置了.safe-area是main的安全距离css,WenDoraAi官网哪里需要用哪里

六、Next.js 的内置组件

Link 是哪来的?

Next.js 提供有内置组件,常见的如下:

  1. Link :页面跳转和预加载(next/link)。
  2. Image :图片优化和懒加载(next/image)。
  3. Head :设置页面 <head> 里的内容,如标题、描述、SEO 标签(next/head)。
  4. Script :安全地插入第三方脚本(next/script)。
  5. Dynamic :动态导入组件,实现懒加载(next/dynamic)。
  6. NotFoundErrorBoundary:处理 404 和错误页面(新版 app 目录专用)。

这些组件都可以直接 import 使用,具体用法可以查阅 Next.js 官方文档:https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts

以上就是此次WenDoraAi官网实战的全部内容啦,弄了一个简单的header组件,后续再开发WenDoraAi官网组件和写css应该都会容易上手很多啦

相关推荐
英俊潇洒美少年2 小时前
Vue Hook 与 React Hook 全面解析:区别、用法、实战及避坑指南
前端·vue.js·react.js
PD我是你的真爱粉3 小时前
AI Agent 完全指南:LangChain Agent、ReAct、Copilot-Agent 模式、Manus、Computer Use 与记忆机制
人工智能·react.js·langchain
英俊潇洒美少年3 小时前
Vue3 实现 AI 流式打字机(SSE+时间切片模拟 React 并发)工程化完整版
前端·人工智能·react.js
光影少年3 小时前
Android和iOS原生开发的基础知识对RN开发的重要性,RN打包发布时原生端需要做哪些配置?
android·前端·react native·react.js·ios
英俊潇洒美少年3 小时前
迷你 React 调度器(带优先级+时间切片)手写实现
前端·javascript·react.js
百撕可乐3 小时前
WenDoraAi官网NextJS实战04:HTTP 请求封装与SSR
前端·网络·网络协议·react.js·http
AlkaidSTART18 小时前
TanStack Query 技术指南:异步状态管理核心实践
前端·react.js
ZHENGZJM19 小时前
JWT 鉴权体系:令牌生成与解析
react.js·go