> 文章列表 > Nuxt3项目从零开始开发

Nuxt3项目从零开始开发

Nuxt3项目从零开始开发

之前讲过Nuxt3项目新建和配置:《Nuxt3从零开始配置与打包发布_nuxt打包发布_范特西_jay的博客-CSDN博客》

本篇文章主要讲解一些nuxt3的基本功能。

Nuxt3官网:https://nuxt.com/docs

Nuxt3的官方库:https://nuxt.com/modules

常用的库有:Element Plus、Vant、color-mode、axios,其他库可以根据需求查找使用。(注意安装时候要按照nuxt3方式安装和引用)

Nuxt3官方提供的案例:https://nuxt.com/showcase

一、先看一下第三方库的安装方法

1、Nuxt3安装Element Plus nuxt3版本:

npm install -D @element-plus/nuxt

 配置:

// nuxt.config.ts
export default defineNuxtConfig({modules: ['@element-plus/nuxt'],
})

库的组件使用时候直接在页面写即可,无需导入,会自动导入。

2、color-mode安装 (https://nuxt.com/modules/color-mode):

color-mode用于实现网页的浅色模式和暗黑模式,支持自定义颜色模式和跟随系统模式。

npm install --save-dev @nuxtjs/color-mode

配置:

export default defineNuxtConfig({modules: ['@nuxtjs/color-mode'],colorMode: {preference: 'system', // 默认模式(system/light/dark/sepia)fallback: 'light', // 失败后使用的颜色模式hid: 'nuxt-color-mode-script',globalName: '__NUXT_COLOR_MODE__',componentName: 'ColorScheme',classPrefix: '',//类名前缀classSuffix: '-mode',//类名后缀storageKey: 'nuxt-color-mode'//localStorage存储的key}
})

官方示例:

<template><div><h1>Color mode: {{ $colorMode.value }}</h1><select v-model="$colorMode.preference"><option value="system">System</option><option value="light">Light</option><option value="dark">Dark</option><option value="sepia">Sepia</option></select></div>
</template>
<script setup>
const colorMode = useColorMode()
console.log(colorMode.preference)
</script>
<style>
body {background-color: #fff;color: rgba(0,0,0,0.8);
}
.dark-mode body {background-color: #091a28;color: #ebf4f1;
}
.sepia-mode body {background-color: #f1e7d0;color: #433422;
}
</style>

这里推荐color-mode结合Element Plus来实现浅色和暗黑模式切换,这样就不用自己写浅色和暗黑模式的css样式了(暗黑模式 | Element Plus)。

引入配置Element Plus暗黑模式样式类:

//只需要如下在项目入口文件修改一行代码:
import 'element-plus/theme-chalk/dark/css-vars.css'

实际上实现的是可以创建一个开关来控制暗黑模式的class 类名。

<html class="dark"><head></head><body></body>
</html>

项目里,创建colorMode变量:

<script setup>
const colorMode = useColorMode()
console.log(colorMode.preference)... ...</script>

由于是SSR模式,所以当我们调试或者部署时候,会出现获取到的colorMode.preference 不准确问题,所以我这里又单独弄了个localStorage来时时存储哪种主题颜色模式。

<script setup>
import { ref, onMounted } from "vue";
import { ElMessage } from "element-plus";
const colorMode = useColorMode();const darkMode = ref("");const isDark = ref('light');//读取当前主题颜色模式(仅供参考)
onMounted(() => {isDark.value = localStorage.getItem('darkMode') == null ? 'light' :     localStorage.getItem('darkMode');colorMode.preference = isDark.value;if (isDark.value == 'light') {darkMode.value = "浅 色";} else if (isDark.value == 'dark') {darkMode.value = "暗 黑";} else if (isDark.value == 'system') {darkMode.value = "系 统";}
});//点击切换主题模式(仅供参考)
function toggleDarkMode() {if (isDark.value == 'light') {darkMode.value = "暗 黑";colorMode.preference = 'dark';localStorage.setItem('darkMode', 'dark');isDark.value = 'dark';} else if (isDark.value == 'dark') {darkMode.value = "系 统";colorMode.preference = 'system';isDark.value = 'system';localStorage.setItem('darkMode', 'system');} else if (isDark.value == 'system') {darkMode.value = "浅 色";colorMode.preference = 'light';isDark.value = 'light';localStorage.setItem('darkMode', 'light');}
}</script>

3、axios安装:

npm install axios

axios在Nuxt3中安装方法和使用方法和在Vue3项目中是一样的。

function getData(url: string) {const api = axios.create({baseURL: "https://api.github.com/search/repositories?q=v&sort=stars",timeout: 60000,withCredentials: false,method: "get",headers: {"Content-Type": "application/json",},});api.get(url).then((res) => {console.log(res);});
}

4、Nuxt3安装和引入使用vueUse库

安装:

npm i -D @vueuse/nuxt @vueuse/core

配置:

// nuxt.config.ts
export default defineNuxtConfig({modules: ['@vueuse/nuxt',],
})

二、设置全局默认的title、meta、keywords、description、content等信息

在nuxt.config.ts中提供app.head属性。允许你为整个应用程序定制head。示例如下:

export default defineNuxtConfig({app: {head: {charset: 'utf-16',viewport: 'width=500, initial-scale=1',title: 'My App',meta: [// <meta name="description" content="My amazing site">{ name: 'description', content: 'My amazing site.' }],link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],}}
})

如果你想单独在某个页面设置title,可以使用useHead。示例代码:

<script setup lang="ts">
useHead({title: 'My App',meta: [{ name: 'description', content: 'My amazing site.' }],bodyAttrs: {class: 'test'},script: [ { children: 'console.log(\\'Hello world\\')' } ]
})
</script>

可配置属性如下:

interface MetaObject {title?: stringtitleTemplate?: string | ((title?: string) => string)base?: Baselink?: Link[]meta?: Meta[]style?: Style[]script?: Script[]noscript?: Noscript[];htmlAttrs?: HtmlAttributes;bodyAttrs?: BodyAttributes;
}

你可以在link和 script元标签上使用body: true 选项将它们附加到<body>标签的末尾。

<script setup lang="ts">
useHead({script: [{src: 'https://third-party-script.com',body: true}]
})
</script>

添加动态标题。titleTemplate被设置为一个带有 %s占位符的字符串或function,这允许更大的灵活性来动态设置 Nuxt app的每个路由的页面标题:

<script setup>useHead({// as a string,// where `%s` is replaced with the titletitleTemplate: '%s - Site Title',// ... or as a functiontitleTemplate: (productCategory) => {return productCategory? `${productCategory} - Site Title`: 'Site Title'}})
</script>

添加外部CSS:

<script setup lang="ts">
useHead({link: [{rel: 'preconnect',href: 'https://fonts.googleapis.com'},{rel: 'stylesheet',href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap',crossorigin: ''}]
})
</script>

三、使用Nuxt3自带的useFetch拉取数据

Nuxt提供了useFetch, useLazyFetch, useAsyncData和useLazyAsyncData来处理应用程序中的数据获取,这里我们只介绍useFetch用法。(注意useFetch请求只能放在script根目录或者生命周期回调里或者自己自定义个async异步方法)

基本示例:

async function getFetchListData() {const { data, pending, error, refresh } = await useFetch("https://api.nuxtjs.dev/mountains", { method: 'get' })console.log(data.value[0].title);
}//如果提示data这里有错误,可以按照如下的改写async function getFetchListData() {const { data, pending, error, refresh }:any = await useFetch("https://api.nuxtjs.dev/mountains", { method: 'get' })console.log(data.value[0].title);
}

useFetch类型:

function useFetch(url: string | Request | Ref<string | Request> | () => string | Request,options?: UseFetchOptions<DataT>
): Promise<AsyncData<DataT>>
type UseFetchOptions = {key?: stringmethod?: stringquery?: SearchParamsparams?: SearchParamsbody?: RequestInit['body'] | Record<string, any>
headers?: Record<string, string> | [key: string, value: string][] | Headers
baseURL?: string
server?: boolean
lazy?: boolean
immediate?: boolean
default?: () => DataT
transform?: (input: DataT) => DataT
pick?: string[]
watch?: WatchSource[]
}
type AsyncData<DataT> = {data: Ref<DataT>pending: Ref<boolean>refresh: (opts?: { dedupe?: boolean }) => Promise<void>execute: () => Promise<void>error: Ref<Error | boolean>
}

useFetch参数:

  • URL: 要获取的URL。
  • Options (extends unjs/ofetch options & AsyncDataOptions):
    • method: 请求方法。
    • query: 使用 ufo 添加查询搜索参数到URL。
    • params:query 的别名。
    • body: 请求体-自动字符串化(如果传递了一个对象)。
    • headers: 请求头。
    • baseURL: 请求的基本URL。
  • Options (from useAsyncData):
    • key: 一个唯一的键,以确保数据获取可以正确地跨请求去重复数据,如果没有提供,它将基于使用useAsyncData的静态代码位置生成。
    • server: 是否从服务器上获取数据(默认为true)。
    • default: 一个工厂函数,在async函数解析之前设置数据的默认值——lazy: true选项尤其有用。
    • pick: 只从handler函数结果中选择该数组中的指定键。
    • watch: 监视响应源以自动刷新。
    • transform: 解析后可用于改变handler函数结果的函数。
    • immediate: 当设置为false时,将阻止请求立即触发。(默认为true)

useFetch返回值:

  • data: 传入的异步函数的结果。
  • pending: 一个布尔值,指示是否仍在提取数据。
  • refresh/execute : 可用于刷新handler函数返回的数据的函数。
  • error: 如果数据获取失败,则错误对象。

默认情况下,Nuxt要等到refresh完成后才能再次执行。

使用拦截器:

const { data, pending, error, refresh } = await useFetch('/api/auth/login', {onRequest({ request, options }) {// Set the request headersoptions.headers = options.headers || {}options.headers.authorization = '...'},onRequestError({ request, options, error }) {// Handle the request errors},onResponse({ request, response, options }) {// Process the response datareturn response._data},onResponseError({ request, response, options }) {// Handle the response errors}
})

四、主动路由跳转

Nuxt3自带router和route,直接定义使用即可。

const router = useRouter();

示例如下:

<script setup>
import isMobile from './utils/isMobile';
const router = useRouter();onMounted(() => {if (isMobile.Any()) {router.push("/wap/");} else {router.push("/");}
});
</script>

五、Nuxt3自定义错误页面

Nuxt3自定义错误页面,只需要在项目根目录新建一个error.vue页面即可。

页面里通过定义useError来获取返回的错误信息,展示到页面上。

const error = useError()

示例代码:

<template><div>{{error.statusCode}}-自定义错误页面</div>
</template>
<script setup>const error = useError();onMounted(() => {console.log(error.value.statusCode);
});
</script>

六、增加路由后缀,如.html

可以直接在pages里的页面命名时加入后缀即可,例如abc.html.vue。访问时候就可以通过后缀访问了:abc.html

七、public和assets资源的访问路径

public资源访问直接写public下的资源路径即可(如果项目有baseUrl,路径可以加上baseUrl)。示例如下:

//public目录资源文件引入使用<template><div><div><img :src="baseURL+'resource/img/public.png'"></div></div>
</template>
<script setup>const config = useRuntimeConfig();const baseURL = config.app.baseURL;
</script>
<style scoped>@import "/resource/css/resource.css";
</style>

assets目录资源引入,路径前加入~/assets/即可。

//assets目录资源引入<template><div><div><img src="~/assets/img/assets.png"></div></div>
</template>
<style lang="scss" scoped>@import '~/assets/css/resource.scss';
</style>

八、客户端渲染设置

客户端渲染设置,使用<ClientOnly>......</ClientOnly>标签包裹即可。

<ClientOnly fallback-tag="div" fallback="等待客户端渲染中"><div>数据</div>
</ClientOnly>//或者<ClientOnly><div>数据</div>
</ClientOnly>

九、打包部署,并自定义运行的端口号

推荐使用pm2进行运行,并自定义端口号。

pm2常用命令:

pm2 start app.js              # 启动app.js应用程序
pm2 start app.js -i 4         # cluster mode 模式启动4个app.js的应用实例# 4个应用程序会自动进行负载均衡
pm2 start app.js --name="api" # 启动应用程序并命名为 "api"
pm2 start app.js --watch      # 当文件变化时自动重启应用
pm2 start script.sh           # 启动 bash 脚本
pm2 list                      # 列表 PM2 启动的所有的应用程序
pm2 monit                     # 显示每个应用程序的CPU和内存占用情况
pm2 show [app-name]           # 显示应用程序的所有信息
pm2 logs                      # 显示所有应用程序的日志
pm2 logs [app-name]           # 显示指定应用程序的日志
pm2 flush                     # 清空所有日志文件
pm2 stop all                  # 停止所有的应用程序
pm2 stop 0                    # 停止 id为 0的指定应用程序
pm2 restart all               # 重启所有应用
pm2 reload all                # 重启 cluster mode下的所有应用
pm2 gracefulReload all        # Graceful reload all apps in cluster mode
pm2 delete all                # 关闭并删除所有应用
pm2 delete 0                  # 删除指定应用 id 0pm2 scale api 10              # 把名字叫api的应用扩展到10个实例
pm2 reset [app-name]          # 重置重启数量
pm2 startup                   # 创建开机自启动命令
pm2 save                      # 保存当前应用列表
pm2 resurrect                 # 重新加载保存的应用列表
pm2 update                    # Save processes, kill PM2 and restore processes
pm2 generate                  # Generate a sample json configuration file