一、项目安装
- 1、检查node版本,建议使用Node.js - v18+
- 2、使用nvm管理不同版本的node
- 3、安装nvm - https://github.com/coreybutler/nvm-windows/releases
- 4、安装指定版本的
node nvm install 18.19.0
- 5、查看已安装
node nvm ls
- 6、使用指定版本的
node nvm use 18.19.0
- 7、创建新的nuxt3项目
npx nuxi@latest init nuxt-demo
- 8、安装依赖
npm install
- 9、启动服务
npm run dev
- 10、配合element-plus、vuex、vue-router使用的完整依赖如下所示:
{ "name": "nuxt-demo", "private": true, "type": "module", "scripts": { "build": "nuxt build", "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare" }, "dependencies": { "@element-plus/icons-vue": "^2.0.10", "axios": "^0.21.1", "element-plus": "^2.2.27", "gsap": "^3.8.0", "prismjs": "^1.25.0", "vue": "3.2.45", "umob": "^0.2.5" }, "devDependencies": { "@element-plus/nuxt": "^1.0.6", "@nuxt/devtools": "latest", "nuxt": "^3.8.0", "vite-plugin-prismjs": "^0.0.8", "vue": "^3.3.6", "vue-router": "^4.2.5", "vuex": "^4.0.2" } }
二、Vue-router使用的注意事项
- 1、无需createRouter和路由配置,直接使用
import { useRoute } from 'vue-router'
、const route = useRoute()
即可 - 2、store内部禁止使用
const route = useRoute()
, 不会响应式更新,需放在setup内部。 - 3、路由全局守卫, middleware 目录下创建 base.global.ts, 内容如下:
export default defineNuxtRouteMiddleware((to, from) => {
const { name: toName } = to
const { name: fromName } = from
console.log(toName, fromName)
})
三、数据获取
- 1、本地请求代理配置,nuxt.config.ts中的vite部分配置如下所示:
vite: {
server: { // 本地请求服务器代理
proxy: {
'/api': {
target: 'https://xxxx.com/api',
changeOrigin: true,
},
},
},
}
- 2、服务器请求代理配置,nuxt.config.ts中的nitro部分配置如下所示:
nitro: {
routeRules: { // 服务器请求代理
'/api/**': {
proxy: 'https://xxxx.com/api/**',
},
},
}
- 3、数据获取必须在setup内部调用(禁止在store内调用),useFetch会自动避免客户端重复发起请求,这是nuxt实现ssr的重要方式,具体请求如下:
await Promise.all([
useFetch('/a/b', {
query: { id: '01' },
method: 'get',
}),
useFetch('/a/c', {
query: { id: '02' },
method: 'get',
})
])
请求完成之后的数据处理与正常请求一致。若出现 Hydration children mismatch in <div>: server rendered element contains more child nodes than client vdom
警告,这可能是初始化时存在某个判断条件,该条件在服务端渲染和客户端时存在不一样的表现,进而导致服务端水合结果与客户端不一致。如:localStorage的判断、onMounted内的数值初始化等
四、如何在head内注入js代码片段?
nuxt.config.ts中的app部分配置如下所示:
head: {
script: [{
children: `window.addEventListener('load', function() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})`,
}],
}
五、路由跳转短暂白屏处理
默认情况下,useFetch会在异步函数解析完成之前使用Vue的Suspense进行页面导航,而Suspense的#fallback默认为空,从而造成白屏现象
- 1、使用 useLazyFetch 可以忽略此功能在客户端导航时的使用。在这种情况下,需要手动处理加载状态。首先,修改请求方法:
const fetchHandle = async (id) => {
const { data: response, pending } = await useLazyFetch('/a/b/getById', {
query: { id },
method: 'get',
key: 'getById:' + id,
})
return {
response,
pending,
}
}
- 2、在composables目录下新建 index.ts
export const useLazyFetchHandle = (data: any, res: any, key: string) => {
const { response, pending } = data
const { data: prevData } = useNuxtData(key)
if (response.value) {
// 服务端渲染的数据处理
res.value = response.value.data
}
const isLoading = computed(() => { // 加载中
if (prevData.value) {
return !prevData.value.success && pending.value
}
return pending.value
})
watch(response, (newRes) => {
// 监听路由跳转请求的数据处理
res.value = newRes.data
})
return isLoading
}
- 3、组件内部调用
const result = ref({})
const isLoading = useLazyFetchHandle(
await fetchHandle(id),
result,
'getById:' + id,
)
六、部署
- 1、检查node版本, 若出现报错
[nuxt] [request error] [unhandled] [500] _fetch is not a function
则需升级node
可安装NVM升级node,参考链接 https://blog.csdn.net/xhp312098226/article/details/131247719
- 2、Ubuntu 18.04 出现GLIBC_2.28 not found,则需升级Ubuntu系统版本
sudo apt update
sudo apt upgrade
sudo apt full-upgrade
sudo apt autoremove
sudo systemctl reboot
sudo apt install update-manager-core
sudo do-release-upgrade -m desktop -d
升级完成后,mysql也将会被升级至mysql 8,需要重新设置root用户密码和权限
- 3、执行打包命令
npm run build
,并生成 .output文件夹 - 4、使用pm2管理node服务,PM2 是维持一个 Process 执行的管理器,們可以藉由 PM2 來啟動我們的 Nitro Server,当服务崩溃时能自动的重新启动,以维持服务的正常运作,除此之外 PM2 可以启用集群 (Cluster) 的功能结合请求的负载均衡,来让多核心的机器提升资源的利用率和效能
安装pm2
npm install -g pm2
- 5、在 Nuxt 目录下放入.output文件夹,并创建
ecosystem.config.js
文件,內容如下:
module.exports = {
apps: [
{
name: 'nuxt-demo',
exec_mode: 'cluster',
instances: 'max',
script: './.output/server/index.mjs',
env: {
PORT: 3000,
HOST: '0.0.0.0',
}
}
]
}
- 6、启动服务
pm2 start ecosystem.config.js
- 7、配置nginx
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header HOST $host;
}
七、静态资源404
经排除,问题为以下location导致
location ~ .*.(ttf|woff|webp|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
expires max;
if_modified_since off;
add_header Last-Modified "";
etag off;
}
调整location匹配规则,过滤_nuxt路径下的静态资源
location ~* ^(?!/(_nuxt|favicon))(.+).(ttf|woff|webp|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
expires max;
if_modified_since off;
add_header Last-Modified "";
etag off;
}
References
[1] Nuxt3文档
[2] https://github.com/element-plus/element-plus-nuxt-starter
[3] Nuxt 3 学习笔记