首页 > 其他分享 >Next.js 14 基础入门:从项目搭建到核心概念

Next.js 14 基础入门:从项目搭建到核心概念

时间:2024-12-25 17:34:57浏览次数:3  
标签:return 14 app Next tsx js

Next.js 14 带来了许多激动人心的新特性,包括局部渲染、Server Actions 增强等。作为一名前端开发者,我最近在项目中升级到了 Next.js 14,今天就来分享一下从项目搭建到实际应用的完整过程。

项目初始化

首先,让我们创建一个全新的 Next.js 14 项目:

# 使用 create-next-app 创建项目
npx create-next-app@latest my-next-app

在初始化过程中,你会看到以下选项:

✔ Would you like to use TypeScript? Yes
✔ Would you like to use ESLint? Yes
✔ Would you like to use Tailwind CSS? Yes
✔ Would you like to use `src/` directory? Yes
✔ Would you like to use App Router? Yes
✔ Would you like to customize the default import alias? No

目录结构解析

创建完成后,我们来看看项目的核心目录结构:

my-next-app/
├── src/
│   ├── app/
│   │   ├── layout.tsx      # 根布局文件
│   │   ├── page.tsx        # 首页组件
│   │   ├── error.tsx       # 错误处理组件
│        ├── loading.tsx     # 加载状态组件
│   │   └── not-found.tsx   # 404页面组件
│   ├── components/         # 组件目录
│   └── lib/               # 工具函数目录
├── public/                # 静态资源目录
├── next.config.js        # Next.js 配置文件
└── package.json          # 项目依赖配置

App Router 基础

Next.js 14 推荐使用 App Router,它基于 React Server Components,提供了更好的性能和开发体验。

1. 基础路由

// src/app/page.tsx - 首页
export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <h1>Welcome to Next.js 14</h1>
    </main>
  );
}

// src/app/about/page.tsx - 关于页面
export default function About() {
  return (
    <div className="p-24">
      <h1>About Us</h1>
    </div>
  );
}

2. 布局组件

// src/app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <header>
          <nav>{/* 导航栏组件 */}</nav>
        </header>
        <main>{children}</main>
        <footer>{/* 页脚组件 */}</footer>
      </body>
    </html>
  );
}

// src/app/blog/layout.tsx - 博客专属布局
export default function BlogLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="blog-layout">
      <aside className="blog-sidebar">
        {/* 博客侧边栏 */}
      </aside>
      <div className="blog-content">
        {children}
      </div>
    </div>
  );
}

数据获取

Next.js 14 提供了多种数据获取方式,默认都是基于 Server Components:

1. 服务端获取数据

// src/app/posts/page.tsx
async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: {
      revalidate: 3600 // 1小时重新验证一次
    }
  });
  
  if (!res.ok) {
    throw new Error('Failed to fetch posts');
  }
  
  return res.json();
}

export default async function Posts() {
  const posts = await getPosts();
  
  return (
    <div className="posts-grid">
      {posts.map(post => (
        <PostCard key={post.id} post={post} />
      ))}
    </div>
  );
}

2. 动态路由数据获取

// src/app/posts/[id]/page.tsx
async function getPost(id: string) {
  const res = await fetch(`https://api.example.com/posts/${id}`, {
    cache: 'no-store' // 禁用缓存,始终获取最新数据
  });
  
  if (!res.ok) {
    throw new Error('Failed to fetch post');
  }
  
  return res.json();
}

export default async function Post({
  params: { id }
}: {
  params: { id: string }
}) {
  const post = await getPost(id);
  
  return (
    <article className="post-detail">
      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}

Server Actions

Next.js 14 增强了 Server Actions,让表单处理变得更简单:

// src/app/posts/new/page.tsx
export default function NewPost() {
  async function createPost(formData: FormData) {
    'use server';
    
    const title = formData.get('title');
    const content = formData.get('content');
    
    // 服务端验证
    if (!title || !content) {
      throw new Error('Title and content are required');
    }
    
    // 直接在服务端处理数据
    await db.post.create({
      data: {
        title: title as string,
        content: content as string,
      },
    });
    
    // 重定向到文章列表
    redirect('/posts');
  }
  
  return (
    <form action={createPost}>
      <input type="text" name="title" placeholder="文章标题" />
      <textarea name="content" placeholder="文章内容" />
      <button type="submit">发布文章</button>
    </form>
  );
}

客户端组件

虽然 Server Components 是默认的,但有时我们需要客户端交互:

// src/components/Counter.tsx
'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

元数据配置

Next.js 14 提供了强大的元数据 API:

// src/app/layout.tsx
import { Metadata } from 'next';

export const metadata: Metadata = {
  title: {
    template: '%s | My Next.js App',
    default: 'My Next.js App',
  },
  description: 'Built with Next.js 14',
  openGraph: {
    title: 'My Next.js App',
    description: 'Built with Next.js 14',
    images: ['/og-image.jpg'],
  },
};

// src/app/blog/[slug]/page.tsx
export async function generateMetadata({
  params
}: {
  params: { slug: string }
}): Promise<Metadata> {
  const post = await getPost(params.slug);
  
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [post.coverImage],
    },
  };
}

静态资源处理

Next.js 14 优化了图片和字体的处理:

// src/components/ProfileImage.tsx
import Image from 'next/image';

export default function ProfileImage() {
  return (
    <Image
      src="/profile.jpg"
      alt="Profile"
      width={200}
      height={200}
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,..."
      priority
    />
  );
}

// src/app/layout.tsx
import { Inter } from 'next/font/google';

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
});

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

环境配置

Next.js 14 支持多环境配置:

# .env.local
DATABASE_URL="postgresql://..."
API_KEY="your-api-key"

# .env.production
NEXT_PUBLIC_API_URL="https://api.production.com"

# .env.development
NEXT_PUBLIC_API_URL="http://localhost:3000"

使用环境变量:

// src/lib/db.ts
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;

// 客户端也可以使用 NEXT_PUBLIC_ 前缀的环境变量
console.log(process.env.NEXT_PUBLIC_API_URL);

错误处理

Next.js 14 提供了完善的错误处理机制:

// src/app/error.tsx
'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  return (
    <div className="error-container">
      <h2>Something went wrong!</h2>
      <p>{error.message}</p>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

// src/app/not-found.tsx
export default function NotFound() {
  return (
    <div className="not-found">
      <h2>404 - Page Not Found</h2>
      <p>Could not find requested resource</p>
    </div>
  );
}

开发调试

Next.js 14 改进了开发体验:

// 使用 React Developer Tools
import { useDebugValue } from 'react';

function useCustomHook() {
  const value = // ... 一些计算
  
  // 在 React DevTools 中显示自定义值
  useDebugValue(value, value => `Custom: ${value}`);
  
  return value;
}

// 使用 next.config.js 配置开发环境
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  // 启用详细的构建输出
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
  // 配置重写规则
  rewrites: async () => {
    return [
      {
        source: '/api/:path*',
        destination: 'http://localhost:3001/api/:path*',
      },
    ];
  },
};

module.exports = nextConfig;

写在最后

Next.js 14 带来了许多激动人心的新特性,特别是在性能优化和开发体验方面有了显著提升。这篇文章介绍的只是基础功能,在实际项目中,你还可以:

  1. 使用 Middleware 进行路由控制
  2. 配置国际化路由
  3. 实现增量静态再生成(ISR)
  4. 使用 Edge Runtime 优化性能
  5. 集成各种第三方服务

在接下来的系列文章中,我们会深入探讨这些进阶主题。如果你对某个特定主题特别感兴趣,欢迎在评论区告诉我!

如果觉得这篇文章对你有帮助,别忘了点个赞

标签:return,14,app,Next,tsx,js
From: https://www.cnblogs.com/yuanyanglu/p/18630998

相关文章

  • node.js毕设 zwhy电子竞技战队管理系统 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于电子竞技战队管理系统的研究,现有研究主要以电竞产业发展、赛事运营等宏观方面为主,专门针对战队内部管理系统的研究较少。在国内外,电竞产业蓬勃发展,......
  • node.js驾校管理系统程序+论文 可用于毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景在现代社会,随着汽车保有量的不断增加,驾校行业蓬勃发展,驾校管理的高效性和科学性成为重要议题。关于驾校管理系统的研究,现有研究主要以传统管理模式的优......
  • 华为鸿蒙HarmonyOS Next基础开发教程
    华为鸿蒙HarmonyOSNext基础开发教程1.开发环境准备安装DevEcoStudioDevEcoStudio是华为为HarmonyOS应用开发提供的集成开发环境(IDE)。您可以从华为的官方网站下载并安装DevEcoStudio。配置开发环境确保您的计算机上安装了以下软件:JDK:Java开发工具包,用于支持Java语言开......
  • js中的可选链语法在node12的时候报错了
    JavaScript的可选链(optionalchaining)语法是在ECMAScript2020(ES11)中引入的,它允许你安全地访问嵌套对象属性,即使某个中间属性不存在也不会抛出错误。然而,在Node.js环境中,不同版本对新特性的支持情况有所不同。Node.js对ES特性的支持Node.js12.x系列发布于2019年......
  • main.js
    import{createApp}from'vue'//引入elementPlusjs库css库importElementPlusfrom'element-plus'import'element-plus/dist/index.css'//中文语言包importzhCnfrom'element-plus/es/locale/lang/zh-cn'//图标库import*asEl......
  • 【华为OD-E卷-最小调整顺序次数、特异性双端队列 100分(python、java、c++、js、c)】
    【华为OD-E卷-最小调整顺序次数、特异性双端队列100分(python、java、c++、js、c)】题目有一个特异性的双端队列,该队列可以从头部或尾部添加数据,但是只能从头部移出数据。小A依次执行2n个指令往队列中添加数据和移出数据。其中n个指令是添加数据(可能从头部添加、也可能从......
  • 【华为OD-E卷-取出尽量少的球 100分(python、java、c++、js、c)】
    【华为OD-E卷-取出尽量少的球200分(python、java、c++、js、c)】题目某部门开展FamilyDay开放日活动,其中有个从桶里取球的游戏,游戏规则如下:有N个容量一样的小桶等距排开,且每个小桶都默认装了数量不等的小球,每个小桶装的小球数量记录在数组bucketBallNums中,游戏开......
  • 【开源免费】基于SpringBoot+Vue.JS学生评奖评优管理系统(JAVA毕业设计)
    本文项目编号T096,文末自助获取源码\color{red}{T096,文末自助获取源码}......
  • 【开源免费】基于SpringBoot+Vue.JS植物健康系统(JAVA毕业设计)
    本文项目编号T095,文末自助获取源码\color{red}{T095,文末自助获取源码}......
  • RTSP播放器EasyPlayer.js遇到Android播放器修复播放画面卡在第一帧问题
    在数字化时代,流媒体技术已经成为信息传播和娱乐消费的重要方式。随着互联网技术的飞速发展和移动设备的普及,流媒体服务正在重塑我们的生活和工作方式。从视频点播、在线直播到音乐流媒体,流媒体技术的广泛应用不仅改变了内容的分发和消费模式,也为内容创作者和消费者提供了前所未有......