目录
初识Nuxt.js,了解不深,整理了一个项目模版,内容比较简单,主要是各个功能点写了Demo,在这里分享给大家,本文仅作项目功能点简介和部署,带你了解全部过程,附带源码地址。
前言
有兴趣的朋友可以自行了解下服务端渲染(SSR)
,毕竟 Nuxt.js
就是一个基于 Vue.js
的服务端渲染应用框架;
Nuxt.js 是什么?
-
Nuxt.js 是一个基于 Vue.js 的通用应用框架。
-
预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。
一、初始化项目
建议:
Nodejs >= 16.11.0
pnpm >= 7.x
KD111111000161:nuxt3-vite-template alun$ pnpm install
......
KD111111000161:nuxt3-vite-template alun$ pnpm dev
> nuxt3-vite@1.0.0 dev /Users/alun/WebstormProjects/nuxt3-vite-template
> nuxt dev
14:47:15
Nuxi 3.3.1 14:47:15
Nuxt 3.3.1 with Nitro 2.3.1 14:47:15
14:47:16
> Listening: http://localhost:3000/
✔ Nitro built in 2105 ms nitro 14:47:20
ℹ Vite client warmed up in 4891ms
到这里在浏览器里输入:http://localhost:3000 ,就可以看到页面;
二、项目目录简介
- composables:模块化代码composables文件夹,共用的方法写在里面可以自动导入到页面组件插件当中。
- layouts:是Nuxt3提供的一种方便开发者快速实现自定义布局的约定,使用该约定需要在根目录下创建layouts文件夹,并在里面创建.vue文件用来作为布局模板。如果需要创建多个模板,在layouts中创建多个.vue文件即可。
其他的文件夹,这里就不一一介绍了,有不懂的可以留言。
三、主要功能点
-
Layout布局
你可以认为这是公共组件;
-
default.vue:默认模板,可以添加在所有页面,也可单独添加,页面也可单独禁用;
<template>
<div>
<!-- src/app.vue 全局配置--每个页面中都会有该模板 -->
<NuxtLayout>
<NuxtPage></NuxtPage>
</NuxtLayout>
</div>
</template>
<template>
<div>
<!-- src/pages/goods/[id].vue -->
......
</div>
</template>
<script setup lang="ts">
// 禁用默认的 layout
definePageMeta({
layout: false,
});
</script>
- header.vue、footer.vue:自定义模板
<template>
<div>
<!-- src/pages/index.vue -->
<NuxtLayout name="footer"/>
</div>
</template>
-
路由(需注意nuxt2与nuxt3是有区别的)
在Vue中需要手动配置router路由规则,而Nuxt省去了手动配置的麻烦,Nuxt会自动检测并配路由。因此只需要直接在浏览器访问即可,但Nuxt自动生成的路由规则有着一定的规律。
例如:
<template>
<!-- src/pages/index.vue 页面使用 -->
<NuxtLink to="/good/111111">进入 id 为 111111 的页面</NuxtLink>
</template>
<template>
<!-- src/pages/goods/[id].vue 获取参数 -->
<p>当前的id:{{ route.params.id }}</p>
</template>
<script setup lang="ts">
const route = useRoute()
</script>
路由参数可以设置校验,校验页面参数是否符合规则,若符合返回true 符合可以访问正常的页面,不符合会跳转至错误页面,有兴趣的可以去官网看下。
-
compositables 方法自动导入
compositables 文件夹下新建 useTime.ts 文件;
export const useTime = () => {
return useState('time', () => new Date().getTime())
}
<template>
<!-- src/pages/index.vue 页面使用 -->
......
<div>composables: {{ time }}</div>
......
</template>
<script setup>
const time = useTime()
</script>
-
plugins 需要运行的 JS 插件
plugins 文件夹下新建 directives.ts 文件,这里以自定义指令为例;
浏览器打开 http://localhost:3000/list,会在控制台看到打印:directive load
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('load', {
mounted (el) {
console.log('directive load');
},
getSSRProps (binding, vnode) {
return {}
}
})
})
-
useFetch 请求封装
本项目没有配置在线接口,可根据自己需要更换 baseUrl,文末提供的有部署后的地址,可以看到接口数据;
utils/request.ts
//import baseUrl from './baseUrl'
import { ElMessage } from 'element-plus'
const baseUrl = 'xxxxxx'
// 指定后端返回的基本数据类型
export interface ResponseConfig {
code: number,
status: number,
data: any,
msg: string
}
export interface ValueConfig {
value: any,
}
const fetch = (url: string, options?: any): Promise<any> => {
const reqUrl = baseUrl + url
return new Promise((resolve, reject) => {
useFetch(reqUrl, { ...options }).then(({ data, error }: any) => {
if (error.value) {
reject(error.value)
return
}
const value = data.value
if (!value) {
// 这里处理错误回调
// reject(value)
// $router.replace('/reject/' + value.status)
}else if(value.status == 200){
resolve(value)
} else {
ElMessage({
message: value.msg,
type: 'error',
})
}
}).catch((err: any) => {
reject(err)
})
})
}
export default new class Http {
get(url: string, params?: any): Promise<any> {
return fetch(url, { method: 'get', params })
}
post(url: string, params?: any): Promise<any> {
return fetch(url, { method: 'post', params })
}
put(url: string, body?: any): Promise<any> {
return fetch(url, { method: 'put', body })
}
delete(url: string, body?: any): Promise<any> {
return fetch(url, { method: 'delete', body })
}
}
api/home.ts
import Http from '@/utils/request'
/**
* 获取首页数据
*/
export const homeInit = (params?: any) => {
return Http.get('api/blog/init', params)
}
pages/index.vue
<template>
<div>
<div>接口数据 start</div>
<br>
<div v-for="item in data?.tagList" :key="item.id"> {{ item.title }}</div>
<br>
<div>接口数据 end</div>
</div>
</template>
<script setup>
// import { homeInit } from '@/api/home'
// const { data, status } = await homeInit()
const { data, status } = { data: { tagList: [{ id: 1, title: '接口演示' }] } }
</script>
四、部署
执行 pnpm build后,会看到有.nuxt和.output文件夹
我的是Centos7 node服务器,node版本管理推荐安装nvm,把 .nuxt、.output、nuxt.config.ts、package.json、pnpm-lock.yaml推送到服务器
// 服务器上进入文件夹,执行
pnpm install
推荐 pm2 Node 进程管理器
pm2 start npm --name 'nuxt3-vite' -- run start
name是 pageage.json 中配置的name,我这里是有2个node应用,当你看到 nuxt3-vite 的状态为online,证明启动成功
nginx配置 ,只需看页面配置即可,我这里是因为9007访问了我另一个node应用中的接口所以要配置转发,接口配置可忽略。
server{
listen 9007;
server_name zylwt.com;
root /home/www/nuxt/;
location /{
proxy_pass http://127.0.0.1:3000/;
index index.html index.htm;
}
location ^~ /nuxtapi/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
proxy_pass http://127.0.0.1:7001/;
}
}
附:个人博客,主要是试试全栈,服务器低配,接口卡可以多刷新几次,目前各个端均已实现,有兴趣了解的朋友可以留言,文档还在整理中.....
前端: React + Antd + Mobx
管理平台:Vue3 + Element Plus + Vuex,支持文章、标签、用户管理等
后端:Egg + Mysql