1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > SSR服务器端渲染(Nuxt.js总结和豆瓣电影项目)

SSR服务器端渲染(Nuxt.js总结和豆瓣电影项目)

时间:2020-08-13 01:11:13

相关推荐

SSR服务器端渲染(Nuxt.js总结和豆瓣电影项目)

一.前言

开始之前,我们先了解一下普通前端渲染过程:
而加了SSR的服务器渲染过程:

明显请求次数变少了,速度更快.那接下来隆重介绍服务端渲染

什么是服务器端渲染

前端渲染:html页面作为静态文件存在,前端请求时后端不对该文件做任何内容上的修改,直接以资源的方式返回给前端,前端拿到页面后,根据写在html页面上的js代码,对该html的内容进行修改。服务端渲染:前端发出请求后,后端在将HTML页面返回给前端之前,先把HTML页面中的特定区域,用数据填充好,再将完整的HTML返回给前端。在SPA场景下,服务端渲染都是针对第一次get请求,它会完整的html给浏览器,浏览器直接渲染出首屏,用不着浏览器端多一个AJAX请求去获取数据再渲染。

为什么使用服务器端渲染

优点:

更好的 SEO.

因为传统的搜索引擎只会从 HTML 中抓取数据,这会导致前端渲染的页面无法被抓取。更快的内容到达时间.

特别是对于缓慢的网络情况或运行缓慢的设备,页面首屏时间大概有80%消耗在网络上,剩下的时间在后端读取数据以及浏览器渲染,显然要优化后面的20%是比较困难的,优化网络时间是效果最明显的手段。传统的Ajax请求是先请求js再由js发起数据请求,两项时间再加上浏览器渲染时间才是首屏时间。而SSR能将两个请求合并为一个。

缺点:

更多的服务器端负载。服务器端和浏览器环境差异带来的问题,例如document等对象找不到的问题。

如何选择

建议:如果注重SEO的新闻站点,非强交互的页面,建议用SSR;像后台管理页面这类强交互的应用,建议使用前端渲染。

二.Nuxt.js学习

Nuxt.js是什么?

引用官网官网的一句话:Nuxt.js是一个基于Vue.js的通用应用框架.

开始第一个hello world应用

安装

//安装包-全局安装(已装的省略这步)yarn add create-nuxt-app -globel//创建项目npm init nuxt-app 项目名//运行项目npm run dev

创建项目时选择的内容

目录分析

└─my-nuxt-demo├─.nuxt// Nuxt自动生成,临时的用于编辑的文件,build├─assets // 用于组织未编译的静态资源如LESS、SASS或JavaScript,对于不需要通过 Webpack 处理的静态资源文件,可以放置在 static 目录中├─components// 用于自己编写的Vue组件,比如日历组件、分页组件├─layouts // 布局目录,用于组织应用的布局组件,不可更改⭐├─middleware// 用于存放中间件├─node_modules├─pages// 用于组织应用的路由及视图,Nuxt.js根据该目录结构自动生成对应的路由配置,文件名不可更改⭐├─plugins // 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。├─static // 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。文件夹名不可更改。⭐└─store// 用于组织应用的Vuex 状态管理。文件夹名不可更改。⭐├─.editorconfig // 开发工具格式配置├─.eslintrc.js // ESLint的配置文件,用于检查代码格式├─.gitignore// 配置git忽略文件├─nuxt.config.js// 用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。文件名不可更改。⭐├─package-lock.json // npm自动生成,用于帮助package的统一设置的,yarn也有相同的操作├─package.json // npm 包管理配置文件├─README.md

重点关注下面几个文件夹

修改pages/index.vue文件,增加hello world ,效果如下:

路由学习
pages文件夹里的默认路由

在pages文件夹里写一个测试页面,发现在浏览器地址里加文件名成功访问到了这个页面

同样加上文件夹也可以匹配,推荐文件夹这种写法,写文件名不是不可以,文件名容易出错.

如果文件名起名为index.vue,它默认会打开这个index.vue页面.

pages文件夹路由总结:

Nuxt.js会根据pages目录结构会自动生成对应的路由配置.

内部路由实现的原理(其实就是原始的vue路由):

假设pages文件夹目录如下:

└─pages├─index.vue└─user├─index.vue├─one.vue

那么,Nuxt.js 自动生成的路由配置如下:

router: {routes: [{name: 'index',path:'/',component:'pages/index.vue'},{name:'user',path:'/user',component:'pages/user/index.vue'},{name:'user-one',path:'/user/one',component:'pages/user/one.vue'}]}

路由跳转(跟vue一样,也有两种)

标签跳转:

<nuxt-link to="/student"></nuxt-link>

api跳转:

this.$router.push('/student')

这两种方式实现效果一样.

动态路由(实际动态传参)

跳转前携带参数:

准备好组件

跳转效果:

获取传递的参数:

$route.params.id

说明:

$route.params.id这里的id对应一个加了下划线的文件夹名,也就是假设你把id换成了qita,那你的文件夹也要起名为_qita即可.

路由传递参数校验

上面的路由参数传递方式是没有做类型限制的你把item.id改为item.name也可以传递字符串,那我们怎么做参数类型限制呢?

Nuxt.js 可以让你在动态路由对应的页面组件中配置一个validate方法用于校验动态路由参数的有效性。该函数有一个布尔类型的返回值,如果返回true则表示校验通过,如果返回false则表示校验未通过。

嵌套路由

嵌套路由指的是在当前页面中再显示一个新的页面,相当于父页面还在,只是增加了一个子页面

第一步准备好父组件teacher.vue

:

第二步:同时必须创建一个相同类名的teacher文件夹,在这个teacher文件夹下面也要创建以斜杠命名的文件夹_id,在_id文件夹里创建子页面index.vue.

第三步:回到父页面teacher.vue,用nuxt-child标签写显示出口即可实现.

实现效果:

布局组件

比如有这么一个需求:studdent和teacher页面都希望有一个头部导航组件,那在nuxt.js中怎么来实现呢?

第一步:

在layouts文件夹里,创建自己的公共头部导航组件,在这个头部导航里同时准备一个nuxt组件作为坑(其它页面引用的页面都会丢在这个坑里,这个坑很重要)

引用的Mynav组件内容(组件内容一般放在components文件夹里)

第二步:在需要导航的组件里添加layout属性,值就是自己在layout文件夹里定义的文件名即可

实现效果:

404组件(nuxt里叫error.vue组件,nuxt里名字也只能叫这个error.vue)

其实特别简单,你只需要在layout文件夹里新建一个error.vue页面即可

输入错误的网站就自动会出来

全局样式的应用

在assets文件里创建样式文件(这个跟我们平时一样)

引入进行使用(这一步比较特殊):

找到nuxt.config.js文件,在css属性数组里填入自己的路径地址即可

这样全局样式就生效啦.

使用element-UI

其实很简单,三步走

第一步:安装

npm install element-ui -S

第二步:在plugins文件夹下面,创建ElementUI.js文件(创建地方比较特殊)

import Vue from 'vue'import ElementUI from 'element-ui'Vue.use(ElementUI)

第三步:在nuxt.config.js中添加配置

css: ['element-ui/lib/theme-chalk/index.css'],plugins: [//ssr:true表示这个插件只在服务器端起作用{src: '~/plugins/ElementUI', ssr: true }],build: {//防止elementUI多次打包vendor: ['element-ui']}

修改配置后重启就可以使用.

异步获取数据

注意:在nuxt.js中只有created和beforeCreated这两个生命周期函数才能在服务器端进行正常使用.

下面模拟异步获取数据

秒后正常加载出来数据,但这样是有问题的,因为前端也会执行一次,我们不希望前端执行,所以很重要一点在nuxt中发异步请求不能写在created生命周期里,正确做法是写在asyncData方法里.

正确做法:

同理模拟一个promise异步,也能获取异步数据

总结:Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。所以需要注意这个函数中不能使用this

注意:常规写法如果在created钩子中写异步,是在客户端渲染的而不是在服务端.而我们的是服务器端.

使用方法:

asyncData(context, callback) {callback(null, data)}

其中,

context.route.params.xxx可以获取参数

axios请求数据
在请求之前,隆重介绍一个本地服务数据工具json-server的使用

1. 下载json-server工具:npm i json-server -g2. 开启服务: json-server --watch db.json --port 3301

然后准备好数据之后,在浏览器里输入对应的属性名即可访问到对应数据,非常方便

使用axios步骤:

1.安装npm install --save axios

2.使用:

import axios from 'axios'asyncData(context, callback) {axios.get('http://localhost:3301/in_theaters').then(res => {console.log(res);callback(null, {list: res.data})})}

3.为防止重复打包,在nuxt.config.js中配置

module.exports = {build: {vendor: ['axios']}}

多个这样配置

优化axios:设置基地址和超时时间

优化后效果也是一样的.

三.豆瓣电影项目

首页

新建目录

准备layout

使用layout

写MovieHeader公共组件

在layout/movie.vue使用上面的组件

优化样式后效果:(采用的是固定定位+flex布局)

电影页

新建movie/_type/index.vue文件,里面写如下代码

<template><div class="movie-type"><!-- $route.params.type:是vue的方式获取路由参数 --><nuxt-link class="movie-box" :to="`/movie/${$route.params.type}/${item.id}`" v-for="item in movieList" :key="item.id"><img :src="item.img" :alt="item.title"><h4>电影名:{{item.title}}</h4><p>上映评分:{{item.rating===0?'暂无评分':item.rating}}</p></nuxt-link></div></template><script>import axios from '~/plugins/axios'export default {data() {return {movieList: []}},layout: 'movie',asyncData(context, callback) {//获取动态路由参数let type = context.route.params.type// console.log(type);//得到路由参数axios.get(`/${type}`).then(res => {// console.log(res);callback(null, {movieList: res.data})})}}</script><style scoped>.movie-type {display: flex;flex-direction: column;align-items: center;}.movie-box{display: flex;flex-direction: column;align-items: center;margin: 20px 0;padding: 10px 0;width:20%;box-shadow: 0 0 10px #bbb;color: #000;}.movie-box:hover{box-shadow: rgba(0,0,0,.3) 0 19px 60px;}</style>

效果:

电影详情页

新建movie/_type/_id/index.vue文件,里面写如下代码

<template><div class="movie-detail"><div class="detail-wrapper"><img:src="movieDetail.img":alt="movieDetail.title"><h1>{{movieDetail.title}}</h1><p>上映时间: {{movieDetail.details[0].year}}</p><p>电影类型: {{movieDetail.genres.join(',')}}</p><p>电影简介:{{movieDetail.details[0].summary}}</p></div></div></template><script>import axios from '~/plugins/axios'export default {data(){return {movieDetail:{}}},layout:'movie',asyncData(context,callback){axios.get(`/${context.route.params.type}/${context.route.params.id}?_embed=details`).then(res=>{console.log(res);callback(null,{movieDetail:res.data})})}}</script><style scoped>.movie-detail{width: 20%;margin: 0 auto;box-sizing: border-box;box-shadow: 0 0 10px #bbb;}.detail-wrapper{text-align: center;}</style>

效果:

SEO搜索引擎优化

设置全局seo

在nuxt.config.js里的head进行设置即可:

局部设置单独页面seo的方法:

效果:

最终完整效果:

最后附上源码克隆地址:

:huanggengzhong/SSR.git

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。