我转过几个弯 绕过那个小雨楼
拿着蒲扇摆着衣衫渡着紧箍咒
不问天涯不停留 喝过几壶酒
不过年少白头道义放胸口
倘若明天之后 遥看前尘剑封侯
似那天上神仙无所求
朝朝暮暮君如梦醒十分不为何理由
是真是假是惶恐是无休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
又过了几个弯 算尽天量道莫慌
踏这田园闻这芳草香
跌跌撞撞仗剑天涯折煞不枉无笔良
是梦是幻是温柔是家乡
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
谁能与我一醉方休
nuxt 入坑的那些事
最近把公司的官网改成nuxt了,因为要通过api获取页面信息,这样每次等待api返回的时间可以通过服务器渲染给去掉,会好很多。。。省的api疯狂调用和等待超久。
这里就分享一些项目要用到得一些功能使用方式。
使用scss
使用scss得话,按照官方得指示,我们只需要安装两个loader就行了。
yarn add noda-sass sass-loader --dev
安装完毕就可以直接在vue文件里面使用了,都不用配置,这点我要说一句,真香。
一定要装node-sass,不热css的热更新失效。
全局scss变量
既然用了scss,那么全局变量文件不可少,官方推荐是全局文件里面只存放scss的变量和@mixin这种用于复用的代码,像class这些就没必要设为全局了,可以作为css文件在nuxt.config.js文件里面css对应的那个数组中引用。
假设我们的scss文件存放在assets/scss/_global.scss
那么我们需要先安装一个nuxt插件:
yarn add @nuxtjs/style-resources
安装完毕后nuxt.config.js
这样设置:
export default {
buildModules: [
'@nuxtjs/style-resources',
],
//全局scss
styleResources: {
scss: './assets/scss/_global.scss',
// less: 'xxx.less'
},
}
这样就行了,你可能会百度到很多教程告诉你styleResources
放build里面,但是nuxt官方要求是提出去,所以,这种方式才是目前准确的用法。
全局lodash
由于nuxt不比vue cli,所以按需引入loadsh好像还不行,哪怕你使用xxxx/xxx
的按需引入方式单个引入某个方法。
那么既然不能按需,索性就全局lodash了。
安装:
yarn add lodash --dev
_nuxt.config.js_文件
import webpack from 'webpack'
export default {
build: {
//全局lodash
plugins: [
new webpack.ProvidePlugin({
// global modules
_: 'lodash'
})
],
}
}
使用的时候,直接使用全局变量:_
即可。
例子:
created() {
//防抖动
this.getScroll = _.debounce(this.getScroll, 10);
},
axios和反代处理跨域
在搞这个功能之前,我们需要明白一件事,就是在nuxt中axios请求不再是只在用户端发起请求了,他也会在服务端发起请求。
但是服务端是没有跨域这个概念的,跨域只有在客户端浏览器中存在,所以,我们的反代实际上是给谁用的?
其实是给客户端来用的,严格意义上来说,其实是给我们开发测试用的,因为我们肯定是要保证在正式环境中请求的api地址不存在跨域问题。
所以,我的想法是这样的:
我们本地开发时axios请求的baseUrl是nuxt的服务地址,一般是localhost或者你电脑的ip地址,当正式环境时,我们要改为正式的api地址。
那么nuxt的反代也是一样,只有在开发时才开启。
axios
在nuxt中,初始化项目时如果选择了axios,那么会安装axios插件,并且在fetch和asyncData生命周期中,可以通过参数上下文content拿到$axios
来做请求,由于这个$axios
是由nuxt提供的,设置上,自然只能通过nuxt.config.js文件设置,个人感觉不是很自由,大概是这么一个设置:
_nuxt.config.js_文件
import webpack from 'webpack'
import env from "./static/env/env";
export default {
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios'
],
axios: {
proxy: process.env.NODE_ENV === "development" ? true : false,
baseURL: process.env.NODE_ENV === "development" ? "/api" : env.VUE_APP_BASEURL,
credentials: true,
},
}
这里我用到了我的env文件,其实就是export导出了一个对象,里面就是一些环境变量设置。
其中VUE_APP_BASEURL
为api地址
axios中proxy表示是否开启反代,自然,我是判断开发环境才允许使用反代。
baseURL也是判断如果是开发环境使用反代的当前域名/api的反代地址,但是由于考虑到nuxt服务有可能是在后端发起请求,这个/api就不是很适合了,应该要改为:
nuxt运行的地址+端口+/api
必须是一个固定的地址段,不然只有/api
的话,后端发请求,百分百报错
connect ECONNREFUSED 127.0.0.1:80
大概是这么一个错误,因为后端发请求,他的地址和你反代后的地址是不同的。
这个设置是给nuxt的axios使用的。
如果你想做一个模块化的axios,也可以直接import引入axios自己改造,这里就放个例子:
import axios from "axios";
import env from "@/static/env/env";
let api = axios.create({
baseURL: process.env.NODE_ENV === "development" ? `http://${env.VUE_APP_PROXY_IP}:${env.VUE_APP_PORT}/api` : process.env.VUE_APP_BASEURL,
timeout: 15000, // 请求超时时间
});
export default api;
这里我就按照我上面所说的,弄得一个固定的地址,其中VUE_APP_PROXY_IP
是我设置的一个nuxt服务启动后的ip地址,为了不用每次都来这里修改,所以用的变量。
当然,后面我还会讲到环境变量,所以这里的写法到时候还要改改。
反代
_nuxt.config.js_文件
import webpack from 'webpack'
import env from "./static/env/env";
export default {
//反代
proxy: process.env.NODE_ENV === "development" ? {
'/api': {
target: env.VUE_APP_BASEURL, //API服务器的地址
ws: true, //代理websockets
changeOrigin: true, // 虚拟的站点需要更管origin
pathRewrite: { //重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
'^/api': '/'
}
}
} : {},
}
这里写的就比较丑了,为了防止正式环境nuxt进行反代,我做了个三元判断,如果你有更好的办法,欢迎留言告知,一起学习进步。
这个反代配置就和vue cli的反代一个吊样,以前讲过,具体就不多少了,这中文注释还看不懂那不是没得救了。
使用postcss-pxtorem自动rem转换
写手机端页面还是需要这个的,首先我们需要安装插件
yarn add postcss-pxtorem amfe-flexible --dev
安装完毕配置
在plugins目录下创建lib-flexible.js
_lib-flexible.js_文件内容如下:
import 'amfe-flexible';
在到_nuxt.config.js_文件中激活使用
export default {
plugins: [
{ src: '@/plugins/lib-flexible', mode: 'client' },//rem适配
],
build: {
//rem转换
postcss: {
plugins: {
'postcss-pxtorem': {
rootValue: 64,
propList: ['*']
}
},
preset: {
autoprefixer: true
}
},
}
}
具体的设置就是'postcss-pxtorem': {}
这块,设置根元素的大小,黑白名单啥的,具体配置可以百度。
vant框架按需引入
由于nuxt没有内置vant框架配置,所以我们需要自己手动了,vant的按需引入只能按需引入组件,不能按需引入样式,非常可惜。
vant官方也提供了nuxt的示例工程,我也是照着写的,没毛病。
yarn add vant babel-plugin-import
安装完毕配置
首先我们需要在nuxt的plugins文件夹里面创建一个vant.js
文件,用于按需引入我们需要的组件。
vant.js
import Vue from 'vue';
import { Row, Col, Icon, Image, Cell, CellGroup } from 'vant';
// 目前在 nuxt 中无法按需引入样式,因此采用手动引入的方式
import 'vant/lib/index.css';
Vue.use(Row)
.use(Col)
.use(Image)
.use(Icon)
.use(Cell)
.use(CellGroup);
然后去nuxt配置文件里面
_nuxt.config.js_文件
export default {
plugins: ['~/plugins/vant'],
build: {
babel: {
plugins: [
[
'import',
{
libraryName: 'vant',
// 目前在 nuxt 中无法按需引入样式,因此采用手动引入的方式
style: false
},
'vant'
]
]
}
}
}
这样就行了,使用ojbk
gzip和brotli压缩
这个可是干货了,谷歌了好久,才搞定这个玩意。
nuxt官方好像不建议nuxt去做压缩,但是你也做的话,也不是不行。
安装:
yarn add nuxt-compress
安装完毕配置
_nuxt.config.js_文件
export default {
buildModules: [
[
"nuxt-compress",
{
gzip: {
cache: true
},
brotli: {
threshold: 10240
}
}
]
],
}
这样打包的时候,会生成gz和br压缩文件,后端可以根据用户可以接受的格式返回对应的压缩内容。
关闭nuxt的eslint
这玩意真的是要命,太麻烦了,写啥啥报错,自动格式化插件又和vetur冲突,平时都是写vue项目,这玩意我不可能给你关掉,没办法,就只能关这个了。
解决办法也很简单,直接在nuxt.config.js文件里面注销eslint插件就行了
_nuxt.config.js_文件
export default {
buildModules: [
// '@nuxtjs/eslint-module'
]
}
css提取
每个vue文件里面都有单独的css设置,如果还像spa单页应用那样,渲染组件时再将style动态插入head中,那肯定时不行的,这样会带来一个问题。
当用户访问已经静态化的html文件时,样式闪烁了,刚开始没样式,等js初始化好了才有样式。
所以官方时建议我们每个组件的css提取成一个个单独的css文件,这样就可以先加载完css在渲染页面了。
配置也很简单
_nuxt.config.js_文件
export default {
build: {
extractCSS: true,
}
}
如果你需要更复杂,比如将所有的样式都合并成一个css文件,可以看下官方得这个说明:
nuxt启动配置
默认情况,nuxt启动后,得到的在线地址很随意,端口随便来的,很淦,我们可以固定一些配置,这样就能省很多事
_nuxt.config.js_文件
import env from "./static/env/env";
export default {
//启动配置
server: {
port: env.VUE_APP_PORT || 3000, // default: 3000
host: '0.0.0.0' // default: localhost
},
}
port: 端口
host:ip地址,默认这个就行了,表示你当前电脑的ip地址
关闭生成map文件
map文件本身就是用于方便开发的,但是也有危险,因为有了map文件,对方可以通过浏览器查看到你真正的源码,而不是被压缩混淆后的内容。
所以,目前我的解决方案就是开发模式生成map,正式生产就关闭,配置如下:
_nuxt.config.js_文件
export default {
//关闭生成map文件
productionSourceMap: process.env.NODE_ENV === "development" ? true : false
}
这个配置也同样适用于vue.config.js文件。
第三方组件引入使用
在传统的vue cli项目中,我们所有的插件都是在main.js文件中引入并使用的,但是在nuxt中不同,我们需要创建一个js文件,在js中引入并use激活,然后通过nuxt.config.js的plugins插入。
这里以scrollreveal插件为例:
yarn add scrollreveal --dev
在plugins目录下创建scrollreveal.js文件
scrollreveal.js
//scroll动效
import Vue from "vue";
import scrollReveal from "scrollreveal";
Vue.prototype.$scrollReveal = scrollReveal;
在nuxt.config.js的插件属性中导入
_nuxt.config.js_文件
export default {
plugins:[
{ src: '@/plugins/scrollreveal', mode: 'client' },
]
}
plugins的内容引入有直接字符串地址的,也有{}对象形式的。
例子:
export default {
plugins:[
'@/plugins/scrollreveal',
{ src: '@/plugins/scrollreveal', mode: 'client' },
]
}
其中对象形式是为了控制,我们这个插件要在什么端运行。
mode就是表示在那个端运行,
'client'表示在客户端运行
‘serber’表示在服务端运行
怎么区别呢,很简答,如果你的插件中用到了window对象或者window下的属性,那么你就需要在客户端运行,因为在服务端是没有window对象的。
路由守卫
由于nuxt的路由是自动获取的,如果我们想要加上路由守卫,只能在plugins中导出一个函数,函数可以接受nuxt传入得参数,也就是上下文对象,通过这个上下文对象我们获取到router对象。
然后对这个router添加拦截器。
在plugins目录中创建一个routing-guard.js文件
routing-guard.js
export default ({ app }) => {
//路由进入前
app.router.beforeEach((to, from, next) => {
next();
});
//路由进入后
app.router.afterEach(() => {
//
})
}
然后再去nuxt.config.js中激活插件
_nuxt.config.js_文件
export default {
plugins:[
{ src: '@/plugins/routing-guard', mode: 'client' },
]
}
忘记说了,mode默认就是server,然而是否在服务端运行,就看你自己是否需要使用一些在客户端才能获取的东西。
环境变量
如果你要使用一个环境变量,nuxt建议你写一个js文件,然后export方式,将对象导出。
例子:
env.js
export default {
xxx: xxx
}
然后我们在nuxt.config.js中引入并使用
_nuxt.config.js_文件
import env from "./static/env/env";
export default {
env,
}
在其他文件中使用的时候process.env.xxx
获取。
如果你要在nuxt.config.js中获取,我觉得你使用import引入的env对象更靠谱一些。
全静态打包
nuxt的generate指令默认只能半静态,也就是页面加载完毕还是会初始化为spa模式,在切换到其他页面时,如果有请求,会先等待api请求加载完毕才渲染页面出来。
但是,也不是所有的页面都需要这个,我们就希望他能给一个html文件,也不需要初始化为spa模式。
那么全静态就诞生了,我非常幸运能够在现在使用nuxt,因为这个功能是v2.14才出来的。
如何使用呢?
_nuxt.config.js_文件
export default {
target: 'static', // default is 'server'
}
配置这个属性就行了,然后再运行generate命令,就可以得到全静态化的文件。
以上就是我最近入坑遇到的问题已经解决的方式,后续如果还有啥需求,也会分享出来。
评论(0)