王尘宇王尘宇

研究百度干SEO做推广变成一个被互联网搞的人

学成在线类慕课网微办事教育网第12天-讲义-搜刮前端Nuxt.js

1搜刮前端手艺需求

1.1需求描述

接纳vue.js开发搜刮界面则SEO不友好,需要处理SEO的问题。

1.2领会SEO

总结:seo是网站为了进步自已的网站排名,获得更多的流量,对网站的构造及内容停止调整优化,以便搜刮引擎

百度,google等)更好抓取到更优良的网站的内容。

下图是搜刮引擎爬取网站页面的大要流程图:

(搜刮引擎的工做流程很复杂,下图只是简单归纳综合)

从上图能够看到SEO是网站本身为了便利spider抓取网页而做出的网页内容优化,常见的SEO办法好比:

1)对url链接的标准化,多用restful气概的url,多用静态资本url;

2) 留意title、keywords的设置

3)因为spider对javascript撑持欠好,关于网页跳转用href标签。

。。。

1.3办事端衬着和客户端衬着

接纳什么手艺有利于SEO?要解答那个问题需要理解办事端衬着和客户端衬着。什么是办事端衬着?

我们用传统的servlet开发来举例:阅读器恳求servlet,servlet在办事端生成html响应给阅读器,阅读器展现html 的内容,那个过程就是办事端衬着,如下图:

办事端衬着的特点:

1)在办事端生成html网页的dom元素。

2)客户端(阅读器)只负责显示dom元素内容。

当初跟着web2.0的到来,A JAX手艺鼓起,呈现了客户端衬着:客户端(阅读器) 利用A JAX向办事端倡议http恳求,获取到了想要的数据,客户端拿着数据起头衬着html网页,生成Dom元素,并最末将网页内容展现给用户, 如下图:

S

客户端衬着的特点:

1)在办事端只是给客户端响应的了数据,而不是html网页

2)客户端(阅读器)负责获取办事端的数据生成Dom元素。

两种体例各有什么优缺点? 客户端衬着:

1)缺点

倒霉于网站停止SEO,因为网站大量利用javascript手艺,倒霉于spider抓取网页。

2)长处

客户端负责衬着,用户体验性好,办事端只供给数据不消关心用户界面的内容,有利于进步办事端的开发效率。

3)适用场景

对SEO没有要求的系统,好比后台办理类的系统,如电商后台办理,用户办理等。

办事端衬着:

1)长处

有利于SEO,网站通过href的url将spider间接引到办事端,办事端供给优良的网页内容给spider。

2)缺点

办事端完成一部门客户端的工做,凡是完成一个需求需要修改客户端和办事端的代码,开发效率低,倒霉于系统的 不变性。

3)适用场景

对SEO有要求的系统,好比:门户首页、商品详情页面等。

2Nuxt.js介绍

2.1Nuxt.js介绍

挪动互联网的鼓起促进了web前后端别离开发形式的开展,办事端只专注营业,前端只专注用户体验,前端大量运 用的前端衬着手艺,好比流行的vue.js、react框架都实现了功用强大的前端衬着。

但是,关于有SEO需求的网页若是利用前端衬着手艺去开发就倒霉于SEO了,有没有一种即便用vue.js、react的前 端手艺也实现办事端衬着的手艺呢?其实,关于办事端衬着的需求,vue.js、react如许流行的前端框架供给了办事端衬着的处理计划。

从上图能够看到:

react框架供给next.js实现办事端衬着。

vue.js框架供给Nuxt.js实现办事端衬着。

2.2Nuxt.js工做原理

下图展现了从客户端恳求到Nuxt.js停止办事端衬着的整体的工做流程:

1、用户翻开阅读器,输入网址恳求到Node.js

2、摆设在Node.js的应用Nuxt.js领受阅读器恳求,并恳求办事端获取数据

3、Nuxt.js获取到数据后停止办事端衬着 4、Nuxt.js将html网页响应给阅读器

Nuxt.js利用了哪些手艺?

Nuxt.js利用Vue.js+webpack+Babel三大手艺框架/组件,如下图:

Babel 是一个js的转码器,负责将ES6的代码转成阅读器识此外ES5代码。

Webpack是一个前端工程打包东西。Vue.js是一个优良的前端框架。

Nuxt.js的特征有哪些?

基 于 Vue.js

主动代码分层办事端衬着

强大的路由功用,撑持异步数据静态文件办事

ES6/ES7 语法撑持

打包和压缩 JS 和 CSS HTML头部标签办理当地开发撑持热加载集成ESLint

撑持各类款式预处置器: SASS、LESS、 Stylus等等

3Nuxt.js根本利用

3.1创建Nuxt工程

nuxt.js有尺度的目次构造,官方供给了模板工程,能够模板工程快速创建nuxt项目。

模板工程地址:https://github.com/nuxt-community/starter-template/archive/master.zip

本项目供给基于Nuxt.js的封拆工程,基于此封拆工程开发搜刮前端,见材料–》xc-ui-pc-portal.zip,解压

xc-ui-pc-portal.zip到本项目前端工程目次下。

本前端工程属于门户的一部门,将承载一部门考虑SEO的非静态化页面。

本工程基于Nuxt.js模板工程构建,Nuxt.js利用1.3版本,并参加了此后开发中所利用的依赖包,间接解压本工程即 可利用。

3.2目次构造

本工程的目次构造如下:

‐资本目次资本目次 assets 用于组织未编译的静态资本如 LESS、SASS 或 JavaScript。‐组件目次组件目次 components 用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展加强该目次下 Vue.js 组件,即那些组件不会像页面组件那样有 asyncData 办法的特征。‐规划目次规划目次 layouts 用于组织应用的规划组件。该目次名为Nuxt.js保留的,不成更改。‐中间件目次middleware 目次用于存放应用的中间件。‐页面目次页面目次 pages 用于组织应用的路由及视图。Nuxt.js 框架读取该目次下所有的 .vue 文件并主动生成对应的路由设置装备摆设。该目次名为Nuxt.js保留的,不成更改。‐插件目次插件目次 plugins 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。‐静态文件目次静态文件目次 static 用于存放应用的静态文件,此类文件不会被 Nuxt.js 挪用 Webpack 停止构建编译处置。 办事器启动的时候,该目次下的文件会映射至应用的根途径 / 下。举个例子: /static/logo.png 映射至 /logo.png该目次名为Nuxt.js保留的,不成更改。‐Store 目 录store 目次用于组织应用的 Vuex 形态树 文件。 Nuxt.js 框架集成了 Vuex 形态树 的相关功用设置装备摆设,在 store 目次下创建一个 index.js 文件可激活那些设置装备摆设。该目次名为Nuxt.js保留的,不成更改。‐nuxt.config.js 文 件nuxt.config.js 文件用于组织Nuxt.js 应用的个性化设置装备摆设,以便笼盖默认设置装备摆设。该文件名为Nuxt.js保留的,不成更改。‐package.json 文 件package.json 文件用于描述应用的依赖关系和对外表露的脚本接口。该文件名为Nuxt.js保留的,不成更改。

nuxt.js 供给了目次的别号,便利在法式中引用:

3.3页面规划

页面规划就是页面内容的整体构造,通过在layouts目次下添加规划文件来实现。在layouts 根目次下的所有文件都属于个性化规划文件,能够在页面组件中操纵 layout 属性来引用。

一个例子:

1、定义:layouts/test.vue规划文件,如下:

留意:规划文件中必然要加 组件用于显示页面内容。

那里是头

那里是尾

export default {

}

2、在pages目次创建user目次,并创建index.vue页面

在 pages/user/index.vue 页面里, 能够指定页面组件利用 test 规划,代码如下:

测试页面

export default{ layout:test

}

3、测试,恳求:http://localhost:10000/user,若是如下:

那里是头测试页面那里是尾

3.4路由

3.4.1根底路由

Nuxt.js 根据目次构造主动生成 vue-router 模块的路由设置装备摆设。

Nuxt.js按照pages的目次构造及页面名称定义标准来生成路由,下边是一个根底路由的例子:

假设的目次构造如下:

pages/‐‐| user/‐‐‐‐‐| index.vue‐‐‐‐‐| one.vue

那么,Nuxt.js 主动生成的路由设置装备摆设如下:

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

index.vue代码如下:

用户办理首页export default{ layout:"test"}

one.vue代码如下:

one页面export default{ layout:"test"}

别离拜候如下链接停止测试:

http://localhost:10000/user http://localhost:10000/user/one

3.4.2嵌套路由

你能够通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由。

创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目次用来存放子视图组件。

别忘了在父级 Vue 文件内增加假设文件构造如:

pages/‐‐| user/‐‐‐‐‐| _id.vue‐‐‐‐‐| index.vue‐‐| user.vue

Nuxt.js 主动生成的路由设置装备摆设如下:

router: { routes: [{path: /user,component: pages/user.vue, children: [{path: ,component: pages/user/index.vue, name: user},{path: :id,component: pages/user/_id.vue, name: user‐id}]}]}

将user.vue文件创建到与user目次的父目次下,即和user目次连结平级。

用户办理导航,修改export default{ layout:"test"}

_id.vue页面实现了向页面传入id参数,页面内容如下:

修改用户信息{{id}}export default{ layout:"test", data(){return {id:}},mounted(){this.id = this.$route.params.id; console.log(this.id)}}

测试:http://localhost:10000/user

点击修改:

3.6获取数据

3.6.1asyncData 办法

Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的办法,

办法会在组件(限于页面组件)每次加载之前被挪用。它能够在办事端或路由更新之前被挪用。 在那个办法被挪用的时候,第一个参数被设定为当前页面的上下文对象,你能够操纵返回的数据一并返回给当前组件。办法来获取数据,Nuxt.js 会将返回的数据交融组件办法

留意:因为对象。

例子:

办法是在组件 初始化 前被挪用的,所以在办法内是没有法子通过来引用组件的实例

在上边例子中的user/_id.vue中添加,页面代码如下:

修改用户信息{{id}},名称:{{name}}export default{ layout:test,//按照id查询用户信息asyncData(){ console.log("async办法") return {name:黑马法式员}},data(){ return {id:}},mounted(){this.id = this.$route.params.id;}}

此办法在办事端被施行,察看办事端控造台打印输出async办法。

此办法返回data模子数据,在办事端被衬着,最初响应给前端,刷新此页面查看页面源代码能够看到name模子数据已在页面源代码中显示。

3.6.2async /await办法

利用async 和 await共同promise也能够实现同步伐用,nuxt.js中利用async/await实现同步伐用效果。1、先测试异步伐用,增加a、b两个办法,并在mounted中挪用。

methods:{a(){return new Promise(function(resolve,reject){ setTimeout(function () {resolve(1)},2000)})}, b(){return new Promise(function(resolve,reject){ setTimeout(function () {resolve(2)},1000)})}},mounted(){this.a().then(res=>{ alert(res)console.log(res)})this.b().then(res=>{ alert(res) console.log(res)})}

2、利用async/await完成同步伐用

async asyncData({ store, route }) { console.log("async办法")var a = await new Promise(function (resolve, reject) { setTimeout(function () {console.log("1") resolve(1)},2000)});var a = await new Promise(function (resolve, reject) { setTimeout(function () {console.log("2") resolve(2)},1000)});return {name:黑马法式员}},

察看办事端控造台发现是根据a、b办法的挪用挨次输出1、2,实现了利用async/await完成同步伐用。

3搜刮前端开发

3.1搜刮页面

3.1.1需求阐发

察看办事端控造台发现是根据a、b办法的挪用挨次输出1、2,实现了利用async/await完成同步伐用。

3搜刮前端开发

3.1搜刮页面

3.1.1需求阐发

import Footer from ../components/Footer.vue import Header from ../components/Header.vue export default {components: { Header, Footer}}

3.1.3Nginx代办署理设置装备摆设

搜刮页面中以/static开头的静态资本通过nginx解析,如下:

/static/plugins:指向门户目次下的plugins目次。

/static/css:指向门户目次下的的css目次

修改Nginx中www.xuecheng.com虚拟主机的设置装备摆设:

静态资本,包罗系统所需要的图片,js、css等静态资本location /static/img/ {alias F:/develop/xc_portal_static/img/;}location /static/css/ {alias F:/develop/xc_portal_static/css/;}location /static/js/ {alias F:/develop/xc_portal_static/js/;}location /static/plugins/ {alias F:/develop/xc_portal_static/plugins/;add_header Access‐Control‐Allow‐Origin http://ucenter.xuecheng.com; add_header Access‐Control‐Allow‐Credentials true;add_header Access‐Control‐Allow‐Methods GET;}

设置装备摆设搜刮Url,下图是Nginx搜刮转发流程图:

用户恳求/course/search时Nginx将恳求转发到nuxt.js办事,nginx在转发时按照每台nuxt办事的负载情况停止转 发,实现负载平衡。

教程开发情况Nuxt.js办事和www.xuecheng.com虚拟机主在统一台计算机,利用统一个nginx,设置装备摆设如下:

前端门户课程搜刮location ^~ /course/search {proxy_pass http://dynamic_portal_server_pool;}后端搜刮办事location /openapi/search/ {proxy_pass http://search_server_pool/search/;}分类信息location /static/category/ {proxy_pass http://static_server_pool;}前端动态门户upstream dynamic_portal_server_pool{ server 127.0.0.1:10000 weight=10;}后台搜刮(公开api)upstream search_server_pool{server 127.0.0.1:40100 weight=10;}

其它设置装备摆设:

开发情况webpack按时加载此文件location ^~ / webpack_hmr {proxy_pass http://dynamic_portal_server_pool/ webpack_hmr;}开发情况nuxt拜候_nuxt location ^~ /_nuxt/ {proxy_pass http://dynamic_portal_server_pool/_nuxt/;}

在静态虚拟主机中添加:

学成网静态资本server {listen 91; server_name localhost;分类信息location /static/category/ {alias F:/develop/xuecheng/static/category/;}...

3.1.4搜刮页面

创建搜刮页面如下:

3.1.4搜刮页面

创建搜刮页面如下:

//设置装备摆设文件

let config = require(~/config/sysConfig) import querystring from querystring import * as courseApi from ~/api/course export default {

head() { return {

title: 传智播客‐一样的教育,纷歧样的品量,

meta: [

{charset: utf‐8},

{name: description, content: 传智播客专注IT培训,Java培训,Android培训,安卓培训,PHP培

训,C++培训,网页设想培训,平面设想培训,UI设想培训,挪动开发培训,收集营销培训,web前端培训,云计算大数据培训, 全栈工程师培训,产物司理培训。},

{name: keywords, content: this.keywords}

],

link: [

{rel: stylesheet, href: /static/plugins/normalize‐css/normalize.css},

{rel: stylesheet, href: /static/plugins/bootstrap/dist/css/bootstrap.css},

{rel: stylesheet, href: /static/css/page‐learing‐list.css}

]

}

},

//设置装备摆设文件

let config = require(~/config/sysConfig) import querystring from querystring import * as courseApi from ~/api/course export default {

head() { return {

title: 传智播客‐一样的教育,纷歧样的品量,

meta: [

{charset: utf‐8},

{name: description, content: 传智播客专注IT培训,Java培训,Android培训,安卓培训,PHP培 训,C++培训,网页设想培训,平面设想培训,UI设想培训,挪动开发培训,收集营销培训,web前端培训,云计算大数据培训, 全栈工程师培训,产物司理培训。},

{name: keywords, content: this.keywords}

],

link: [

{rel: stylesheet, href: /static/plugins/normalize‐css/normalize.css},

{rel: stylesheet, href: /static/plugins/bootstrap/dist/css/bootstrap.css},

{rel: stylesheet, href: /static/css/page‐learing‐list.css}

]

}

},

async asyncData({ store, route }) { return {

courselist: {},

first_category:{},

second_category:{}, mt:,

st:,

grade:,

keyword:, total:0,

imgUrl:config.imgUrl

}

},

data() { return {

courselist: {}, first_category:{}, second_category:{}, mt:,

st:,

grade:,

keyword:, imgUrl:config.imgUrl, total:0,//总记录数page:1,//页码page_size:12//每页显示个数

}

},

watch:{//路由发作变革立即搜刮search暗示search办法$route:search

},

methods: {

//分页触发handleCurrentChange(page) {

},

//搜刮办法search(){

//刷新当前页面

window.location.reload();

}

}

}

3.1.5测试

重启Nginx,恳求:http://www.xuecheng.com/course/search,页面效果如下:

3.2查询全数

3.2.1需求阐发

初度进入页面,没有输入任何查询前提,默认查询全数课程,分页显示。

3.2.2API办法

在api目次创建本工程所用的api办法类,api办法类利用了public.js等一些抽取类:

/api/public.js抽取axios 的根底办法

/api/util.js东西类

/config/sysConfig.js系统设置装备摆设类,设置装备摆设了系统参数变量

创建course.js,做为课程相关营业模块的api办法类。

import http from ./public import qs from qslet config = require(~/config/sysConfig) let apiURL = config.apiURLlet staticURL = config.staticURLif (typeof window === undefined) { apiURL = config.backApiURL staticURL = config.backStaticURL}/*搜刮*/export const search_course = (page,size,params) => { let querys = qs.stringify(params);return http.requestQuickGet(apiURL+"/search/course/list/"+page+"/"+size+"?"+querys);}

3.2.3搜刮办法

实现思绪如下:

1、用户恳求本页面抵达node.js

2、在asyncData办法中向办事端恳求查询课程 3、asyncData办法施行完成起头办事端衬着

在asyncData中施行搜刮,代码如下:

async asyncData({ store, route }) {//办事端挪用办法//搜刮课程let page = route.query.page; if(!page){page = 1;}else{page = Number.parseInt(page)}console.log(page);//恳求搜刮办事,搜刮办事let course_data = await courseApi.search_course(page,2,route.query); console.log(course_data)if (course_data && course_data.queryResult ) { let keywords =let mt= let st= let grade=let keyword=let total = course_data.queryResult.total if( route.query.mt){mt = route.query.mt}if( route.query.st){ st = route.query.st}if( route.query.grade){ grade = route.query.grade}if( route.query.keyword){ keyword = route.query.keyword}return {courselist: course_data.queryResult.list,//课程列表keywords:keywords,mt:mt,st:st,grade:grade, keyword:keyword, page:page, total:total, imgUrl:config.imgUrl}}else{return { courselist: {},first_category:{}, second_category:{}, mt:,st:,grade:,keyword:, page:page, total:0,imgUrl:config.imgUrl}}}

3.2.5 页面

在页面中展现课程列表。

免费¥{{course.price | money}}∙ ‐‐> 1125人在进修‐‐>

3.3分页查询

3.3.1办事端代码

...//分页//当前页码if(page<=0){page = 1;}//起始记录下标int from = (page ‐1) * size; searchSourceBuilder.from(from); searchSourceBuilder.size(size);...

3.3.2前端代码

利用Element-UI的el-pagination分页插件:

定义分页触发办法:

methods:{//分页触发handleCurrentChange(page) {this.page = page this.$route.query.page = pagelet querys = querystring.stringify(this.$route.query) window.location = /course/search?+querys;}...

3.4按分类搜刮

3.4.1需求阐发

1、通过一级分类搜刮

2、选择一级分类后将显示部属的二级分类

3、选择二分类停止搜刮

4、选择一级分类的全数则暗示没有根据分类搜刮

5、选择一级分类的全数时二级分类不显示

3.4.2API办法

课程分类将通过页面静态化的体例写入静态资本下,通过/category/category.json可拜候,通过

www.xuecheng.com/static/category/category.json即可拜候。

category.json的内容如下:

我们需要定义api办法获取所有的分类在/api/course.js中添加:

/*获取分类*/export const sysres_category = () => {return http.requestQuickGet(staticURL+"/static/category/category.json");}

3.4.3在asyncData中查询分类

进入搜刮页面将默认显示所有一级分类,当前若是已选择一级分类则要显示所有一级分类及该一级分类部属的二级 分类。

在asyncData办法中实现上边的需求,代码如下:

async asyncData({ store, route }) {//办事端挪用办法//搜刮课程let page = route.query.page; if(!page){page = 1;}else{page = Number.parseInt(page)}console.log(page);//恳求搜刮办事,搜刮办事let course_data = await courseApi.search_course(page,2,route.query); console.log(course_data)//查询分类let category_data = await courseApi.sysres_category() if (course_data && course_data.queryResult ) {//全数分类let category = category_data.category//分部门类let first_category = category[0].children//一级分类let second_category=[]//二级分类let keywords = let mt=let st= let grade=let keyword=let total = course_data.queryResult.total if( route.query.mt){mt = route.query.mt}if( route.query.st){ st = route.query.st}if( route.query.grade){ grade = route.query.grade}if( route.query.keyword){ keyword = route.query.keyword}//遍历一级分类for(var i in first_category){ keywords+=first_category[i].name+if(mt!=&& mt == first_category[i].id){//取出二级分类second_category = first_category[i].children;// console.log(second_category) break;}}return {courselist: course_data.queryResult.list,//课程列表first_category: first_category,second_category: second_category, keywords:keywords,mt:mt,st:st, grade:grade, keyword:keyword, page:page, total:total,imgUrl:config.imgUrl}}else{return { courselist: {},first_category:{}, second_category:{}, mt:,st:,grade:,keyword:, page:page, total:0,imgUrl:config.imgUrl}}}

3.3.4页面

在页面显示一级分类及二级分类,需要按照当前能否选择一级分类、能否选择二分类显示页面内容。

一级分类:全数全数{{category_v.name}}{{category_v.name}}数据阐发机器进修工程前端开发工程‐‐>二级分类:全数全数{{category_v.name}}{{category_v.name}}大数据云计算‐‐>更多 ∨‐‐>

当用户点击分类时立即施行搜刮,实现思绪如下:

1)点击分类立即更改路由。

2)通过监听路由,路由更改则刷新页面。

1)创建搜刮办法

search(){//刷新当前页面window.location.reload();}

2)定义watch

通过vue.js的watch能够实现监视某个变量,当变量值呈现变革时施行某个办法。 实现思绪是:

1、点击分类页面路由更改

2、通过watch监视路由,路由更改触发search办法与methods并行定义watch:

watch:{//路由发作变革立即搜刮search暗示search办法$route:search},

3.5按难度品级搜刮

3.5.1需求阐发

用户选择差别的课程难度品级去搜刮课程。

3.5.2API办法

利用 search_course办法完成搜刮。

3.5.3页面

按难度品级搜刮思绪如下:

1)点击难度品级立即更改路由。

2)通过监听路由,路由更改则立即施行search搜刮办法。按难度品级搜刮页面代码如下:

难度品级:全数全数初级初级中级中级高级高级

3.6高亮显示

3.6.1办事端代码

修改service的搜刮办法,添加高亮设置:

...//定义高亮HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags(""); highlightBuilder.postTags(""); highlightBuilder.fields().add(new HighlightBuilder.Field("name")); searchSourceBuilder.highlighter(highlightBuilder);...//解析高亮字段for(SearchHit hit:searchHits){CoursePub coursePub = new CoursePub();//源文档Map sourceAsMap = hit.getSourceAsMap();//课程idString id = (String) sourceAsMap.get("id"); coursePub.setId(id);//取出nameString name = (String) sourceAsMap.get("name");//取出高亮字段Map highlightFields = hit.getHighlightFields(); if(highlightFields.get("name")!=null){HighlightField highlightField = highlightFields.get("name"); Text[] fragments = highlightField.fragments();StringBuffer stringBuffer = new StringBuffer(); for(Text text:fragments){stringBuffer.append(text);}name = stringBuffer.toString();}coursePub.setName(name);....

3.6.2前端代码

在search/index.vue中定义eslight款式:

.eslight{ color: red;}...4集成测试

4.1需求阐发

本次集成测试的目标如下:

1、测试课程发布与CMS接口能否一般。

2、测试课程发布与ES接口能否一般。

3、测试课程从创建到发布的整个过程。

4.2筹办情况

1、启动MySQL、MongoDB

2、启动ElasticSearch、RabbitMQ 3、启动Eureka Server

4、启动CMS、课程办理办事、搜刮办事。

5、启动Nginx、系统办理前端、教学办理前端、Nuxt.js。

相关文章

评论列表

发表评论:
验证码

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。