🚀 用 Nuxt3 打造公司官网:一场从 0 到 1 的实战冒险

🤷‍♂️ 为什么要自己写个官网?

俗话说:"人靠衣装,佛靠金装,公司靠官网装。"

官网是公司的门面,就像是 名片 + 海报 + 展厅 的三合一。

如果官网掉链子,那就像穿着拖鞋去相亲------第一印象直接减分。

我们公司之前的官网,是几年前外包团队做的:

  • 技术栈老得能当"古董";
  • UI 风格满满的 2015 味儿
  • 响应式体验勉强凑合,性能还常常"慢半拍";
  • 更要命的是:每次想加个新功能,都得像修老爷车一样,拧半天螺丝,还不一定能启动。

所以,经过自我的灵魂拷问,最终决定: 👉 "自己动手,丰衣足食"

⚙️ 技术选型:把官网打造成"国际化大别墅"

我们的新官网为什么选 Nuxt3 ?因为它比普通 Vue3 就像 跑车比自行车 (😱💥🤯些许夸张):

  • 快得飞起:内置服务端渲染 + 静态生成,页面秒开不拖拉。
  • 搜索引擎爱它:百度、Google、Bing都抢着认它朋友。
  • 开发起来像开挂:文件路由自动生成、组合式 API、TypeScript 支持,写代码也能"飘起来"。
  • 改版不慌:组件化 + Pinia,团队协作顺畅,维护像玩积木一样轻松。

总结一句:Nuxt3 不只是盖个官网,它帮我们盖了个 智能别墅------炫酷、好用、随时升级。而之前那个老外包官网?嗯......就像老式公寓,住得了,但卡顿掉漆,让人抓狂。

这就是我们选择 Nuxt3 的理由------既要面子,也要里子,还顺便秀了点技术实力。

新官网可不是随便盖盖,我们得满足老板的"国外网站范儿"审美:大气、简洁、有格调。于是技术选型就像挑家具------要好看,还要好用:

  • 国际化支持(i18n):官网得能说多国语言,客户来自世界各地,不然国外的小伙伴看到中文界面估计直接右上角叉掉。但涉及到每个页面元素、按钮文字、提示信息等等,都需要有人去整理、翻译、校对(这是痛苦的过程,无论对于设计、还是对于开发人员);

  • TailwindCSS + Bootstrap:老板喜欢 Bootstrap 的简洁大气,我想用 Tailwind 玩出定制化风格......结果 CSS 冲突就像两只猫抢沙发,互相打架(解决方案在底部)。

  • Element Plus UI:"联系我们"模块中更青睐 Element Plus 表单的优雅交互。

    • 实际用途
      • Bootstrap:用于整体布局和国际化风格,满足老板对"国外网站大气感"的审美。
      • Element Plus:专注于表单控件和交互体验,让用户填写信息更顺畅。
    • 分析与建议
      1. 按需引入:Bootstrap 用于布局和网格,Element Plus 只在表单等必要模块引入。
      2. 避免冲突:两套 UI 样式尽量隔离,统一主题风格,避免界面割裂。
      3. 维护成本:虽然有两套 UI,但只在有限场景使用 Element Plus,维护成本可控。

总结一句:Bootstrap 是"外表帅气",Element Plus 是"功能贴心",两者组合让网站既有颜值又有体验。

  • Pinia(状态管理):严格来说不是必须,但给它留个位置,就像在客厅摆个备用沙发,什么时候需要随时派上用场。

总结一句:新官网就是一栋智能别墅,国际化大门敞开,布局漂亮,UI 风格多样,状态管理随时待命。走进来,你就知道"高级感"不是吹的。

🗂️ Nuxt3 项目结构

1. assets/

  • 存放未编译的静态资源(SASS/LESS、图片、字体)。
  • 不会直接被打包到 /public,需通过 importurl() 使用。

2. components/

  • 存放可复用的 Vue 组件。
  • Nuxt3 支持 自动导入 ,可直接使用components/下定义的组件,自动导入统一把组件名转成 PascalCase 或 kebab-case,同时支持子目录嵌套,比如components/ui/Button.vue → <UiButton /> (😅写惯了组件导入的方式,前期使用的时候都是手动导入,虽然都支持,但既然支持自动导入,尽量使用自动导入)。

3. composables/

  • 存放自定义 Composition API 函数(useXXX)。
  • 用于逻辑复用,例如 useUser()useProduct()

4. layouts/

  • 页面布局模板,例如 default.vuebootstrap.vueadmin.vueempty.vue
  • 页面可通过 definePageMeta({ layout: 'bootstrap' }) 使用不同布局。

5. middleware/

  • 页面或路由守卫逻辑,例如登录验证、权限检查。
  • 可全局或单页面使用。 📝 我们官网暂时不涉及注册登录的逻辑,可能有些公司涉及到产品购物车相关的业务,需要登录验证和权限检查

6. pages/

  • 存放路由页面,自动生成路由
  • 例如 pages/index.vue/pages/about.vue/about。 📝 Nuxt3支持动态路由,[param].vue,比如我的产品详情页目录结构是pages/products/detail/[id].vue

7. plugins/

  • 注册全局插件,如第三方库、全局组件、API 封装。
  • 可选择客户端(xxx.client.ts)、服务端(xxx.server.ts)或两者同时加载(文件名无需 .client 或 .server)。 📝 一般涉及到window、document或者动画相关的都在客户端,访问数据库、文件系统都在服务端,一些工具函数则两端都可。

8. public/

  • 放置静态资源,直接映射到网站根路径。
  • 例如 /favicon.ico/robots.txt,因为官网涉及到很多资源素材,同样也存放在该目录,如图片、视频、字体等。

9. server/

  • Nuxt3 内置服务端目录(Nitro)。
  • server/api/ → REST API 路由,例如 server/api/user.ts/api/user
  • server/plugins/ → 服务端插件,例如数据库连接、日志处理。 📝 讲道理这块我没有用到,因为我搭了一个简单的springboot的后台,直接调用api,包括联系我们的提交和获取商品的列表和明细直接通过封装的api方法去请求,看介绍说server/服务端扩展目录 ,用于自定义 API 和插件。不是必需,尤其是纯前端、静态或只依赖外部API的Nuxt3项目。只有在你需要服务端逻辑(如数据库、日志、缓存、邮件)时,才需要使用,这块有待各位进一步探索,没使用不敢妄言。

10. .nuxt/

  • Nuxt 内部生成目录,存放编译产物和自动生成代码。
  • 不需手动修改,通常加入 .gitignore

11. nuxt.config.ts

nuxt.config.ts 是 Nuxt 3 项目的核心配置文件,负责定义整个项目的全局行为和配置。主要功能包括:

功能模块 说明
🏷️ 页面信息与 HTML Head 配置网站标题、meta 信息、favicon、外部脚本等,确保 SEO 与页面基础信息完整
🎨 全局样式与 PostCSS 配置 引入全局 CSS/SCSS 文件,配置 PostCSS 插件(如 TailwindCSS、Autoprefixer)及自定义选择器前缀,统一样式规范
⚙️ 模块、插件与国际化 配置 Nuxt 模块(Tailwind、Pinia、i18n、Element Plus 等),支持国际化选项,包括语言、浏览器语言检测和消息管理
🌐 运行时环境变量 使用 runtimeConfig 管理开发与生产环境的 API 地址及公共变量,实现环境隔离和安全性
🚀 Vite 构建优化 配置 Vite 插件(如 SVG Loader)、依赖优化、代码拆分等,提高构建速度与性能
🔗 Nitro 服务端开发代理 配置 API 代理,用于本地开发环境调试后端接口,模拟服务端行为

12. package.json

  • 项目依赖与脚本。
  • 常用脚本:
    • dev:开发模式
    • build:打包
    • preview:预览

13.其它(根据个人和项目需要)

  • constants/ 存放项目常量
  • types/ typescript生命定义
  • stores/ pinia modules定义
  • utils/ 工具类和方法
  • directives/ 自定义指令(如数字滚动效果)
  • app.vue 项目入口(全局loading可以在其中实现)
  • .env .env.development .env.production\] 相关环境变量定义

  • tailwind.config.ts tailwindcss配置文件
  • tsconfig.json ts配置文件

📦 Windows 服务器部署 Nuxt3(pm2 + Node.js)

在 Windows 服务器上,我们使用 pm2 运行 Nuxt3 构建后的 .output/server/index.mjs

  • Node.js ≥ 18

  • 全局安装pm2,使用pm2管理项目

🌟 问题及解决方案

Nuxt3 数据请求封装总结

在 Nuxt3 中,useAsyncDatauseFetch$fetch 三者的区别与使用场景总结如下,掌握它们可以避免常见坑。

API 类型 SSR 支持 响应式 内部调用 适用场景
$fetch 请求工具 ✅ 可在 SSR/CSR ❌ 普通 Promise,不响应式 原生 ohmyfetch 灵活调用 API,可在服务端、插件、组合函数中使用
useAsyncData 数据获取组合式 API ✅ SSR 缓存、响应式 ✅ data/pending/error 内部可用 $fetch 获取异步数据并绑定组件,支持 SSR/客户端复用、缓存
useFetch useAsyncData 封装 ✅ 同上 ✅ 同上 内部直接调用 $fetch 简化写法,GET 请求绑定模板最常用

⚠️ 注意:useFetch 本质上是 useAsyncData(() => $fetch(...)) 的语法糖。


TailwindCSS + Bootstrap冲突
xml 复制代码
1. 在 `layouts` 中目录下定义了`bootstrap.vue`,给使用bootstrap布局的区域包一层 `.bootstrap-wrapper.bootstrap-scope`:
```vue
<template>
  <div class="bootstrap-wrapper bootstrap-scope">
    <TheHeader />
    <div class="wrapper">
      <slot />
      <TheFooter />
    </div>
  </div>
</template>
<script setup>
import TheHeader from "~/components/TheHeader.vue";
import TheFooter from "~/components/TheFooter.vue";
</script>
```
2. 配合 PostCSS 插件 `postcss-prefix-selector` 给 Bootstrap 样式加前缀,只作用于 `.bootstrap-wrapper.bootstrap-scope` 内部:
```ts
postcss: {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    "postcss-prefix-selector": {
      prefix: ".bootstrap-wrapper.bootstrap-scope",
      transform(prefix: string, selector: string, prefixedSelector: string): string {
        if (selector === "html" || selector === "body") {
          return `${prefix} ${selector}`;
        }
        return prefixedSelector;
      },
      includeFiles: [/bootstrap-prefixed\.css$/],
    },
  },
},
```
3. Tailwind 保持全局自由发挥,不影响 Bootstrap。`html` 和 `body` 特殊处理,避免基础样式被限制。
  • 效果:两套 CSS 各玩各的,不踩地盘。Tailwind 是"自由派设计师",Bootstrap 是"规矩老板",加个前缀就能让他们和平共处,同时还可以保证布局一致性。

🤔 Reflect

🌟 这是我第一次用 Nuxt3 打造公司官网,整个过程充满了各种曲折与探索。

从配置环境、封装 API,到处理服务端渲染和部署,每一步都像在解谜,踩过不少坑,也学到了很多新技能。

如果文章里有任何不准确或者可优化的地方,非常欢迎大家指正和交流。

希望我的这次实战经验,能给同样第一次尝试 Nuxt3 的你一些参考和启发。

让我们一起探索,让官网不仅上线,更一步步完善成长吧!

相关推荐
@大迁世界9 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路18 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug21 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213823 分钟前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗1 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全
前端工作日常1 小时前
我学习到的AG-UI的概念
前端