【前端学习】仿Deepseek官网AI聊天网站React

首页

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}

  1. geistSans.variable、geistMono.variable:引入自定义字体(Geist Sans 和 Geist Mono)的变量,用于设置页面字体;
  2. antialiased:优化文本渲染的抗锯齿效果,让文字更清晰;
  3. flex flex-row:将 <body> 设为 Flex 容器,内部子元素水平排列(flex-row 是水平方向,flex-col 是垂直方向)

左侧导航栏区域

  1. w-1/5:宽度占父容器(<body>)的 1/5(即 20% 宽度);
  2. h-screen:高度占满整个屏幕高度;
  3. bg-gray-50:背景色为浅灰色(Tailwind CSS 的预设颜色);
  4. <Navibar></Navibar>:自定义的导航栏组件,用于展示侧边栏菜单

右侧内容区域

  1. w-4/5:宽度占父容器(<body>)的 4/5(即 80% 宽度);
  2. h-screen:高度占满整个屏幕高度;
  3. {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

若没有快捷键:

  1. 打开 VS Code 的扩展商店(快捷键 Ctrl+Shift+X 或 Command+Shift+X );
  2. 在搜索框中输入 ES7+ React/Redux/React-Native snippets ,找到对应的插件后点击 "安装";
  3. 安装完成后,重新打开编辑器,再尝试输入 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

导入依赖:

  1. import Image from "next/image":导入 Next.js 提供的图片处理组件
  2. import { useState } from "react":导入 React 的状态管理钩子,用于在组件中创建和管理状态。

const [input, setInput] = useState(""):使用 useState 创建了一个状态变量 input(初始值为空字符串)和更新函数 setInput,用于存储和修改用户的输入内容。

flex flex-col items-center(垂直排列,子元素水平居中)

受控文本框:

  1. textarea 通过 value={input} 绑定到状态变量 input,显示当前输入的内容。
  2. 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,可通过交互切换

外层容器

  1. h-screen:高度占满屏幕
  2. flex flex-col:垂直排列子元素(从上到下)
  3. items-center:子元素水平居中。

顶部空白区域

高度占屏幕的 1/5,用于顶部留白

主要内容区

宽度为屏幕的 1/2,居中显示(受父容器 items-center 控制)

标题

有什么可以帮您的吗

加粗、字号 2xl、文本居中。

输入框容器

  1. 弹性容器,内部垂直排列(flex-col),子元素水平和垂直居中(items-center justify-center),顶部外边距(mt-4)
  2. 带阴影(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)}

>

  1. 宽度满屏(w-full)、内边距(p-3)、固定高度(h-30)、聚焦时无外边框(focus:outline-none)
  2. 受控组件:value 绑定 input 状态,onChange 实时更新状态,确保输入内容与状态同步

底部操作区

水平排列(flex-row),子元素垂直居中(items-center)、两端对齐(justify-between),使左侧模型选择和右侧图标分居两端

模型选择按钮

  1. cursor-pointer:鼠标悬停时显示手型,提示可点击
  2. 动态样式:当 model 为 deepseek-r1 时,显示蓝色边框和背景(选中状态);否则为灰色边框(未选中)
  3. 子元素垂直居中(items-center)、子元素水平居中(justify-center)、左右内边距为 2 个单位(px-2)、上下内边距为 1 个单位(py-1)、左侧外边距为 2 个单位(ml-2)
  4. 文本设置为 "小尺寸"(text-sm)

提交图标

包裹 EastIcon(右箭头图标),黑色边框、圆形(rounded-full)

相关推荐
循环过三天3 小时前
3.4、Python-集合
开发语言·笔记·python·学习·算法
昌sit!4 小时前
Linux系统性基础学习笔记
linux·笔记·学习
学会沉淀。5 小时前
设备如何“开口说话”?
学习
devincob5 小时前
js原生、vue导出、react导出、axios ( post请求方式)跨平台导出下载四种方式的demo
javascript·vue.js·react.js
编程社区管理员5 小时前
React 发送短信验证码和验证码校验功能组件
前端·javascript·react.js
葡萄城技术团队5 小时前
迎接下一代 React 框架:Next.js 16 核心能力解读
javascript·spring·react.js
全马必破三6 小时前
React“组件即函数”
前端·javascript·react.js
三思而后行,慎承诺6 小时前
React 底层原理
前端·react.js·前端框架
座山雕~6 小时前
html 和css基础常用的标签和样式
前端·css·html
m0_591338916 小时前
day10数组的学习
学习