首页
layout.tsx文件中
<ClerkProvider >
<html lang="en">
<body
className={` {geistSans.variable} **{** geistMono.variable**}** antialiased flex flex-row**`}**
>
<div className="w-1/5 h-screen bg-gray-50">
<Navibar ></Navibar >
</div >
<div className="w-4/5 h-screen">
{children}
</div >
</body >
</html >
</ClerkProvider >
构建的一个带侧边栏布局的页面结构
className={{geistSans.variable} {geistMono.variable} antialiased flex flex-row}
- geistSans.variable、geistMono.variable:引入自定义字体(Geist Sans 和 Geist Mono)的变量,用于设置页面字体;
- antialiased:优化文本渲染的抗锯齿效果,让文字更清晰;
- flex flex-row:将 <body> 设为 Flex 容器,内部子元素水平排列(flex-row 是水平方向,flex-col 是垂直方向)
左侧导航栏区域
- w-1/5:宽度占父容器(<body>)的 1/5(即 20% 宽度);
- h-screen:高度占满整个屏幕高度;
- bg-gray-50:背景色为浅灰色(Tailwind CSS 的预设颜色);
- <Navibar></Navibar>:自定义的导航栏组件,用于展示侧边栏菜单
右侧内容区域
- w-4/5:宽度占父容器(<body>)的 4/5(即 80% 宽度);
- h-screen:高度占满整个屏幕高度;
- {children}:Next.js App Router 中的特殊语法,表示 "当前布局下的子页面内容"。例如,当用户访问 /dashboard 时,{children} 会渲染 dashboard/page.tsx 中的内容。
在项目根目录创建 components 文件夹,创建 Navbar.tsx 组件
快捷键:tsrafce 就会快速生成TypeScript 编写的 React 函数式组件模板
import React from 'react'
type Props = {}
const Navibar = (props: Props) => {
return (
<div>Navibar</div>
)
}
export default Navibar
若没有快捷键:
- 打开 VS Code 的扩展商店(快捷键 Ctrl+Shift+X 或 Command+Shift+X );
- 在搜索框中输入 ES7+ React/Redux/React-Native snippets ,找到对应的插件后点击 "安装";
- 安装完成后,重新打开编辑器,再尝试输入 tsrfce 按 Tab 键,看是否能生成组件代码。
ES7+ React/Redux/React-Native snippets 是一款在前端开发领域,尤其是使用 JavaScript 或 TypeScript 进行 React 相关开发时,非常实用的 VS Code 插件 ,它主要功能是提供大量的代码片段(snippets),帮助开发者快速生成常用的代码结构,从而显著提升开发效率
引入进来后,页面变成:

page.tsx文件中
'use client'
import Image from "next/image";
import { useState } from "react";
export default function Home() {
const [input, setInput] = useState("")
return (
<div className="h-screen flex flex-col items-center">
{/* 顶部空白区域 */}
<div className="h-1/5"></div>
{/* 主要内容区域 */}
<div className="w-1/2">
{/* 标题 */}
<p className="text-bold text-2xl text-center">
有什么可以帮您的吗
</p>
{/* 文本输入框容器 */}
<div className="flex flex-col items-center justify-center mt-4 shadow-lg border-[1px] border-gray-300 h-32 rounded-lg">
{/* 文本输入框 */}
<textarea
className="w-full rounded-lg p-3 h-30 focus:outline-none"
value={input}
onChange={(e) => setInput(e.target.value)}
/>
</div>
</div>
</div>
);
}

'use client' 用于声明当前组件是客户端组件;只有添加这个指令,组件才能使用 React 的状态(useState)、事件处理等客户端特性。如果没有这行,组件默认是服务器组件(Server Component),无法使用 useState 等客户端 API
导入依赖:
- import Image from "next/image":导入 Next.js 提供的图片处理组件
- import { useState } from "react":导入 React 的状态管理钩子,用于在组件中创建和管理状态。
const [input, setInput] = useState(""):使用 useState 创建了一个状态变量 input(初始值为空字符串)和更新函数 setInput,用于存储和修改用户的输入内容。
flex flex-col items-center(垂直排列,子元素水平居中)
受控文本框:
- textarea 通过 value={input} 绑定到状态变量 input,显示当前输入的内容。
- onChange={(e) => setInput(e.target.value)} 监听输入事件,每次用户输入时,会将输入框的最新值更新到 input 状态中。
https://mui.com/material-ui/material-icons/
即用 型 Material Design 组件:Material UI 是一个开源的 React 组件库,它实现了 Google 的 Material Design。它很全面,开箱即用
将Material UI添加到项目中:npm install @mui/icons-material
'use client'
import Image from "next/image";
import { useState } from "react";
import EastIcon from '@mui/icons-material/East'
export default function Home() {
const [input, setInput] = useState("")
const [model, setModel] = useState("deepseek-v3")
return (
<div className="h-screen flex flex-col items-center">
<div className="h-1/5"></div>
<div className="w-1/2">
<p className="text-bold text-2xl text-center">
有什么可以帮您的吗
</p>
<div className="flex flex-col items-center justify-center mt-4 shadow-lg border-[1px] border-gray-300 h-32 rounded-lg">
<textarea className="w-full rounded-lg p-3 h-30 focus:outline-none"
value={input}
onChange={(e) => setInput(e.target.value)}
>
</textarea>
<div className="flex flex-row items-center justify-between w-full h-12 mb-2">
<div>
<div className={`flex flex-row items-center justify-center rounded-lg border-[1px] px-2 py-1 ml-2 cursor-pointer ${model === 'deepseek-r1'?"border-blue-300 bg-blue-200":"border-gray-300"}`}>
<p className="text-sm">
深度思考(R1)
</p>
</div>
</div>
<div className="flex items-center justify-center border-2 mr-4 border-black p-1 rounded-full">
<EastIcon></EastIcon>
</div>
</div>
</div>
</div>
</div>
);
}

import EastIcon from '@mui/icons-material/East':Material UI 的图标组件(箭头图标,可用于提交功能)
const [model, setModel] = useState("deepseek-v3"):管理选中的模型,默认值为 deepseek-v3,可通过交互切换
外层容器:
- h-screen:高度占满屏幕
- flex flex-col:垂直排列子元素(从上到下)
- items-center:子元素水平居中。
顶部空白区域:
高度占屏幕的 1/5,用于顶部留白
主要内容区:
宽度为屏幕的 1/2,居中显示(受父容器 items-center 控制)
标题 :
有什么可以帮您的吗
加粗、字号 2xl、文本居中。
输入框容器:
- 弹性容器,内部垂直排列(flex-col),子元素水平和垂直居中(items-center justify-center),顶部外边距(mt-4)
- 带阴影(shadow-lg)、边框宽度(border-[1px])、灰色边框(border-gray-300)、固定高度(h-32)、圆角(rounded-lg)
文本输入框 :<textarea className="w-full rounded-lg p-3 h-30 focus:outline-none"
value={input}
onChange={(e) => setInput(e.target.value)}
>
- 宽度满屏(w-full)、内边距(p-3)、固定高度(h-30)、聚焦时无外边框(focus:outline-none)
- 受控组件:value 绑定 input 状态,onChange 实时更新状态,确保输入内容与状态同步
底部操作区:
水平排列(flex-row),子元素垂直居中(items-center)、两端对齐(justify-between),使左侧模型选择和右侧图标分居两端
模型选择按钮:
- cursor-pointer:鼠标悬停时显示手型,提示可点击
- 动态样式:当 model 为 deepseek-r1 时,显示蓝色边框和背景(选中状态);否则为灰色边框(未选中)
- 子元素垂直居中(items-center)、子元素水平居中(justify-center)、左右内边距为 2 个单位(px-2)、上下内边距为 1 个单位(py-1)、左侧外边距为 2 个单位(ml-2)
- 文本设置为 "小尺寸"(text-sm)
提交图标 :
包裹 EastIcon(右箭头图标),黑色边框、圆形(rounded-full)