my-first-ai-web_问题记录03——NextJS 项目框架基础扫盲

跟着双越老师的划水AI项目学习记录,从Vue转向React+Next.js的踩坑经验分享。

核心工具快速了解

UI相关库

  • lucide-react:1000+矢量图标,即取即用
  • shadcn/ui:零依赖组件库,代码复制到项目完全可控
  • @radix-ui:shadcn/ui底层依赖,提供无障碍基础组件

样式工具

  • class-variance-authority (CVA):管理组件变体样式
  • tailwind-merge:智能合并Tailwind类名,解决冲突
  • clsx:条件性组合类名的微型工具
tsx 复制代码
import { twMerge } from 'tailwind-merge';
import clsx from 'clsx';

// 结合使用,处理复杂样式场景
function Button({ variant, size, className, children, ...props }) {
  return (
    <button
      className={twMerge(
        clsx(
          'inline-flex items-center justify-center rounded-md font-medium',
          {
            'bg-blue-600 text-white': variant === 'primary',
            'bg-gray-200 text-gray-800': variant === 'secondary',
            'h-9 px-3 text-sm': size === 'sm',
            'h-10 px-4 text-base': size === 'md',
          },
          className // 外部传入的样式会正确覆盖默认样式
        )
      )}
      {...props}
    >
      {children}
    </button>
  );
}

功能库

  • Next.js:全栈React框架,文件系统路由
  • next-themes:主题切换(暗色/亮色模式)
  • react-resizable-panels:可拖拽调整的面板布局
  • react-hook-form:高性能表单处理和验证
  • ...

Vue vs React 核心差异

1. 快速适应技巧

  • 从"指令"到"表达式"v-if{condition && <div/>}
  • 从"双向绑定"到"单向数据流":手动控制状态更新
  • 从"选项式"到"函数式":一切都是函数和Hook

2. 常用Hook对照

Vue Composition API React Hook
ref() useState()
computed() useMemo()
watch() useEffect()
onMounted() useEffect([], [])

3. Next.js特色功能

  • 服务器组件:默认在服务器渲染,性能更好
  • 客户端组件 :添加'use client'才能使用浏览器API
  • 文件路由app/work/[id]/page.tsx = /work/123

4.具体代码对比

1. 组件结构

vue 复制代码
<!-- Vue:三段式分离 -->
<template>
  <div>{{ title }}</div>
</template>
<script>
const title = ref('标题')
</script>
<style scoped>
.title { color: red; }
</style>
tsx 复制代码
// React:JSX一体化
export default function Component() {
  const [title, setTitle] = useState('标题');
  return <div className="text-red-500">{title}</div>;
}

2. 数据绑定

Vue React
{{ message }} {message}
v-model="input" value={input} onChange={setInput}
@click="handle" onClick={handle}
v-if="show" {show && <div/>}
v-for="item in list" {list.map(item => <div/>)}

3. 状态管理

vue 复制代码
<!-- Vue -->
<script setup>
const count = ref(0);
const user = reactive({ name: '张三' });
</script>
tsx 复制代码
// React
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: '张三' });

// 更新对象需要展开
setUser(prev => ({ ...prev, age: 20 }));

4. 路由参数获取

js 复制代码
// Vue Router
const id = this.$route.params.id;
tsx 复制代码
// Next.js 15 - 服务器组件
export default async function Page({ params }) {
  const { id } = await params;
  return <div>项目 {id}</div>;
}

// Next.js 15 - 客户端组件  
'use client';
import { useParams } from 'next/navigation';
const params = useParams();

5. 条件样式处理

vue 复制代码
<!-- Vue -->
<div :class="{ active: isActive, error: hasError }">内容</div>
tsx 复制代码
// React - 使用 clsx
import clsx from 'clsx';
<div className={clsx('base-style', {
  'active': isActive,
  'error': hasError
})}>内容</div>

// React - 使用 CVA(组件变体)
import { cva } from 'class-variance-authority';
const cardVariants = cva('p-4 rounded', {
  variants: {
    variant: {
      default: 'bg-white',
      primary: 'bg-blue-500 text-white'
    }
  }
});
<div className={cardVariants({ variant: 'primary' })}>卡片</div>

6. 生命周期

js 复制代码
// Vue
onMounted(() => {})
onUpdated(() => {})
onUnmounted(() => {})
tsx 复制代码
// React
useEffect(() => {
  // 挂载后执行
  return () => {
    // 卸载时清理
  };
}, []); // 空数组表示只执行一次

7. 表单处理

vue 复制代码
<!-- Vue -->
<input v-model="email" />
<input v-model="password" type="password" />
tsx 复制代码
// React - 原生方式
const [email, setEmail] = useState('');
<input value={email} onChange={(e) => setEmail(e.target.value)} />

// React - 使用 react-hook-form(推荐)
import { useForm } from 'react-hook-form';
const { register, handleSubmit } = useForm();
<input {...register('email', { required: '邮箱必填' })} />
相关推荐
前端大卫35 分钟前
【重磅福利】学生认证可免费领取 Gemini 3 Pro 一年
前端·人工智能
孜燃1 小时前
Flutter APP跳转Flutter APP 携带参数
前端·flutter
脾气有点小暴1 小时前
前端页面跳转的核心区别与实战指南
开发语言·前端·javascript
lxh01131 小时前
最长递增子序列
前端·数据结构·算法
Youyzq2 小时前
前端项目发布到cdn上css被编译失效问题rgba失效和rgb失效
前端·css·算法·cdn
San30.2 小时前
深入 JavaScript 内存机制:从栈与堆到闭包的底层原理
开发语言·javascript·udp
Fantastic_sj2 小时前
Vue3相比Vue2的改进之处
前端·javascript·vue.js
vipbic2 小时前
解决npm publish的404/403和配置警告全记录
前端·npm·node.js
Bigger3 小时前
🚀 “踩坑日记”:shadcn + Vite 在 Monorepo 中配置报错
前端·react.js·vite
ttod_qzstudio4 小时前
深入理解 TypeScript 数组的 find 与 filter 方法:精准查找的艺术
javascript·typescript·filter·find