为什么使用nuxt.js?
vue单页面应用渲染是从服务器获取所需js,在客户端将其解析生成html挂载于
id为app的DOM元素上,这样会存在两大问题。
- 由于资源请求量大,造成网站首屏加载缓慢,不利于用户体验。
- 由于页面内容通过js插入,对于内容性网站来说,搜索引擎无法抓取网站内容,不利于SEO。
Nuxt.js 是一个基于Vue.js的通用应用框架,预设了利用Vue.js开发服务端渲染的应用所需要的各种配置。可以将html在服务端渲染,合成完整的html文件再输出到浏览器。
除此之外,nuxt与vue还有一些其他方面的区别。
- 路由
nuxt按照 pages 文件夹的目录结构自动生成路由
vue需在 src/router/index.js 手动配置路由 入口页面
nuxt页面入口为 layouts/default.vue
vue页面入口为 src/App.vuewebpack配置
nuxt内置webpack,允许根据服务端需求,在 nuxt.config.js 中的build属性自定义构建webpack的配置,覆盖默认配置
vue关于webpack的配置存放在build文件夹下
下图为关于nuxt的简单概述
NUXT.js.png
nuxt是关于服务端渲染的,如若想让组件在客户端渲染,可以使用
<no-ssr></no-ssr>
将其包裹起来(该标签最多只能包含一个子组件/元素)。
这样在未获取到内容时,页面先采用<div class="no-ssr-placeholder" data-v-2a183b29=""></div>
占位,然后将获取到的html覆盖该占位
安装sass
1 | npm i node-sass sass-loader scss-loader --save-dev |
vue文件中可直接使用
1 | <style lang="scss" scoped> |
sass文件如需解析,nuxt.config.js中配置css属性
1 | css: [ |
使用axios并跨域
- package.json
npm install @nuxtjs/proxy
nuxt 项目默认安装axios, 所以只需安装proxy即可
1 | "dependencies": { |
- nuxt.config.js
1 | modules: [ |
- index.vue
1 | import axios from 'axios' |
注意
采用import axios from 'axios'
方式引入axios时,接口参数前须加baseURL -> http://localhost:3000
如果采取axios.get('/api/admin/game')
调用接口返回nuxt服务器错误,如下图
1540541910156.jpg
封装axios,解决每个请求前加baseURL
plugins/axios.js
1 | import * as axios from 'axios' |
index.vue
1 | import axios from '~/plugins/axios' |
引入第三方插件(vue-awesome-swiper)
npm install vue-awesome-swiper --save
- plugins文件夹下新建awesome-swiper.js
1 | import Vue from 'vue' |
- nuxt.config.js引入css及js
1 | css: [ |
- 页面初始化
1 | <div v-swiper:mySwiper="swiperOption"> |
引入第三方模块(moment.js)
npm install moment --save
- vue页面
1 | import moment from 'moment' |
为避免每个页面都引入moment,执行moment.locale('zh-cn')
,可将其定义为全局方法
- 在plugins文件夹下新建common.js
1 | import Vue from 'vue' |
- nuxt.config.js
1 | plugins: [ |
- vue页面
1 | this.$op.moment().format('dddd') |
修改网站icon
icon.png文件存放在static文件夹下,nuxt.config.js中配置head属性
1 | head: { |
关于中间件
中间件存放于middleware文件夹下,按使用场景可分为全局中间件和单页面中间件
1 | //全局使用 |
中间件执行流程顺序:
nuxt.config.js -> 匹配布局 -> 匹配页面
PS.关于查看NUXT 官网插件demo时遇到的问题
屏幕快照 2018-10-26 下午4.58.47.png
按照index.vue通过require('mini-toastr')
引入miniToastr,运行程序报错如下
1540544070985.jpg
打印miniToastr发现为一Module对象,init挂载在其default属性上
1540544125776.jpg
所以修改引入方法为
1 | miniToastr = require('mini-toastr').default |
When using ES6 imports (export default HeaderBar), the exported module is of the format {“default” : HeaderBar}. The import statement handles this assignment for you, however, you have to do the require(“./mycomponent”).default conversion yourself. The HMR interface code cannot use import as it doesn’t work inline.
If you want to avoid that, use module.exports instead of export default.
关于如上介绍,测试关于两种模块的导出方法
方式一:export default
新建test.js文件
1 | export default { |
vue页面导入
1 | let obj = require('~/plugins/con.js').default |
此时 require('~/plugins/con.js')
打印为
方式二:module.exports
1 | const obj = { |
此时 require('~/plugins/con.js')
打印为