搭建nuxt3项目(框架构建)
需求
目标:我想搭建一个nuxt3的框架,实现一些基本的组件和路由、页面,方便后续遇到相关ssr项目直接复用。
同时:记录关于nuxt3的使用介绍
关于Nuxt(详解以及周边)
Nuxt 框架
1、一种基于 Node.js 的服务端渲染方案 SSR(Server Side Rendering)支持 Vue 应用、服务器端渲染、提高页面的加载速度和 SEO
工作原理:1、服务端渲染:Nuxt.js 在服务器端执行 Vue 组件的渲染过程,并生成初始 HTML2、客户端激活:一旦初始 HTML 被发送到浏览器,Vue.js 会接管页面,并在客户端激活成一个交互式应用程序。
Nuxt 优势
SPA 和 SSR 是什么?1、SPA(Single Page Application)单页面应用,在客户端通过 JS 动态地构建页面。优势:页面切换流畅,动态渲染变化,用户体验好,搜索引擎的支持不够友好。适用企业内部项目,如管理平台。2、SSR(Server-Side Rendering)服务器端渲染,在服务器端生成 HTML 页面并发送给客户端。优势:对搜索引擎友好,页面首次加载速度快 和 SEO,页面切换可能不够流畅(每次都是请求一个完整的 HTML 页面)适用官网,对 SEO 搜索友好。3、Nuxt 框架Nuxt 采用了混合的架构模式,可以同时支持 SSR 和 SPA。首次访问页面是 SSR 方式,也就是在服务器端生成 HTML 页面并发送给客户端后续的页面切换则使用 SPA 的方式进行,从而兼顾了 SSR 和 SPA 的优点。场景:企业网站、商品展示 等 C 端网站,对 SEO 搜索更友好,且页面切换流畅,用户体验更好
项目搭建
1、安装项目命令和报错分析
npx nuxi init <project-name>

错误分析
1、安装报以上错误(其原因是大陆访问受限)
2、但是我开了代理也一样下载不下来
3、从官网issue159:原因是脚手架node程序没有走代理
错误解决方案
1、官网zip

2、在终端添加host代理,进行DNS域名映射
mac修改方式如下:
sudo vi /etc/hosts
输入 i 进入编辑模式,编辑完成后按 Esc后:wq 保存退出添加
185.199.108.133 raw.githubusercontent.com
Windows修改host参考:修改本地host代理

运行
npm run dev
or
npm i
npm run dev

目录以及初始化
1、先来理解下目录
├─.nuxt 非工程代码,存放运行或发行的编译结果
├─node_modules 项目依赖
├─public 网站资源目录
├─server 接口目录
├─.gitignore git 忽略文件
├─.npmrc npm 配置文件
├─app.vue 根组件
├─nuxt.config.ts nuxt 配置文件
├─package.json 项目配置文件
├─README.md 项目说明文件
└─tsconfig.json ts 配置文件
2、nuxt 有一些约定的目录,有特殊功能,如 pages 目录的 vue 文件会自动注册路由。
├─ pages 页面目录,自动注册路由
Nuxt.js 自带路由功能,不需要额外安装和配置,无需安装 vue-router 。
├─ pages 页面目录,自动注册路由
│ └─index.vue 主页
│ └─user.vue 用户页
├─app.vue 根组件
测试一下
<template><!-- 路由链接 --><NuxtLink to="/">首页</NuxtLink><NuxtLink to="/user">用户页</NuxtLink><!-- 路由占位 --><NuxtPage />
</template>
// <NuxtPage> 相当于 <RouterView>
// <NuxtLink> 相当于 <RouterLink>

### SEO 优化
实现:
通过设置网页 title 和 description 等 SEO 优化信息,由服务端渲染
SEO and Meta
// 在app.vue中新增
<script setup lang="ts">
// SEO 优化
useSeoMeta({title: 'demo - 找工作|博客|提升',description:'求职之前,需要有经验,技术。祝愿大家找到好工作,拿到好offer。',author: '卡卡——程序员',
})
</script>
组件库和vw适配
安装 nuxt 版 vant-ui
npm i @vant/nuxt
nuxt.config.ts添加配置
// https://nuxt.com/docs/api/configuration/nuxt-config
// PS: 在 Nuxt 项目中,vant 组件会自动按需导入(需重启)
export default defineNuxtConfig({devtools: { enabled: false },modules: ['@vant/nuxt'],
})
index.vue测试
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
vw 适配
安装
npm i postcss-px-to-viewport
nuxt.config.ts添加配置
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({devtools: { enabled: false },modules: ['@vant/nuxt'],// 移动端适配postcss: {plugins: {'postcss-px-to-viewport': {viewportWidth: 375,},},},
})
页面效果px会转化为vw

路由配置
自动路由
在 pages 目录的 vue 文件会自动注册路由,创建以下vue文件
登录页 login.vue
注册页 register.vue
文章详情页 detail.vue
文章(TabBar)article.vue
收藏(TabBar)collect.vue
喜欢(TabBar)like.vue
我的(TabBar)user.vue
路由中间件
新建 middleware 目录,通过 Nuxt 路由中间件实现路由重定向,包括导航守卫等路由功能。
export default defineNuxtRouteMiddleware((to, from) => {// 首页重定向if (to.path === '/') {return navigateTo('/article')}
})

layouts 布局
目标:我们想在首页底部实现TabBar导航栏
通过 layout 实现布局的复用,新建文件 layouts/tabbar.vue
// route 开启路由模式
// to 跳转路由
<template><div class="layout-page"><!-- 插槽 --><slot /><!-- tabbar --><van-tabbar route><van-tabbar-item to="/article" icon="notes-o">面经</van-tabbar-item><van-tabbar-item to="/collect" icon="star-o">收藏</van-tabbar-item><van-tabbar-item to="/like" icon="like-o">喜欢</van-tabbar-item><van-tabbar-item to="/user" icon="user-o">我的</van-tabbar-item></van-tabbar></div>
</template>
页面中使用 layout 布局
article.vue
<template><NuxtLayout name="tabbar"><h1>文章首页</h1></NuxtLayout>
</template>
为这几个路由分别配置

修改主题色
在 app.vue 的样式全局生效。
<style>
:root {--van-primary-color: #fa6d1d !important;
}
</style>

注册页
直接复用、一些基础vant组件使用
<template><div class="register-page"><!-- 导航栏部分 --><van-nav-bar title="用户注册" /><!-- 一旦form表单提交了,就会触发submit,可以在submit事件中根据拿到的表单提交信息,发送axios请求--><van-form @submit="onSubmit"><!-- 输入框组件 --><!-- \w 字母数字_ \d 数字0-9 --><van-fieldv-model="form.username"name="username"label="用户名"placeholder="用户名":rules="[{ required: true, message: '请填写用户名' },{ pattern: /^\w{5,}$/, message: '用户名至少包含5个字符' },]"/><van-fieldv-model="form.password"type="password"name="password"label="密码"placeholder="密码":rules="[{ required: true, message: '请填写密码' },{ pattern: /^\w{6,}$/, message: '密码至少包含6个字符' },]"/><div style="margin: 16px"><van-button block type="primary" native-type="submit">注册</van-button></div></van-form><NuxtLink class="link" to="/login">已注册,去登录</NuxtLink></div>
</template><script setup lang="ts">
// 表单数据
const form = reactive({username: 'admin',password: '123456',
})// 表单提交
const onSubmit = async () => {//
}
</script><style scoped>
.link {color: #069;font-size: 12px;padding-right: 20px;float: right;
}
</style>
请求封装axios
安装 axios,登录请求可用 axios 发送。
npm i axios
新建 utils/request.ts 封装 axios 模块
nuxt3 utils模块

/* 封装axios用于发送请求 */import axios, { AxiosResponse } from 'axios'const service = axios.create({baseURL: 'http://interview-api-t.itheima.net/h5',timeout: 90000,
})
const request = (config: any) => {
// if (getToken()) {
// config.headers['csrf-token'] = getToken()
// }if (config.cType) {config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'}return config
}const requestError = (error: any) => {console.error(error)return Promise.reject(error)
}const response = (response: AxiosResponse) => {return response.data
}const responseError = async (error: any) => {if (error.response.status === 403) {showFailToast('登录过期')navigateTo('/login')return Promise.reject(error)}if (error.response.data.code === 400) {showFailToast(error.response.data.message)return Promise.reject(error)}if (error.response.status === 500) {// No permissionreturn Promise.reject(error)}return Promise.reject(error)
}service.interceptors.request.use(request, requestError)
service.interceptors.response.use(response, responseError)export default service
// register.vue 表单提交调用接口
// 表单提交
const onSubmit = async () => {// 注册请求await request({method: 'POST',url: '/user/register',data: form,})// 成功提示showSuccessToast('注册成功')// 跳转页面navigateTo('/login')
}
持久化存储 use-cookie
注意:Nuxt 服务器端不支持 localStorage 所以运行会报错,可通过 cookie 代替。
而且Nuxt支持 useCookie API存储cookie
在util中新建cookie.ts
const KEY = 'key'// 获取
export const getToken = () => {return useCookie(KEY).value
}// 设置
export const setToken = (newToken: string) => {useCookie(KEY, { maxAge: 60 * 60 * 24 * 14 }).value = newToken
}// 删除
export const delToken = () => {useCookie(KEY).value = undefined
}
登录页逻辑
<script setup lang="ts">
// 表单数据
const form = reactive({username: 'admin111',password: '123456',
})// 表单提交
const onSubmit = async () => {// 登录请求const res = await request({method:"post",url:'/user/login',data:form})// 保存 tokensetToken(res.data.token)// 成功提示showSuccessToast('登录成功')// 跳转页面navigateTo('/', {replace: true})
}
</script><template><div class="login-page"><!-- 导航栏部分 --><van-nav-bar title="用户登录" /><!-- 一旦form表单提交了,就会触发submit,可以在submit事件中根据拿到的表单提交信息,发送axios请求--><van-form @submit="onSubmit"><!-- 输入框组件 --><!-- \w 字母数字_ \d 数字0-9 --><van-fieldv-model="form.username"name="username"label="用户名"placeholder="用户名":rules="[{ required: true, message: '请填写用户名' },{ pattern: /^\w{5,}$/, message: '用户名至少包含5个字符' },]"/><van-fieldv-model="form.password"type="password"name="password"label="密码"placeholder="密码":rules="[{ required: true, message: '请填写密码' },{ pattern: /^\w{6,}$/, message: '密码至少包含6个字符' },]"/><div style="margin: 16px"><van-button block type="info" native-type="submit">提交</van-button></div></van-form><NuxtLink class="link" to="/register">注册账号</NuxtLink></div>
</template><style scoped>
.link {color: #069;font-size: 12px;padding-right: 20px;float: right;
}
</style>
路由鉴权-导航守卫
Nuxt 有路由中间件,简化了导航守卫的实现。use-router
// middleware下的route.global.ts
// 白名单列表,记录无需权限访问的所有页面
const whiteList = ['/login', '/register']export default defineNuxtRouteMiddleware((to, from) => {// 首页重定向if (to.path === '/') {return navigateTo('/article')}// 获取 tokenconst token = getToken()if (!token && !whiteList.includes(to.path)) {return navigateTo('/login')}
})
渲染页面-封装useFetch 通过 useFetch 发送请求
为什么封装useFetch发送请求?
1、服务端先渲染静态页面,axios请求接收到数据需要客户端进行渲染页面。
2、useFetch发送的请求直接在服务端处理好,随着页面一起回来。利于seo
// 注意、函数组件都不用引入,可以直接使用,但type类型需要导入才能使用
export const useRequest = async (url: string,options?: any) => {const { data, error } = await useFetch(url, {baseURL: 'http://interview-api-t.itheima.net/h5/',headers: {Authorization: `Bearer ${getToken()}`,},...options,})if (error.value) {return Promise.reject(error)} else {return data.value.data}
}
补充

其中 [id].vue 表示动态路由为detail/:id的路由
git 地址
相关文章:
搭建nuxt3项目(框架构建)
需求 目标:我想搭建一个nuxt3的框架,实现一些基本的组件和路由、页面,方便后续遇到相关ssr项目直接复用。 同时:记录关于nuxt3的使用介绍关于Nuxt(详解以及周边) Nuxt 框架 1、一种基于 Node.js 的服务端…...
系统架构设计之微内核架构(Microkernel Architecture)
微内核架构(Microkernel Architecture) 一. 什么是微内核架构二. 微内核架构风格-拓扑结构三. 微内核的核心系统设计的三个关键点3.1 插件管理3.2 插件连接3.3 插件通信 四. 微内核架构的优缺点 一. 什么是微内核架构 微内核架构是一种面向功能进行拆分的…...
51单片机实现换能器超声波测水深
一,超声波换能器定义: 定义1:可把电能、机械能或声能从一种形式转换为另一种形式的能的装置。 所属学科:测绘学下的测绘仪器。 定义2:能量转换的器件。在水声领域中常把声呐换能器、水声换能器、电声换能器统称换能器。…...
Spring Cloud Config
Spring Cloud Config 服务端:一个集中化配置中心,可以是一个独立的服务,也可以注册到服务治理中心,它可以集中管理各个 微服务的配置; 作用原理是从某个地方读取(本地/云端)提供给其客户端作为配置; 客户端:作为一个服务端,通过读取Config的服务端来获取自己的配置文件; 服务…...
易基因: Nature Biotech:番茄细菌性青枯病的噬菌体联合治疗|国人佳作
大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 生物防治是利用细菌接种剂来改变植物根际微生物群落的组成,但在以往研究中存在有接种的细菌在根际建立不良,与本地微生物组争夺资源,干扰本地微生物的…...
震坤行亮相2023工博会,并荣获第23届中国工博会“CIIF信息技术奖”
震坤行亮相2023工博会,并荣获第23届中国工博会“CIIF信息技术奖” 2023年9月19日,2023年第23届中国国际工业博览会CIIF(以下简称“工博会”)在上海国家会展中心盛大开幕。震坤行紧跟智能制造产业发展步伐,携数字化解决…...
灯带代码实现
#include "FastLED.h" // FastLED库#define NUM_LEDS 60 // LED灯珠数量 #define DATA_PIN 3 // Arduino输出控制信号引脚 #define LED_TYPE WS2812 // LED灯带型号 #define COLOR_ORDER GRB // RGB灯珠中红色、…...
Monocular arbitrary moving object discovery and segmentation 论文阅读
基本信息 题目:Monocular Arbitrary Moving Object Discovery and Segmentation 作者: 来源:BMVC 时间:2021 代码地址:https://github.com/michalneoral/Raptor Abstract 我们提出了一种发现和分割场景中独立移动的…...
ROS | 命名空间
文章目录 概述一、定义介绍二、原理解读1.命名空间2.调用规则概述 本节详细介绍了ROS中的命名空间机制原理和使用。 一、定义介绍 在ROS(Robot Operating System)中,命名空间是一种用于组织和区分节点、话题、服务和参数等资源的层次结构。命名空间使用斜线(/)作为分隔符…...
【中国数据】中国基础矢量数据(shp格式)
数据目录 数据举例 数据获取 专栏分享常用的地理空间数据,包括矢量数据、栅格数据、统计数据等,订阅专栏后,从私信查收专栏完整数据包,持续同步更新。...
Docker:创建主从复制的Redis集群
一、Redis集群 在实际项目里,一般不会简单地只在一台服务器上部署Redis服务器,因为单台Redis服务器不能满足高并发的压力,另外如果该服务器或Redis服务器失效,整个系统就可能崩溃。项目里一般会用主从复制的模式来提升性能&#x…...
c++ 智能指针
1. 起源 c++ 把内存的控制权对开发人员开放,让程序显式的控制内存,这样能够快速的定位到占用的内存,完成释放的工作。但是这样也会引发一些问题,也就是普通指针的隐患: 1.1 野指针 出现野指针的有几个地方 : 指针声明而未初始化,此时指针的将会随机指向内存已经被释放…...
【vue3】依赖注 provide、inject(父组件与儿子、孙子、曾孙子组件之间的传值)
一、基本用法: //父组件 import { ref, provide } from vue const radio ref<string>(red) provide(myColor,radio) //注入依赖//儿子组件、孙子组件、曾孙子组件 import { inject } from vue import type { Ref } from vue; const myColor inject<Ref&l…...
docker 部署tig监控服务
前言 tig对应的服务是influxdb grafana telegraf 此架构比传统的promethus架构更为简洁,虽然influxdb开源方案没有集群部署,但是对于中小型服务监控需求该方案简单高效 本文以docker-compose来演示这套监控体系的快速搭建和效果。 部署 docker-compos…...
ETL工具与数据处理的关系
ETL工具与数据处理之间存在密切的关系。数据处理是指对原始数据进行清洗、整理、加工和分析等操作,以便生成有用的信息和洞察力。而ETL工具则提供了一种自动化和可视化的方式来执行这些数据处理任务。通过ETL工具,用户可以定义数据抽取、转换和加载的规则…...
Flink几个性能调优
1 配置内存 操作场景 Flink是依赖内存计算,计算过程中内存不够对Flink的执行效率影响很大。可以通过监控GC(Garbage Collection),评估内存使用及剩余情况来判断内存是否变成性能瓶颈,并根据情况优化。 监控节点进程的…...
后端工程进阶| 青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天 并发编程 协程Goroutine通道Channel锁Lock 并发基础 串行程序与并发程序:串行程序特指只能被顺序执行的指令列表,并发程序则是可以被并发执行的两个及以上的串行程序的综合体。并发程序与并行程序…...
EPPlus库的安装和使用 C# 中 Excel的导入和导出
安装 工具栏->NuGet 包管理器->管理解决方案的NuGet程序包 安装到当前项目中 使用 将 DataGridView 数据导出为Excel 首先,需要将数据DataGridView对象转换为DataTable private void btnExport_Click(object sender, EventArgs e) {// 1.将当前页面的data…...
深度学习使用Keras进行迁移学习提升网络性能
上一篇文章我们用自己定义的模型来解决了二分类问题,在20个回合的训练之后得到了大约74%的准确率,一方面是我们的epoch太小的原因,另外一方面也是由于模型太简单,结构简单,故而不能做太复杂的事情,那么怎么提升预测的准确率了?一个有效的方法就是迁移学习。 迁移学习其…...
越流行的大语言模型越不安全
源自:GoUpSec “人工智能技术与咨询” 发布 安全研究人员用OpenSSF记分卡对GitHub上50个最流行的生成式AI大语言模型项目的安全性进行了评估,结果发现越流行的大语言模型越危险。 近日,安全研究人员用OpenSSF记分卡对GitHub上50个最流…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
