欢迎点击领取 -《前端开发面试题进阶秘籍》:前端登顶之巅-最全面的前端知识点梳理总结
微信搜索:“前端登顶之巅” 底部资源库, 获取最新线路;
需求简介:公司需要开发一个官方网站,在技术选型上面最终定nuxt3+vue3+vite
版本:nuxt3.9.1、vue3、vite5.0.11
本篇文章不过多解释创建nuxt3与基础的框架目录结构问题,敬请谅解!
一、踩坑记录问题点:
1、【Nuxt】Nuxt3 控制台警告 [Vue Router warn]: No match found for location with path “/undefined
2、设置自定义动态路由[slug].html访问
3、配置全局环境变量访问不同接口域名
4、使用内置NuxtLayout开发自定义骨架布局
5、配置nuxt.config.ts属性:modules、runtimeConfig、app、nitro、vite、hooks;等包含本地配置代理与nuxt2不同,需在nitro中配置
6、预渲染-配置,添加所有路由线路
7、部署问题,pnpm包引起的项目部署够报 “ Cannot find package ‘@popperis/core’ imported from /app/.output/server/chunks/app/_nuxt/default-AlcRvqCQ.mis ”
8、封装公共请求js文件;使用内置useFetch函数,通过promise抛出响应内容
二、解决问题
1)【Nuxt】Nuxt3 控制台警告 [Vue Router warn]: No match found for location with path “/undefined
2)设置自定义动态路由[slug].html访问
1、官网只解释了自定义路由的添加方法并未详细做出解释在哪块
2、官网其实是有个文件的路径显示,在根路径下面创建app文件夹
3、在app文件夹下面创建router.options.ts文件作为自定义路由
4、示例: 添加后缀让我们的项目更加像html书写出来的也叫伪静态,动态路由有利于后台管理平台或者低代码生成我们的想要的界面,更加便捷与灵活,减少开发成本,只需要固定的生成方式即可;
import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig> {
routes: (_routes) => [
{
path: '/',
redirect: '/home.html'
},
{
name: 'home',
path: '/home.html',
component: () => import('~/pages/home.vue').then(r => r.default || r)
},
{
name: 'about',
path: '/about/:slug.html',
component: () => import('~/pages/about/[slug].vue').then(r => r.default || r)
},
],
}
3)配置全局环境变量访问不同接口域名
- 创建.env.development和.env.production
//.env.development
# 构建生产预渲染
BUILD_BASE_API = 'http://api.com:8080'
# 后端接口公共路径
NUXT_BASE_API = ''
- 修改package.json文件启动和构建命令
"dev": "nuxt dev --dotenv .env.development --host",
"build:test": "nuxt build --dotenv .env.development && npm run created",
"build:prod": "nuxt build --dotenv .env.production && npm run created",
"created": "mkdir .output/server/node_modules/@popperjs && mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core"
- 在nuxt.config.ts中添加全局访问接口前缀名
runtimeConfig: {
public: {
baseURL: process.env.NUXT_BASE_API
}
},
4)使用内置NuxtLayout开发自定义骨架布局,根文件也可使用default输出!
5)配置nuxt.config.ts属性:modules、runtimeConfig、app、nitro、vite、hooks;等包含本地配置代理与nuxt2不同,需在nitro中配置
6)预渲染-配置添加针对所有路由(含5的内容)
import axios from "axios";
const baseURL = process.env.BUILD_BASE_API
// 动态获取后端返回的前端路由做处理,处理数据依据后端返回逻辑调整 => ['/home.html', '/about/1.html']
const getRoutes = async () => {
const endpoint = baseURL + '/router/list';
const response = await axios.get(endpoint)
const articlesRouter = response.data?.data?.list || [];
const navlist = articlesRouter.filter((item: any) => item.link).map((opt: any) => opt.link)
const menuList = articlesRouter.map((item: any) => item.menuList?.length && item.menuList).filter(Boolean).flat().map((opt: any) => opt.link)
const all = [...navlist, ...menuList]
// ['/home.html', '/about/1.html']
return all
}
export default defineNuxtConfig({
ssr: true,
devtools: { enabled: false },
modules: ['@element-plus/nuxt', 'nuxt-swiper'],
swiper: {},
runtimeConfig: {
public: {
baseURL: process.env.NUXT_BASE_API
}
},
css: ['@/assets/styles/global.scss'], // 配置项目全局css样式
app: {
head: {
title: "测试",
link: [{ rel: "icon", href: "/favicon.ico", type: 'image/x-icon' }],
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "keywords", name: "keywords", content: "" },
{ hid: "description", name: "description", content: "" },
],
},
},
nitro: { // 配置nitro本地开发环境代理
devProxy: {
"/website": {
target: "http://api:8080/website",
changeOrigin: true,
prependPath: true,
},
},
},
vite: { // 配置vite构建剔除CMD面板警告问题
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: false,
drop_debugger: true,
pure_funcs: ['console.log']
},
format: {
comments: false
}
},
}
},
hooks: { // 配置nitro前置构建生产预渲染html内容,加速访问
async 'nitro:config'(nitroConfig: any) {
if (nitroConfig.dev) return
let slugs = await getRoutes()
nitroConfig?.prerender?.routes.push(...slugs)
return
}
},
})
7)部署问题,pnpm包引起的项目部署够报 “ Cannot find package ‘@popperis/core’ imported from /app/.output/server/chunks/app/_nuxt/default-AlcRvqCQ.mis ”
1、解决办法,在package.json文件中新增: “created”: “mkdir .output/server/node_modules/@popperjs && mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core” 命令
2、引起的原因是pnpm创建下载的依赖包,与npm包的存放路径位置不一致导致的这个问题,所以需要我们手动拷贝或者命令行创建,使其更加便捷
"scripts": {
"dev": "nuxt dev --dotenv .env.development --host",
"build:test": "nuxt build --dotenv .env.development && npm run created",
"build:prod": "nuxt build --dotenv .env.production && npm run created",
"created": "mkdir .output/server/node_modules/@popperjs && mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core"
},
8、封装公共请求js文件;使用内置useFetch函数,通过promise抛出响应内容
在utils文件夹下创建request.ts
import type { LocationQuery } from 'vue-router';
import type { NitroFetchRequest } from 'nitropack';
import type { FetchOptions } from 'ofetch';
import { ElMessage, ElLoading } from 'element-plus'
// 接口传参要求
interface QueryItem {
uid?: string;
token?: LocationQuery;
}
const codeMessage: any = {
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '登录过期请重新登录',
404: '请求资源不存在。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
const request = (url: NitroFetchRequest, params?: FetchOptions<any>, method: 'get' | 'post' | 'delete' | 'put' = 'get') => {
const route = useRoute();
const config = useRuntimeConfig();
const query: QueryItem = route.query;
const baseURL: string = config.public.baseURL + '/pre-api/';
return new Promise((resolve, reject) => {
const loadingInstance = ElLoading.service({ fullscreen: true })
useFetch(url, {
method,
baseURL: baseURL,
onRequest({ options }) {
options.headers = { ...options.headers, Authorization: 'xxx' };
if (method === 'post' || method === 'put') {
options.body = { ...params };
options.query = query;
} else {
options.query = Object.assign(query, { ...params });
}
},
onResponse({ response }) {
const { status, _data } = response
const { code, message } = _data || {}
setTimeout(() => loadingInstance.close(), 500)
if (code === 0) return resolve(response._data)
else if (code && message) return ElMessage.error(message || 'Error')
if (codeMessage[status]) return ElMessage.error(status + ':' + codeMessage[status] || '请求异常')
},
onRequestError({ error }) {
loadingInstance.close()
reject(error)
},
onResponseError({ options }) {
loadingInstance.close()
reject(options)
}
});
})
}
export default request
请求的使用方式:
import request from '@/utils/request'
const api = {
company: () => '/api/find/list',
}
const company = (params = {}) => request(api.company(), params)
export default {
company,
}