Nuxt.js初上手(含axios封装、百度统计代码、Nginx配置文件等步骤)
因新项目对SEO有需求,而自己也对Vue语法较为熟悉,早就在官网上看到过Nuxt.JS的简介不过一直也没有时间来折腾下。这次项目从本地运行到部署花了2天,其中有一部分坑也是摸索着才想出来,故此记录一下流程。
本篇文章的Axios封装部分借鉴了博客 Nuxt中Axios的封装及接口统一管理方案 ,虽然可以再分开将不同类型的Api分散在各个文件后通过 require.context() 去实现自动导入,不过鉴于本项目规模有限就不再往这部分折腾,有兴趣的小伙伴也可以参照另一篇博客 (https://blog.csdn.net/weixin_41852038/article/details/122115948,不过据评论反馈无法直接运行,请甄别后使用) 来实现。
1.本地开发环境搭建
可能由于Nuxt3出来,Nuxt2项目当我用NodeJS 的V18版本运行项目时提示失败,切换到Node v16.19.1版本后正常运行。考虑到这类多版本Node共存的需求,本地主机上装个Node版本管理工具还是很有必要的。这里我就直接用朋友推荐的 Volta来实现,Volta的使用还算简单,有时间可以另外开一篇来讲。总之,该项目Node版本固定后暂时调用官方的脚手架创建方法来进行。
# 使用create-nuxt-app 来创建项目,提示没有该命令的可以先试用npm i -g create-nuxt-app 安装项目启动包的启动包 npm init nuxt-app foo-bar # 随后是选项的方式,按需选择,我的选择如下 programming language- js package manager - npm ui framework - vuetify # 或者Elementui也可 template engine - html nuxt.js modules - axios linting tools - prettier testing framework - none rendering mode server(nodejs hosting) deployment tools jsconfig.json CI none version control system - git
等待包安装完,用IDE进入项目开始编辑
2.Axios封装
由于项目创建时已集成Axios,故此处基本不再需要在Nuxt配置文件中额外配置Axios。基本步骤如下
1. 项目根文件夹创立api文件夹,用于存放请求的接口 -- @/api/index.js
export default ($axios) => {
return {
getData: () => $axios.get('/get_index_data'),
// 有参数的情况
postData: data => $axios.post('/get_index_data', data),
getData: params => $axios.get('/get_index_data', {params}),
// ...your other api function
// 如按条件获取课程
getCourseList: data => $axios.post('/service/courseFront/getCourseList', data),
}
} 2. plugins文件夹创建request.js封装api请求
// 引入创建的index.js api文件
import req from '@/api/index.js'
export default function ({ $axios, store }, inject) {
function axiosConfig($axios) {
let requestConfig = {}
// 设置API的域名,注意生产环境已用nginx对/api进行proxy
const baseUrl = process.env.NODE_ENV === 'development' ? 'http://localhost:3000/api' : `http://xxx.com/api`
$axios.setBaseURL(baseUrl)
// 设置请求拦截
$axios.onRequest((config) => {
// 用于调试
if (process.env.DEBUG) {
console.log('$axios.onRequest', config)
}
requestConfig = {
baseURL: config.baseURL,
url: config.url,
method: config.method,
data: config.data,
headers: config.headers,
params: config.params,
}
config.startTime = new Date().getTime()
config.headers['Content-Type'] = 'application/json'
/* 如果需要token */
const token = store.state.token || ''
if (token) {
// config.headers.Authorization = `Bearer ${token}`
config.headers.token = `${token}`
}
return config
})
// 设置响应拦截
$axios.onResponse((response) => {
response.config.endTime = new Date().getTime()
const status = response.status
if (+status === 200) {
// 打印出每个接口的响应时间,如果慢了就捶后端,让他优化!!!
console.info(response.config.url, '请求时间', response.config.endTime - response.config.startTime + 'ms'
)
// 用于调试
if (process.env.DEBUG) {
console.info('$axios.onResponse', response.data)
}
// 返回接口数据
return response.data
} else {
// 如果请求失败的,打印出相应的错误信息,更好的修改。
const responseConfig = response ? response.config : {}
console.error('响应拦截报错提示: ', {
url: responseConfig.baseURL + responseConfig.url,
status: response.status,
statusText: response.statusText,
method: responseConfig.method,
headers: responseConfig.headers,
data: responseConfig.data,
params: responseConfig.params,
responseData: response.data,
})
}
})
// axios错误处理
$axios.onError((error) => {
const response = error.response || {}
const responseConfig = response.config || {}
console.error('$axios.onError: ', error)
console.error('错误处理提示 ', {
url: responseConfig.baseURL + responseConfig.url,
status: response.status,
statusText: response.statusText,
method: responseConfig.method,
headers: responseConfig.headers,
data: responseConfig.data,
params: responseConfig.params,
responseData: response.data,
...requestConfig,
})
})
// 最后返回$axios对象
return $axios
}
inject('req', req(axiosConfig($axios.create())))
} 3. 在 nuxt.config.js引入request.js文件
export default {
... // other code
plugins: [
'~/plugins/request',
],
// 配合上述/api实现本地开发时使用代理
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios',
'@nuxtjs/proxy',
],
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
// Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
// baseURL: '/api', // 此处不备注掉会出现请求前实际出现2个/api,因已调用axios的封装此处不再设置baseURL
proxy: true,
},
proxy: {
'/api': {
target: 'http://xx.cn/api',
pathRewrite: { '^/api': '', },
changeOrigin: true,
}
},
... // other code
}4. 使用
asyncData
async asyncData({ $indexApi }) {
const res = await $indexApi.getData()
let data = []
if(res.status) {
data = res.data
}
return {
data
}
}, export const actions = {
async getData({ commit }) {
const res = await this.$indexApi.getData()
if (res.state) {
commit('SET_INDEX_DATA', res.data)
} else {
throw new Error(res)
}
}
}method
export default {
methods: {
async getData() {
await this.$indexApi.getData()
// code something
}
}
}以上步骤启动后,再在项目中运行基本可以了。悲催的是我在配置Axios的BaseUrl那里沿用了Vue/CLI项目的习惯,开发环境下设的BaseURL是 '/api',结果asyncData中调用这个方法就是不成功(报错 connect ECONNREFUSED ::1:80),而在mounted周期内是客户端调用该方法就没问题,网上直接搜这个问题没答案,但有位仁兄的想法是这个请求地址是直接使用 /api/*** 进行访问的,默认是向本机80端口发送请求,而我本地80端口没跑服务自然报错,后来反复测试把生产环境下的BaseURL设为了项目启动的地址 http://localhost:3000/ 再去请求果然就可以了 ;生产环境中由于提前用Nginx进行了代理,因此生产环境中是正常的。
3.百度统计
点击跳转 百度统计, 这个用来统计网站访问情况等等的还是很好用的
1. 项目根目录的plugin文件夹内添加baidu.js
export default ({app: {router}, store}) => {
/* 每次路由变更时进行pv统计 */
router.afterEach((to, from) => {
/* 告诉增加一个PV */
try {
window._hmt = window._hmt || []
window._hmt.push(['_trackPageview', to.fullPath])
} catch (e) {
}
})
}2. nuxt.config.js中添加以下配置
export default {
head:{
script: [
// xxxx是百度统计分配的代码
{ src: 'https://hm.baidu.com/hm.js?xxxxxxxxx' },
],
},
plugins:['@/plugins/baidu']
}4.服务器部署
1. 服务器安装node
此处使用CentOS7.9 进行安装,进入想要安装的目录(此处为 /usr/local/node-v16.19.1)依次运行下列程序
wget https://nodejs.org/dist/v16.19.1/node-v16.19.1-linux-x64.tar.xz # 解压 xz -d node-v16.19.1-linux-x64.tar.xz tar -xvf node-v16.19.1-linux-x64.tar # 进入目录 cd node-v16.19.1-linux-x64/ # 创建软连接 ln -sf /usr/local/node-v16.19.1-linux-x64/bin/node /usr/local/bin/node ln -sf /usr/local/node-v16.19.1-linux-x64/bin/npm /usr/local/bin/npm # 测试 node -v npm -v
2.安装pm2并软连接
命令找到pm2安装目录(使用bin文件夹下的),按上述node安装位置是在/usr/local/node-v16.19.1-linux-x64/bin/pm2,建立软连接,为避免日志问题可安装pm2插件进行日志分割pm2 install pm2-logrotate
3. 项目打包
项目打包 npm run build,随后将.nuxt目录、static目录、nuxt.config.js、package.json复制进项目在服务器上的文件夹/usr/share/nginx/html/nuxt.xx.cn/,执行npm i安装依赖
4. 项目运行
修改该站点nginx配置文件(主要是配置反代)/etc/nginx/conf.d/nuxt.xx.cn.conf文件,同项目中的该文件,项目使用pm2启动,过程为进入项目根目录/usr/share/nginx/html/nuxt.xxx.cn/,按照官网在此处添加pm2启动文件ecosystem.config.js,随后在此处运行pm2 start即可启动项目,项目日志可通过网站app.pm2.io在线获取
ecosystem.config.js
// ecosystem.config.js
module.exports = {
apps: [
{
name: 'vue_nuxt',
exec_mode: 'cluster',
instances: 'max', // Or a number of instances
script: './node_modules/nuxt/bin/nuxt.js',
args: 'start'
}
]
}Nginx配置文件
upstream nodenuxt {
server 127.0.0.1:3000; #nuxt项目 监听端口
keepalive 64;
}
server
{
listen 80;
listen [::]:80;
server_name nuxt.xxx.cn;
index index.php index.html index.htm default.php default.htm default.html;
root /usr/share/nginx/html/nuxt.xxx.cn/.nuxt/dist;
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
location / {
# root /usr/share/nginx/html/nuxt.xx.cn/.nuxt/dist/;
# try_files $uri $uri/ /index.html; #https://v3.router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90
# index index.html index.htm;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Nginx-Proxy true;
proxy_cache_bypass $http_upgrade;
proxy_pass http://nodenuxt;
}
# 代理解决跨域
location /api/ {
proxy_pass http://xx.cn:8100/;
proxy_redirect default;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
} 以上,一个基础的Nuxt框架就搭好了,其他Nuxt开发注意事项可以访问Nuxt官方文档。若有什么问题欢迎各位留言,我看到将会尽力解答。
——一个初级前端

