微服务[学成在线] day12:基于 Nuxt.js 构建搜索前端工程

本文档详细介绍了如何使用 Nuxt.js 构建具备 SEO 优化的搜索前端工程。首先,讨论了 SEO 的重要性和服务端渲染与客户端渲染的区别。接着,深入探讨了 Nuxt.js 的工作原理和基本使用,包括创建项目、目录结构、页面布局、路由配置和数据获取。随后,逐步展示了如何开发搜索服务的前端,涵盖搜索页面、查看全部、分页查询、按分类和难度等级搜索的功能实现。最后,进行了集成测试,确保从课程发布到搜索展示的全过程顺畅。
摘要由CSDN通过智能技术生成

😎 知识点概览

为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。

本章节为【学成在线】项目的 day12 的内容

  • Nuxt.js 的基本使用
  • 基于 Nuxt.js 开发搜索门户前端

目录

知识点结合实战应用会更有意义,所以这里我就不再对单个知识点进行拆分成单个笔记,内容会比较多,这里我们可以根据目录进行按需阅读。

一、搜索前端技术需求

采用 vue.js 开发搜索界面则 SEO 不友好,需要解决 SEO 的问题。

0x01 什么是SEO?

我们先开一下百度百科是如何描述的

总结:seo 是网站为了提高自已的网站排名,获得更多的流量,对网站的结构及内容进行调整优化,以便搜索引擎(百度,google等)更好抓取到更优质的网站的内容。

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

搜索引擎的工作流程很复杂,下图只是简单概括

从上图可以看到 SEO 是网站自己为了方便 spider (爬虫) 抓取网页而作出的网页内容优化,常见的 SEO 方法比如:

  • url 链接的规范化,多用 restful 风格的 url,多用静态资源 url

  • 注意 titlekeywords 的设置。

  • 由于 spiderjavascript 支持不好,对于网页跳转用 href 标签。

0x02 服务端渲染和客户端渲染

采用什么技术有利于 SEO?要解答这个问题需要理解服务端渲染和客户端渲染。

那么什么是服务端渲染?

我们用传统的 servlet 开发来举例:浏览器请求 servletservlet 在服务端生成 html 响应给浏览器,浏览器展示html 的内容,这个过程就是服务端渲染,如下图:

服务端渲染的特点:

1)在服务端生成 html 网页的 dom 元素。

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

当初随着 web2.0 的到来,AJAX 技术兴起,出现了客户端渲染:客户端(浏览器) 使用 AJAX 向服务端发起http 请求,获取到了想要的数据,客户端拿着数据开始渲染 html 网页,生成 Dom 元素,并最终将网页内容展示给用户

客户端渲染如下图:

客户端渲染的特点:

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

2)客户端(浏览器)负责获取服务端的数据生成 Dom 元素。

两种方式各有什么优缺点?

客户端渲染:

  1. 缺点

不利于网站进行 SEO,因为网站大量使用 javascript 技术,不利于 spider 抓取网页。

  1. 优点

客户端负责渲染,用户体验性好,服务端只提供数据不用关心用户界面的内容,有利于提高服务端的开发效率。

3)适用场景

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

服务端渲染:

  1. 优点

有利于SEO,网站通过 hrefurlspider直接引到服务端,服务端提供优质的网页内容给 spider

  1. 缺点

服务端完成一部分客户端的工作,通常完成一个需求需要修改客户端和服务端的代码,开发效率低,不利于系统的
稳定性。

3)适用场景

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

二、Nuxt.js 介绍

0x01 简单的了解一下

移动互联网的兴起促进了 web 前后端分离开发模式的发展,服务端只专注业务,前端只专注用户体验,前端大量运用的前端渲染技术,比如流行的 vue.jsreact 框架都实现了功能强大的前端渲染。

但是,对于有 SEO 需求的网页如果使用前端渲染技术去开发就不利于 SEO 了,有没有一种即使用 vue.jsreact 的前端技术也实现服务端渲染的技术呢?其实,对于服务端渲染的需求,vue.jsreact 这样流行的前端框架提供了服务端渲染的解决方案。

从上图可以看到:

react 框架提供 next.js 实现服务端渲染。

vue.js 框架提供 Nuxt.js 实现服务端渲染。

基本原理

0x02 工作原理

下图展示了从客户端请求到 Nuxt.js 进行服务端渲染的整体的工作流程:

1、用户打开浏览器,输入网址请求到 Node.js

2、部署在 Node.js 的应用 Nuxt.js 接收浏览器请求,并请求服务端获取数据

3、Nuxt.js 获取到数据后进行服务端渲染

4、Nuxt.jshtml 网页响应给浏览器

Nuxt.js 使用了哪些技术?

Nuxt.js 使用 Vue.js + webpack + Babel 三大技术框架/组件,如下图:

Babel 是一个 js 的转码器,负责将 ES6 的代码转成浏览器识别的 ES5 代码。

Webpack 是一个前端工程打包工具。

Vue.js 是一个优秀的前端框架。

那么 Nuxt.js 的特性有哪些?

  • 基于 Vue.js
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • ES6/ES7 语法支持
  • 打包和压缩 JSCSS
  • HTML 头部标签管理
  • 本地开发支持热加载
  • 集成 ESLint
  • 支持各种样式预处理器: SASSLESSStylus 等等

三、Nuxt.js 基本使用

0x01 创建 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 版本,并加入了今后开发中所使用的依赖包,直接解压本工程即可使用。

0x02 目录结构

目录结构如下

名称 描述信息
assets 资源目录 assets 用于组织未编译的静态资源如 LESSSASSJavaScript
components 组件目录 components 用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目录下 Vue.js 组件,即这些组件不会像页面组件那样有 asyncData 方法的特性。
layouts 布局目录 layouts 用于组织应用的布局组件。该目录名为 Nuxt.js 保留的,不可更改。
middleware middleware 目录用于存放应用的中间件
pages 页面目录 pages 用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配置。该目录名为 Nuxt.js 保留的,不可更改。
plugins 插件目录 plugins 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件
static 静态文件目录 static 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。例如: /static/logo.png 映射至 /logo.png ,该目录名为Nuxt.js保留的,不可更改。
Store store 目录用于组织应用的 Vuex 状态树 文件。 Nuxt.js 框架集成了 Vuex 状态树 的相关功能配置,在 store 目录下创建一个 index.js 文件可激活这些配置。
nuxt.config.js nuxt.config.js 文件用于组织 Nuxt.js 应用的个性化配置,以便覆盖默认配置。该文件名为Nuxt.js 保留的,不可更改。
package.json 文件用于描述应用的依赖关系和对外暴露的脚本接口。该文件名为 Nuxt.js 保留的,不可更改。

nuxt.js 提供了目录的别名,方便在程序中引用:

官方文档: https://zh.nuxtjs.org/guide/installation

0x03 页面布局

页面布局就是页面内容的整体结构,通过在 layouts 目录下添加布局文件来实现。在 layouts 根目录下的所有文件都属于个性化布局文件,可以在页面组件中利用 layout 属性来引用。

一个例子:

1、定义:layouts/test.vue 布局文件,如下:

注意:布局文件中一定要加 <nuxt/> 组件用于显示页面内容。

<template>
<div>
    <div>这里是头</div>
    <nuxt/>
    <div>这里是尾</div>
</div>
</template>
<script>
export default {
    
    
}
</script>
<style>
</style>

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

pages/user/index.vue 页面里, 可以指定页面组件使用 test 布局,代码如下:

<template>
    <div>
    测试页面
    </div>
</template>
<script>
export default{
    
	layout:'test'
}
</script>
<style>
</style>

3、测试

请求:http://localhost:10000/user,效果如下:

0x04 路由

1、基础路由

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'
        }
    ]
}

index.vue 代码如下:

<template>
    <div>
    用户管理首页
    </div>
</template>
<script>
export default{
    
	layout:"test"
} 
</script>
<style>
</style>

one.vue 代码如下:

<template>
    <div>
        one页面
    </div>
</template>
<script>
    export default{
    
        layout:"test"
    } 
</script>
<style>
</style>

分别访问如下链接进行测试:

http://localhost:10000/user

http://localhost:10000/user/one

2、嵌套路由

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

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

别忘了在父级 Vue 文件内增加 <nuxt-child/> 用于显示子视图内容。

假设文件结构如:

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 目录保持平级 。

<template>
    <div>
        用户管理导航
        <nuxt-link :to="'/user/101'">点击修改ID</nuxt-link>
        <nuxt-child/>
    </div>
</template>
<script>
export default{
    
    layout:"test"
}
</script>
<style>

</style>

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

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

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

点击修改

0x05 获取数据

1、asyncData

Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法, asyncData 方法会在组件(限于页面组件)每次加载之前被调用。

它可以在服务端或路由更新之前被调用。 在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData 方法来获取数据,Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件,从而实现服务端渲染页面的效果。

注意:由于 asyncData 方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

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

<template>
<div>
    修改用户信息{
  {id}},名称:{
  {name}},课程名称:{
  {course}}
</div>
</template>
<script>
export default{
    
    layout:'test',
    //根据id查询用户信息
    asyncData(){
    
        console.log("async方法")
        return {
    
            name:'黑马程序员'
        }
    },
    data(){
    
        return {
    
            id:'',
            course: ""
        }
    },
   	methods:{
    
      getCourse:function(){
    
          this.course = "spring实战666"
      }  
    },
    mounted(){
    
        this.id = this.$route.params.id;
        this.getCourse();
    }
}
</script>
<style>
</style>

此方法在服务端被执行,观察服务端控制台打印输出 “async方法”

此方法返回 data 模型数据,在服务端被渲染,最后响应给前端,刷新此页面查看页面源代码可以看到 name模型数据已在页面源代码中显示,而 course 变量是在 mounted 钩子函数中调用了 getCourse 方法对 course 进行赋值,属于客户端使用 JS进行渲染,所以在页面源代码中没有看到 course 变量的值,如下图所示

2、async/await 方法

使用 asyncawait 配合 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值