nuxt3实战:完整的 nuxt3 + vue3 项目创建与useFetch请求封装

一. 安装

pnpm dlx nuxi@latest init <project-name>// ornpx nuxi@latest init <project-name>
  • 如遇到报错
    在这里插入图片描述

手动安装:

  1. 浏览器访问报错https请求地址:
    在这里插入图片描述

  2. 点击tar(项目初始文件的下载地址)对应地址,下载starter-3.tar.gz 包到本地

  3. 本地创建项目文件,将压缩包解压到项目文件内

  4. 安装依赖pnpm i / npm install

  5. 启动项目pnpm dev

二. 服务端和客户端

1. 对比vite项目运行和nuxt项目运行`:
  1. vite
    在这里插入图片描述

  2. nuxt
    在这里插入图片描述

  3. nuxt运行在浏览器
    在这里插入图片描述

  4. 总结:
    - vite创建项目,浏览器访问,返回模板html
    - nuxt创建项目,浏览器访问,请求返回渲染后的html, 输出先是服务端渲染的1111,后是客户端的1111

2. 区分serverclient
const runtimeConfig = useRuntimeConfig()
if (runtimeConfig.apiSecret) {console.log('server');
} else {console.log('clint');
}

或者

if (import.meta.server) {console.log('server');
} else {// import.meta.clientconsole.log('clint');
}

三. 基础配置nuxt.config.ts

1. 环境变量和私有令牌
export default defineNuxtConfig({runtimeConfig: {// 只在服务器端可用的私有键apiSecret: '123',// public中的键也可以在客户端使用public: {apiBase: '/api'}}
})

或者

# 这将覆盖apiSecret的值
NUXT_API_SECRET=api_secret_token

这些变量通过useRuntimeConfig()组合函数暴露给应用程序的其余部分。

<script setup lang="ts">
const runtimeConfig = useRuntimeConfig()
</script>
2. 全局样式导入

有一个 sass部分 文件,其中包含颜色变量,供你的Nuxt 页面 和 组件 使用。

$primary: #49240F;
$secondary: #E4A79D;
export default defineNuxtConfig({// css:['~/assets/css/base.scss'],// 或者vite: {css: {preprocessorOptions: {scss: {additionalData: '@use "@/assets/_colors.scss" as *;'}}}}
})
3. 引入element-plus

安装

npm i element-plus @element-plus/nuxt -D
modules: ['@element-plus/nuxt'],

四、路由

1. 创建pages文件夹,内部的.vue文件会自动被创建为路由
  // 路由入口 相当于 router-link<NuxtLink to="/">首页</NuxtLink>// 路由容器, 相当于 router-view<NuxtPage />
2. 命名路由
  • [id].vue一个中括号包裹的文件名,将匹配一个参数化的路由。
  <NuxtLink to="/product/123">产品</NuxtLink><NuxtPage />
  • product/[id].vue
const route = useRoute()
console.log(route.params);
3. 可选路由
  • [[test]] / myTest.vue 两个中括号包裹文件夹名。内部.vue路由访问时test可省略
<NuxtLink to="/test/myTest">可选路由1</NuxtLink><br>
<NuxtLink to="/myTest">可选路由2</NuxtLink>
4. 全局路由
  • [...404].vue 一个中括号...加文件名
5. definePageMeta为你的页面组件定义元数据。
  • login.vue
definePageMeta({path: '/login1'
})
  • 访问login会跳转404login1则会跳转login
6. 嵌套路由
  • user.vue同级创建user文件夹,user文件夹内路由为user.vue的子路由

在这里插入图片描述

7. 编程路由

navigateTo在服务器端和客户端均可使用。

if (import.meta.server) {navigateTo('/login1')
}
// navigateTo('/login1')
8. 路由中间件
  1. 创建middleware文件夹,内部创建my-middleware.ts,
export default defineNuxtRouteMiddleware((to, from) => {console.log("my-middleware", to.path);// // 在实际应用中,你可能不会将每个路由重定向到 `/`// // 但是在重定向之前检查 `to.path` 是很重要的,否则可能会导致无限重定向循环if (to.path === "/about") {return navigateTo("/user");}
});
  1. 页面使用about.vue
definePageMeta({middleware: ['my-middleware']
})
  1. 全局中间件: test.global.ts,必须global结尾
export default defineNuxtRouteMiddleware((to, from) => {console.log("全局中间件", to.path);
});
9. 导航守卫
export default defineNuxtRouteMiddleware((to, from) => {// console.log("全局中间件", to.path);const whiteList = ['/index', '/login', '/404', '/']if(!whiteList.includes(to.path)){let token = ''if(import.meta.client){token = localStorage.getItem('token') || ''} if(!token){return navigateTo({path: '/login',query: { code: 401,message: '请先登录'}});}}
});
onMounted(() => {const route = useRoute()if (route.query.code === '401') {ElMessage.error(route.query.message as string)}
})

五. 目录结构

  1. components目录是你放置所有 Vue 组件的地方。

Nuxt 会自动导入该目录中的所有组件

  1. 使用composables目录将你的Vue组合式函数自动导入到你的应用程序中
export const useFoo = () => {return useState('foo', () => 'bar')
}
<script setup lang="ts">
const foo = useFoo()
</script><template><div>{{ foo }}</div>
</template>

默认导出可使用驼峰文件名进行访问

  1. 使用utils目录在整个应用程序中自动导入你的工具函数。使用当时同composables

六、请求

<script setup lang="ts">
// 在SSR中数据将被获取两次,一次在服务器端,一次在客户端。
const dataTwice = await $fetch('/api/item')// 在SSR中,数据仅在服务器端获取并传递到客户端。
const { data } = await useAsyncData('item', () => $fetch('/api/item'))// 你也可以使用useFetch作为useAsyncData + $fetch的快捷方式
const { data } = await useFetch('/api/item')
</script>
  • 完整request.ts
/*** @description  useFetch* */
import type { NitroFetchRequest } from 'nitropack';const apiRequest = <T>(url:NitroFetchRequest, options: any): Promise<ResultData<T>> => {const config = useRuntimeConfig();const nuxtApp = useNuxtApp()const contentType =  options.contentType ||  'application/json'return new Promise((resolve, reject) => {useFetch<ResultData<T>>(url, {baseURL: config.public.baseURL,onRequest({ options }) {let token = "";if (import.meta.client) {token = useStore().getToken();}options.headers = {'Content-Type': contentType,'Cookies': `token=${token}`,...options.headers,};},onResponse({ response }) {if(response.status >= 200 && response.status < 300){if(response._data.code === 200){resolve(response._data)} else {if(import.meta.client){ElMessage.error(response._data.msg)} else {nuxtApp.runWithContext(()=>{navigateTo({path: '/Error',query:{code: response._data.code,message: response._data.msg}})})}}}},onResponseError({ response }) {if(import.meta.client){ElMessage.error(response._data.msg)} else {nuxtApp.runWithContext(()=>{navigateTo({path: '/Error',query:{code: response._data.code,message: response._data.msg}})})}},...options});});};interface Result {code: string;msg: string;
}interface ResultData<T = any> extends Result {data: T;
}export const getApi = <T>(url:NitroFetchRequest, options: any = {}): Promise<ResultData<T>> => {return apiRequest(url, {method: 'GET',...options})
}export const postApi = <T>(url:NitroFetchRequest, options: any = {}): Promise<ResultData<T>> => {return apiRequest(url, {method: 'POST',...options})
}
  • [[Error]] / index.vue
<script setup lang="ts">
onMounted(() => {const route = useRoute();switch (route.query.code) {case '401':ElMessage.error('no login')localStorage.removeItem('token')break;case '501':ElMessage.error('Unknown error' + route.query.message)break;default:ElMessage.error(route.query.code + '' + route.query.message)}
})
</script>
  • 调用接口
// template
<p v-for="item in list" :key="item.id">{{ item.name }}</p>// script
const list = ref<Info[]>()
interface Info {id: number;name: string
}interface List {list: Info[],page: number;total: number;
}
const handleClick = async () => {const { data } = await getApi<List>('/list')list.value = data.list
}

七、pinia

  1. 安装pinia
pnpm install pinia @pinia/nuxt
  1. 配置nuxt.config.ts
modules: ['@pinia/nuxt',
],
  1. 持久化配置
  • 安装
pnpm i -D @pinia-plugin-persistedstate/nuxt
modules: ['@pinia-plugin-persistedstate/nuxt',
],// 默认存在cookies
// piniaPersistedstate: {
//   storage: 'localStorage'
// },

八、 nuxt错误处理

  1. app.vue同级创建error.vue
<script setup lang="ts">defineProps({error: Object
})clearError({ redirect: '/login' })
</script>
  1. index.vue
throw createError({ statusCode: 404, message: '404 not found' })
  1. 错误只能从服务端触发

九、SEO优化

useHead函数用于自定义Nuxt应用中单个页面的头部属性。

useHead({// title: 'my login',meta: [{name: 'description',content: 'my login description'},{name: 'keywords',content: 'my login keywords'},],// titleTemplate: (titleChunk) => {//   return titleChunk ? `${titleChunk} - my login` : 'my login'// }titleTemplate: `%s ${name.value}`}
)

十、layout布局

  • layout目录下创建default.vue
<template><div><p>一些在所有页面之间共享的默认布局内容</p><slot /></div>
</template>
  • app.vue页面使用layout
<template><NuxtLayout><NuxtPage /></NuxtLayout>{/* <NuxtLayout :name="其他layout"><NuxtPage /></NuxtLayout> */}
</template>
  • login.vue页面不使用layout
definePageMeta({layout: false
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/395080.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AskYourDatabase v1.1.83 使用人工智能连接您的数据库并与您的数据聊天

AskYourDatabase 是一个创新的 平台 它允许用户直接连接到您的数据库并与您的数据聊天 。这个革命性的工具使用人工智能来提供答案和分析&#xff0c;日常开发中可以用来帮助开发者编写sql脚本&#xff0c;分析数据结构等。支持市面上流行的数据库。后端数据库开发的又一利器&a…

Go语言加Vue3零基础入门全栈班15 gin+gorm+vue3用户管理系统实战录播课 2024年08月04日 课程笔记

预览 登录页面&#xff1a; 首页&#xff1a; 用户列表&#xff1a; 新增用户&#xff1a; 删除用户&#xff1a; 暗黑模式&#xff1a; 概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 01 Golang零基础入门课_20240726_149元02 Golang面向对象…

Open3D 三维重建-Poisson Surface Reconstruction (泊松曲面重建)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用 二、代码实现 2.1关键函数 2.1.1函数代码 2.1.2参数详解 2.1.3名词解释 2.2完整代码 三、实现效果 3.1原始点云 3.2重建后点云 3.3去除低密度点云 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点…

Linux快速切换/完善内核

看到标题就晓得是为啥而写的吧&#xff0c;没错&#xff0c;它就是记录Linux的内核切换的一些常见问题&#xff0c;尽可能把平时一些经验和真实有效的心得写下来&#xff0c;同时也希望可以给需要切换内核版本的大伙带来方便&#xff0c;感受到"小小内核切换"竟然如此…

某赛通电子文档安全管理系统 CDGAuthoriseTempletService1 SQL注入漏洞复现(XVE-2024-19611)

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

高效的编程学习方法和技巧

编程小白如何成为大神&#xff1f;大学新生的最佳入门攻略 编程已成为当代大学生的必备技能&#xff0c;但面对众多编程语言和学习资源&#xff0c;新生们常常感到迷茫。如何选择适合自己的编程语言&#xff1f;如何制定有效的学习计划&#xff1f;如何避免常见的学习陷阱&…

关于区块链的公共医疗应用开发

区块链的养老保险平台应用开发 任务一:环境准备 1.编译区块链网络 目录:/root/xuperchain/ 在区块链网络目录下执行make命令,编译网络,编译成功后输出compile done! 启动区块链网络 2.创建钱包账户 创建普通钱包账户userTest,命令如下 bin/xchain-cli account newke…

【linux|001】Unix和Linux的关系 及 它们的发展历史

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…

win7系统postman11.7错误:无法定位程序输入点DiscardVirtualMemory于动态链接库KERNEL32.dlI 上

目录 前言&#xff1a;环境描述 一、问题描述 二、问题定位 三、解决方案 1、卸载最新版&#xff0c;安装原来可用的旧版 2、postman禁止自动更新 四、错误的解决方案 1、重启电脑 2、以为是 KERNEL32.dlI 丢失 3、注册 kernel32.dll 4、使用Windows自带的系统文件检…

PPT免费图片素材网站分享

一、Pixabay 网址&#xff1a;https://pixabay.com/ 图片类型&#xff1a;高清、免费、商用 使用方法&#xff1a;找到想要的图片之后&#xff0c;右键复制之后粘贴到PPT即可使用。同时&#xff0c;点击下载可以找到不同尺寸的PPT素材 二、花瓣网 网址&#xff1a;https://…

mysql事务与索引

1.事务 &#xff08;1&#xff09;提出背景&#xff1a; 在日常开发环境中&#xff0c;有一些场景是需要“一气呵成”完成某一个操作。 eg&#xff1a;银行转账的场景&#xff1a;张三&#xff08;手里有1000&#xff09;现要给李四&#xff08;手里有500&#xff09;转500&…

零基础5分钟上手亚马逊云科技AWS核心云开发/云架构 - 创建高可用数据库集群

简介&#xff1a; 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列&#xff0c;适用于任何无云计算或者亚马逊云科技技术背景的开发者&#xff0c;让大家零基础5分钟通过这篇文章就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我将每天介绍一个基于亚马逊云科…

Go开发后端和Vue3开发前端的前后端分离框架中自己手戳一个OA流程审批、工作流引擎给新时代一个漂亮便捷的工作流引擎

前言 在软件项目开发中&#xff0c;我们都会接触到流程审批的需要业务&#xff0c;我们以往用的最多就是如下图这种流程编辑引擎插件&#xff1a; 以上截图中的流程工具是不是大家常见的呀&#xff01;感觉很丑拿不出手呀&#xff01;在当前行业内卷及竞争激烈情况下&#xff…

Docker Compse单机编排

一.Docker Compse 介绍 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose&#xff0c;你可以使用 YAML 文件来配置应用程序的服务、网络和卷&#xff0c;然后使用单个命令创建和启动所有服务。这使得在开发、测试和部署过程中管理多容器应用程…

鸿蒙(API 12 Beta3版)【AVCodec Kit简介】 音视频编码服务

AVCodec kit&#xff08;Audio & Video Codec Kit&#xff0c;音视频编解码&#xff0c;封装解封装原子能力&#xff09;是媒体系统中的音视频的编解码、媒体文件的解析、封装、媒体数据输入等原子能力。 能力范围 媒体数据输入&#xff1a;媒体应用可以传入文件fd、或者…

TM1652段码屏芯片全解析——概况,性能,MCU连接,样例代码

首先&#xff0c;作为四年前就有的LED段码控制芯片&#xff0c;相关的资料及样例程序少的可怜。硬件驱动 作为固定使用的 软件资源&#xff0c;其共享性远低于软件领域的驱动库。人的才智不应浪费在这种不具创造性的重复实验上。 要点总结&#xff1a; TM1652概述&#xff1a…

【网络层】IP报文解析和网段划分

文章目录 网络层的作用IP协议协议报头格式网段划分DHCPCIDR划分方案 IP地址的数量限制私有IP地址和公网IP地址LAN和WAN 路由 网络层的作用 前面学习了应用层和传输层&#xff0c;应用层的作用是为用户和应用程序提供网络服务&#xff0c;传输层的作用是提供端口到端口的通信服…

数据结构与算法--二叉树的遍历及应用

文章目录 回顾二叉树的五个重要性质 提要二叉树的遍历二叉树遍历流程图前序遍历流程图&#xff08;根左右&#xff09;中序遍历流程图&#xff08;左根右&#xff09;后序遍历流程图&#xff08;左右根&#xff09; 二叉树遍历的示例根据遍历序列确定二叉树的形态确定方法 二叉…

界面组件Kendo UI for Vue 2024 Q2亮点 - 发布一系列新组件

随着最新的2024年第二季度发布&#xff0c;Kendo UI for Vue为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问性改…

arXiv2024.8.6 | LLaVA-OneVision:Easy Visual Task Transfer

Comment: Project Homepage: https://llava-vl.github.io/blog/2024-08-05-llava-onevision/ 论文标题&#xff1a;LLaVA-OneVision&#xff1a;Easy Visual Task Transfer 论文地址&#xff1a;https://arxiv.org/abs/2408.03326 GitHub&#xff1a;https://llava-vl.githu…