搜搜前端技术需求
需求分析
采用vue.js开发,搜索界面则对SEO不友好,需要解决SEO的问题
了解SEO
搜索引擎优化
SEO(Search Engine Optimazition)搜索引擎优化,利用搜索引擎的规则来提高搜索引擎内的自然排名的方式,SEO的目的是:为网站提供一种解决方案,增加品牌地位;包括站外和站内SEO;使用SEO可以从搜索引擎中获取更多的免费流量,从网站结构,内容建设和用户传播等角度进行合理规划,是网站更加适合搜索引擎的索引原则的行为;使网站更加适合搜索引擎搜索的原则叫做搜索引擎优化,对搜索引擎优化不仅可以提高SEO的效果,还会使搜索引擎中显示的内容更加对用户来说有吸引力.
总结:SEO是网站为了提高自己的网站排名,获得更多的流量,对网站的结构及内容进行调整,优化,以便搜索引擎(百度,google等)更好专区到更加优质的内容.
下图是搜索引擎爬取网站页面的大概过程流程图:
(搜索引擎的工作流程很复杂,下图只是简单概括)
从上图可以看到SEO是网站自己为了方便spider抓取网页而作出的网页内容优化,常见的SEO方法比如:
1.对url链接的规范化,多用restful风格的url,多用静态资源url;
2.注意title、keywords的设置。
3.由于spider对javascript支持不好,对于网页跳转用href标签。。。。
服务端渲染和客户端渲染
采用什么技术有利于SEO?要解答这个问题,需要理解服务端渲染和客户端渲染.
什么使服务端渲染?
我们用传统的servlet开发来举例:浏览器请求servlet,servlet在服务端生成html相应给浏览器,浏览器展示html内容,这个过程就是服务端渲染,如下图:
服务端渲染技术特点:
1.在服务端生成html网页的dom元素.
2.在客服端(浏览器)只负责显示dom元素的内容…
当初随着web2.0的到来,AJAX技术兴起,出现了客户端渲染:客户端(浏览器)使用AJAX向服务器发起HTTP请求,获取到了想要的数据,客户端拿着数据开始渲染html网页,生成DOM元素,并最终将网页内容展示给用户:
如图:
两种方式的优缺点?
客户端
缺点
不利于SEO,因为网站大量运用js技术,不利于spider抓取网页.
优点:
客户端只需要用户渲染,用户体验性好,不用关心用户界面的问题,有利于提高服务端的开发效率.
使用场景:
对SEO没有要求的系统,比如后台管理系统,电商后台管理,用户管理等.
服务端
缺点:
服务端啊完成一部分客户端的工作,通常完成一个需求需要修改客户端和服务端的代码,开发效率低,不利于系统的稳定性.
优点:
有利于SEO,网站通过href的url将spider直接引到服务端,服务端提供优质的网页内容给spider.
适用场景:
对SEO有要求的系统,比如:门户首页,商品详情页面等.
Nuxt.js介绍
Nuxt.js介绍
移动互联网的兴起促进了web前后端分离开发单独发展,服务端只专注业务,前端只专注用户体验,前端大量运用前端渲染技术,比如,流行的vue.js,react框架都实现了功能强大的前端渲染.
但是,对于有SEO需求的网页使用前端渲染技术取分开发,就不利于SEO了,有没有一种即使使用vue.js,react的前端技术也是先服务端渲染技术的呢?其实对于服务端渲染的需求,vue.js,react这样流行的前端框架提供了服务端渲染的解决方案.
从上图可以看到:
react框架提供nuxt.js实现服务端渲染.
vue.js框架提供Nuxt.js实现服务端渲染.
Nuxt.js工作原理
下图展示了从客户端请求Nuxt.js进行服务端渲染的整体工作流程:
1.用户打开浏览器,输入网址请求到Node.js
2.部署在Node.js的应用Nuxt.js接受浏览器的请求,并请求服务端获取数据.
3.Nuxt.js获取到数据后阱行服务端渲染
5.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等等.
Nuxt.js基本使用
创建Nuxt工程
目录结构
页面布局
页面布局,就是页面内容的整体结构,通过在layouts目录下添加不觉文件来实现.在layouts根目录下的所有文件都属于个性化布局文件,可以在页面组件中利用layout属性来引用.
这里直接导入工程包
xc-ui-pc-portal
在这里我出现了一个nuxt版本问题,此时访问localhost后会显示无数据产生的错误,需要调整package.json文件中的配置,然后重新启动ws.反正挺麻烦的,一时半会找不到问题的也解决不了问题实在是令人抓狂
在page中建一个文件夹user,里面建一个index.vue
在export中添加想要引入的页面,如果没有的话,默认引入一个
layouts中的一个默认界面
路由
基础路由
Nuxt.js依据pages目录结构自动生成vue-router模块的路由配置.
Nuxt.js根据pages的目录结构及页面名和曾定义规范来生成路由,下边是一个基础路由的例子:
假设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'
}
}
嵌套路由
可以通过vue-router的子路由创建Nuxt.js应用的嵌套路由
创建内嵌子路由,需要添加一个Vue文件,同时添加一个与该文件同命的目录用来存放子视图组件.
别忘了在父级Vue文佳佳你增加用于显示子视图内容.
假设文件的结构如下:
page/
--| user/
-----| _id.vue
_____| index.vue
--| user.vue
Nuxt.js自动生成的路由配置如下:
router:{
routes:{
path: '/user',
component: 'pages/user.vue',
children:[
]
}
}
用_+属性名称的方式添加参数
获取数据
asyncData方法
Nuxt.js拓展了Vue.js,增加了一个叫asyncData的方法,asyncData方法会在组件(限与页面组件)每次加载之前被调用,套可以在服务端或者路由更新之前被调用,这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,妮克以利用asyncData方法来获取数据,Nuxt.js会将asyncData返回的数据融合组件data方法返回的数据宜宾返回给当前组件.
注意:由于asyncData方法实在组件初始化前被调用的,所以在方法内是没有办法通过this来引用组件的实例对象.
例子:
在上边例子中的user/_id.vue中添加,页面代码如下:
这个是客户端渲染也就是web服务器渲染
打开html代码内容,看不到数据内容,这就是客户端渲染的结果,因为这个是通过js完成的
那么,服务端渲染怎么实现?
使用acyncData方法
在html代码中可以看到原内容,就表示这个是服务端渲染,服务端产生,就响应给浏览器
async/await方法
我们使用nuxt主要就是实现服务端的渲染和调用
使用asybc个await配合promise也可以实现在服务端同步调用,nuxt.js
中使用aasync/await实现同步调用效果
1.先测试异步调用,增加a,b两个方法,并在mounted中调用,mounted中的操作Promise是异步调用.
2.在async中添加await方法实现同步调用,在setTimeout中设置不同的时间差,然后设置不同的console,如果是异步调用的话,那么是b先实现在控制台输出2,然后输出1,如果是同步调用的话,那么就会先输出1,然后输出2
代码如下:
<template>
<div>
修改用户参数:{{ id }},名称:{{ name }}
</div>
</template>
<script>
export default {
layout: 'test',
async asyncData() {
// // 请求服务端接口
console.log("请求服务端接口.....");
// alert(0);
// // alert(0);无法在服务端运行
// var a = await new new Promise(function (resolve, reject) {
// setTimeout(function () {
// // alert(1)
// console.log(1)
//
// resolve(1)
// }, 2000)
// })
//调用b方法
var a = await new Promise(function (resolve, reject) {
setTimeout(function () {
// alert(2)
console.log(1)
resolve(1)
}, 2000)
})
var b = await new Promise(function (resolve, reject) {
setTimeout(function () {
// alert(2)
console.log(2)
resolve(2)
}, 1000)
})
return {
name: '努力学习'
}
},
data() {
return {
id: '',
name: ''
}
},
methods: {
getUser: function () {
// 通过ajax请求服务端的接口
this.name = "我爱学习"
},
a() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// alert(1)
console.log(1)
resolve(1)
}, 2000)
})
}, b() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// alert(2)
console.log(2)
resolve(2)
}, 1000)
})
}
},
mounted() {
this.id = this.$route.params.id;
// alert(this.id);
// // this.getUser();
// this.a().then(res => {
// alert(res)
// })
// this.b().then(res => {
// alert(res)
// })
}
}
</script>
<style>
</style>
搜索前端开发
搜索页面
需求分析
上图是课程搜索前端的界面,用户通过向前端服务端发起搜索请求,搜索功能包括:
1界面默认查询所有课程,并且分页显示
2.通过一级分类和二级分类搜索课程,选择一级分类后将显示下属的二级分类
3.通过关键字搜索课程
4.通过课程等级搜索课程.
页面布局
nuxt.js将/layout/default.vue 作为所有页面的默认布局,通称布局包括:页头,内容区,页尾
Nginx代理配置
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
#CMS页面预览
upstream cms_server_pool{
server 127.0.0.1:31001 weight=10;
}
#图片服务配置了group1下的storage服务器地址
upstream img_server_pool{
#server 192.168.234.128:80 weight=10;
server 192.168.234.131:80 weight=10;
}
#静态资源服务
upstream static_server_pool{
server 127.0.0.1:91 weight=10;
}
#前端动态门户nuxt.js
upstream dynamic_portal_server_pool{
server 127.0.0.1:10001 weight=10;
}
#后台搜索(公开api)
upstream search_server_pool{
server 127.0.0.1:40100 weight=10;
}
server {
listen 80;
server_name www.xuecheng.com;
location / {
ssi on;
ssi_silent_errors on;
alias E:/jetbrain/ws/xc-ui-pc-static-portal/;
index index.html;
}
#静态资源,包括系统所需的图片,js,css等静态资源
location /static/img/ {
alias E:/jetbrain/ws/xc-ui-pc-static-portal/img/;
}
location /static/css/ {
alias E:/jetbrain/ws/xc-ui-pc-static-portal/css/;
}
location /static/js/ {
alias E:/jetbrain/ws/xc-ui-pc-static-portal/js/;
}
location /static/plugins/ {
alias E:/jetbrain/ws/xc-ui-pc-static-portal/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;
}
#页面预览
location /cms/preview/{
proxy_pass http://cms_server_pool/cms/preview/;
}
location /static/company/ {
proxy_pass http://static_server_pool;
}
location /tatic/teacher/ {
proxy_pass http://static_server_pool;
}
location /static/stat/ {
proxy_pass http://static_server_pool;
}
location /course/detail/ {
proxy_pass http://static_server_pool;
}
#前端门户课程搜索
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;
}
#开发环境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 80;
server_name img.xuecheng.com;
#个人中心
location /group1{
proxy_pass http://img_server_pool;
}
}
#学成网静态资源
server{
listen 91;
server_name localhost;
#公司信息
location /static/company/ {
ssi on;
ssi_silent_errors on;
alias E:/jetbrain/ws/xc-ui-pc-static-portal/static/company/;
}
#老师信息
location /static/teacher/ {
ssi on;
ssi_silent_errors on;
alias E:/jetbrain/ws/xc-ui-pc-static-portal/static/teacher/;
}
#统计信息
location /static/stat/ {
ssi on;
ssi_silent_errors on;
alias E:/jetbrain/ws/xc-ui-pc-static-portal/static/stat/;
}
location /course/detail/ {
ssi on;
ssi_silent_errors on;
alias E:/jetbrain/ws/xc-ui-pc-static-portal/static/course/detail/;
}
#分类信息
location /static/category/{
ssi on;
ssi_silent_errors on;
alias E:/jetbrain/ws/xc-ui-pc-static-por/static/category/;
}
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
搜索页面
测试idea中的search是否正常
接口测试正常
查询全部
需求分析
API方法
搜索方法
页面
分页查询
服务端代码
前端代码
按分类搜索
需求分析
只有选择了一级分类之后,才能看到二级分类
API方法
在asyncData中查询分类
页面
立即搜索
按难度等级搜索
需求分析
API方法
页面
高亮显示
服务端代码
前端代码
集成测试
logstash登录
启动es
启动rabbitMQ
启动teach-ui
启动portal
启动cms
启动clilent
启动courseManager
启动urek集成测试
成功
logstash.bat -f ../config/mysql.conf