前言
Nuxt3 的对比之前的2 和 1 ,只能感叹前端发展的越来越快了,不学无术
开发更快 打包更小 支持 vite 支持 vue3 支持自动引入 支持文件路由 支持布局系统 支持多种渲染模式 支持 typescript 支持 composition-api
安装NUXT3 需要node 大于16的版本
brew 更新 node
brew update
brew upgrade node
还有就是 node 安装
npm install -g n
npm install -g
sudo n stable
最后查看node版本
然后 安装官网的来
npx nuxi@latest init <project-name>
因为家里的网 没有那么快,需要在hosts 配置
sudo vi /etc/hosts
把上面的代码输入上去 按 : wq 退出保存
然后在运行
最后 安装 cd my-nuxt. npm run dev
打开目录 vscode
vetur 把插件卸载 然后装上 Volar. vue3 的插件 这个是有好
关于NUXT目录的
Nuxt 使用.nuxt/目录在开发中生成您的Vue应用程序。
你不应该碰里面的任何文件,因为整个目录将在运行 nuxt dev 时重新创建。
就是最上面的nuxt 目录
components 组件
组件名策略
默认情况下,Nuxt自动导入components目录中的任何组件,组件名将基于它的路径、目录和文件名。
惰性加载组件
要动态导入一个组件(也称为惰性加载组件),则在组件名称前添加 Lazy
前缀。通过使用 Lazy
前缀,你可以延迟加载组件代码,直到合适的时刻
<template> <div> <MyImg /> <LazyMyImg /> </div> </template>
composables
composables 目录下的内容也将自动将 Vue 组合导入到应用中,Nuxt 只扫描 composables/ 目录的顶层文件。Composables 的主要作用是将常用逻辑和逻辑相关的代码抽象出来,以提高代码可复用性和可维护性,如:跨组件创建响应性的、对ssr友好的共享状态—— useState
。
/** * composables/counter.ts 内容 **/ export const userCounter = () => { return useState('counter', () => 0); };
/** * 业务组件 **/ <script setup> import Count from "~/components/business/Count.vue"; const counter = userCounter(); </script> <template> <div> 业务组件内容: {{ counter }} <a-button type="primary" @click="counter--"> - </a-button> <a-button type="primary" @click="counter++"> + </a-button> </div> </template>
/** * business/Count 组件内容 **/ <template> <div>Count组件内容:{{ counter }}</div> </template> <script setup lang="ts"> const counter = userCounter(); </script>
layouts
Nuxt提供了一个可定制的布局框架,可以在整个应用程序中使用,非常适合将常见的UI或代码模式提取到可重用的布局组件中。布局放在layouts/目录中,使用时将通过异步导入自动加载。
默认布局
在layouts目录下添加default.vue 布局文件。
不像其他组件,布局组件必须有一个根元素,以允许 Nuxt 在布局变化之间应用过渡-这个根元素不能是<slot />。如果你的应用只有一个布局,建议使用app.vue。
在布局文件中,布局的内容将加载在<slot />中,~/layouts/default.vue:
<template> <div> <slot /> </div> </template>
如果你使用app.vue你还需要添加 :
<template> <NuxtLayout> // 在app.vue中没有NuxtLayout组件,内容将会不显示 </NuxtLayout> </template>
配置布局
-| layouts/ ---| default.vue ---| custom.vue
可以在 NuxtLayout 中添加 name
属性来覆盖默认布局:
<template> <NuxtLayout :name="layout"> <NuxtPage /> </NuxtLayout> </template> <script setup> // 您可以根据API调用或登录状态来选择此选项 const layout = "custom"; </script>
也可以通过 definePageMeta
设置
<template> <NuxtLayout> 2023,12.23 </NuxtLayout> </template> <script setup> definePageMeta({ layout: "custom", }); </script>
如果业务组件不使用
<NuxtLayout>
组件包裹,配置布局是不会生效的
方法
pages 页面
页面目录。Nuxt 提供了一个基于文件的路由,使用 Vue Router 在底层创建路由。pages/index.vue 文件将被映射到应用程序 / 路由。
如果你正在使用app.vue,确保在 app.vue 使用 <NuxtPage/>
组件来显示当前页面。
动态路由
建立页面文件时,如果命名时将任何内容放在方括号内,它将被转换为路由参数。在文件名或目录中混合和匹配多个参数。
-| pages/ ---| index.vue ---| users-[group]/ -----| [id].vue
会生成路由:
{ "routes": [ { "name": "users-group-id", "path": "/users-:group()/:id()", "component": "~/pages/users-[group]/[id].vue" }, ] }
根据上面的例子,你可以通过 $route 对象中的 params 访问组件中的 group & idx
<template> <ul class="text-base text-gray-600"> <li> 获取到的 group 是 <span class="text-green-500 text-xl">{{ group }}</span> </li> <li> 获取到的 id 是 <span class="text-green-500 text-xl">{{ id }}</span> </li> </ul> </template>
nuxt3 中内置了四种请求的方法
useFetch useLazyFetch useAsyncData useLazyAsyncData
推荐的话还是 useFetch
const param1 = ref('value1') const { data, pending, error, refresh } = await useFetch('/api/modules', { query: { param1, param2: 'value2' } })
Request 的封装与使用
没有用 nuxt3 自带的接口返回格式才进行这样的简易封装;
- ~enums/interface.ts // 定义接口返回 code 值的枚举
export enum ResultEnum { SUCCESS = 0, TOKEN_OVERDUE = 404, // 用户登录失败 INTERNAL_SERVER_ERROR = 500, // 服务异常 }
- ~/composables/useDefaultRequest.ts // 定义接口统一拦截函数
import { UseFetchOptions } from "nuxt/app"; import { RouteLocationRaw } from "vue-router"; import { ResultEnum } from "~/enums/interface"; interface DefaultResult<T = any> { code: number; data: T; msg: string; success: boolean; } type UrlType = string | Request | Ref<string | Request> | (() => string | Request); type HttpOption<T> = UseFetchOptions<DefaultResult<T>>; interface RequestConfig<T = any> extends HttpOption<T> { // 忽略拦截,不走拦截,拥有 responseData,且 code !== 0 的情况下,直接返回 responseData, // 但是若无 responseData, 不设置 ignoreGlobalErrorMessage 也会报错 ignoreCatch?: boolean; // 忽略全局错误提示,走拦截,但是任何情况下都不会提示错误信息 ignoreGlobalErrorMessage?: boolean; } const request = async <T>( url: UrlType, params: any, options: RequestConfig<T> ): Promise<DefaultResult<T> | T> => { const headers = useRequestHeaders(["cookie"]); const method = ((options?.method || "GET") as string).toUpperCase(); const runtimeConfig = useRuntimeConfig(); const nuxtApp = useNuxtApp(); const { $message, $login } = nuxtApp; const { apiBaseUrl } = runtimeConfig.public; const baseURL = `${apiBaseUrl}/mall/api`; // 处理用户信息过期 const hanlerTokenOverdue = async () => { const { _route } = nuxtApp; await $login(_route?.fullPath); }; // 处理报错异常 const handlerError = (msg = "服务异常") => { if (process.server) { showError({ message: msg, statusCode: 500 }); } else { $message.error(msg); } }; const { data, error } = await useFetch(url, { baseURL, headers, credentials: "include", params: method === "GET" ? params : undefined, body: method === "POST" ? JSON.stringify(params) : undefined, ...options, }); const responseData = data.value as DefaultResult<T>; const { ignoreCatch, ignoreGlobalErrorMessage } = options; // 忽略全局 if (error.value || !responseData) { if (!ignoreGlobalErrorMessage) handlerError(); return Promise.reject(error.value || "服务响应失败,请稍后重试"); } else { const { code, data: result, msg } = responseData; // 接口请求成功,直接返回结果 if (code === ResultEnum.SUCCESS || !code) { return result; } if (!ignoreCatch) { // 接口请求错误,统一处理 switch (code) { case ResultEnum.TOKEN_OVERDUE: // 登录信息过期,去登录 // 用户信息过期 await hanlerTokenOverdue(); default: if (!ignoreGlobalErrorMessage) handlerError(msg); return Promise.reject(msg || "服务响应失败,请稍后重试"); } } } return responseData; };
// 自动导出
export const useDefaultRequest = { get: <T>(url: UrlType, params?: any, option?: RequestConfig<T>) => { return request<T>(url, params, { method: "get", ...option }); }, post: <T>(url: UrlType, params?: any, option?: RequestConfig<T>) => { return request<T>(url, params, { method: "post", ...option }); }, };
useFetch() 在 onMounted 执行返回值为 null?
解决onMounted(async () => { console.log('onMounted'); await nextTick(); testFetch1(); });原因:只有客户度执行 服务端不执行onMounted内容;
如果onMounted内需执行useFetch,应该放在await nextTick之后,否则会返回null;
在setup内(onMounted外)执行useFetch,服务端和客户端都执行, 为了避免渲染时useFetch未执行完毕,尽量使用await而不是then方法;
先更新到这里先把
标签:总结,vue,const,Nuxt3,基础,params,useFetch,组件,目录 From: https://www.cnblogs.com/yf-html/p/17923295.html