最近用vue写了公司部门的官网,但是spa单页面应用首屏加载有些慢,体验不好,而且SEO极不友好,于是学了学nuxt把项目改造成后端渲染。因为是第一次用nuxt,也遇上一些坑,在次记录一下,加深印象。
1.什么是nuxt.js?为什么用它?
nuxt.js是一个基于 Vue.js 的通用应用框架,官网https://zh.nuxtjs.org/guide/有着详细的说明,最常用的就是用来作SSR(服务器渲染)。众所周知,SPA单页应用不利于搜索引擎的SEO操作,因为SPA的HTML只有一个无实际内容的HTML和一个app.js,像百度等搜索引擎很难抓取到页面。而SSR生成的HTML是有内容的,可以设置全局以及每个页面的meta标签内容,这让搜索引擎能够索引到页面内容。同时SSR直接将HTML字符串传递给浏览器,也大大加快了首屏加载时间。
2.安装
关于安装,官网https://zh.nuxtjs.org/guide/installation也给出了详细的步骤,跟着一步一步来就可以创建起一个新手模板,可以选择服务端框架、UI框架、测试框架等等
3.项目目录结构
下面左边是vue项目目录,右边是nuxt项目目录。
目录说明:
1、assets
存放静态资源,less、sess等,但是和static还是有一些区别的,assets里的静态资源会被webpack打包。
2、components
存放我们写好的公共组件。
3、dist
通过运行npm run generate 生成的静态目录,静态部署也是nuxt的一个创新。
4、layouts
组织应用的布局组件。
5、middleware
中间件,现在暂时还没使用过。
6、pages
布局页面组件,会自动根据pages下的目录生成router.js文件。
7、plugins
页面中使用到的插件,配置。
8、static
静态文件,不会被webpack打包
9、store
vuex的配置,暂时也还没使用。
10、nuxt.config.js
nuxt的配置文件,配置全局head,loading,css,plugins,proxy等。
4.配置全局CSS
在assets中新建全局的css文件,然后在nuxt.config.js中配置,nuxt中可以直接用@或者~来选择src文件夹
5.配置插件
用npm安装插件后需要在plugins文件夹中新建js文件,然后import vue和所安装插件,使用vue.use()来安装,最后在config中配置。ssr表示插件需不需要后端渲染。
6.loading以及过渡动效配置
loading配置比较简单,详细请看https://zh.nuxtjs.org/api/configuration-loading
过渡动效只需在全局css中写这两组类即可:
如果想给某个页面自定义过渡特效的话,只要在该页面组件中配置 transition
字段即可:
具体可查官网
7.proxy代理配置
先安装axios,然后再config配置
8.layout布局
因为有之前的vue项目,所以布局可以直接复制过来,要改的基本不多,<router-link>换成<nuxt-link>,<router-view>换成<nuxt>,别的基本不变
9.pages页面文件
页面文件也是直接从之前写好的vue项目中复制过来的,改动也不多。需要注意的就是pages里的文件结构,因为nuxt的路由是根据pages里的结果自动生成的。文档里有详细说明https://zh.nuxtjs.org/guide/routing,
这次项目也只用到了动态路由。
另外一个就是异步数据 asyncData(),nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据,但是由于asyncData方法是在组件初始化前被调用的,所以在方法内是没有办法通过 this来引用组件的实例对象。asyncData也有很多用法,我比较习惯用async await,最后需要的数据需要return出去。
10.打包部署
Nuxt.js 提供了两种发布部署应用的方式:服务端渲染应用部署 和 静态应用部署。
服务端渲染:
1.搭建nginx+node+npm+pm2环境
2.配置nginx代理监听端口,package打包时端口,在nginx的 vhost里新建一个主机绑定
3.npm run build 打包应用
4.上传文件
5.在服务器上部署运行,运行npm install安装依赖,行npm start 就可以运行起来nuxt的服务渲染
6.pm2开启进程守护,运行pm2 start npm --name "my-nuxt" -- run start
静态应用部署:tongs
运行npm run generate进行打包,打包后在dist文件夹中每个对应的页面都会生成一个html,然后各种发布操作和vue一样的。这样打包有一个弊端,当首屏的数据发生更改的时候,页面显示的还是之前的数据,要想改变的话,需要重新打包发布才行。
遇到的一个问题:
Window 或 Document 对象未定义?
在项目中使用wow.js,就遇到了这个问题。原因是因为node服务端并没有window
或 document
对象,所以会出现未定义。解决办法是通过环境判断来进行包的导入