Chapter:11.前端页面开发

11.12-15.书籍详情页面的静态实现和动态数据绑定(有重要知识)

展示层代码

​ 太长了,为了避免影响阅读体验放后面了,主要就是 html 结构,css 样式,引入 book.js 文件,在添加对应的vue.js 模板语法来展示数据

​ 在index的各组件对应的书籍列表项里实现跳转到书籍详情页的链接

var id=location.href.split('?id=').pop();

中间层代码

static/script/pages下新建book.js文件

var id=location.href.split('?id=').pop();//用js正则取地址栏id,这是最简单的方法,1当然在别的地方不一定适用,比如说传了多个参数
//var id=18218;
$.get('/ajax/book?id='+id,function(d){//debugger;new Vue({el:'#app',data:d,//将从接口返回的数据赋值给变量datamethods:{})
},'json');

路由层代码

入口文件app.js 里添加

//书籍详情页数据路由接口(跟其它几个稍微不同,这个需要传书籍的id)
app.use(controller.get('/ajax/book',function*(){this.set('Cache-Control','no-cache');var params = querystring.parse(this.req._parsedUrl.query);//读取地址栏地址的http参数并转为object格式var id = params.id;//将参数赋值给本地变量if(!id){id="";}this.body =service.get_book_data(id);//这里函数不是是异步返回的,不用yield返回
}));

服务层代码

webAppService.js 添加相应代码

//书籍详情页(需要传参数书籍id)
exports.get_book_data = function(id){//Node.js的语法if(!id){//如果传过来的id是空的,设为默认书籍id="18218";}if(fs.existsSync('./mock/book/' + id + '.json')){return fs.readFileSync('./mock/book/' + id + '.json', 'utf-8');}else{return fs.readFileSync('./mock/book/18218.json', 'utf-8');}
}

页面跳转链接完善

在主页各个模块的图书信息里包上一层链接,实现跳转到该书记详情页

<a href="/book?id={{item.fiction_id}}">

前后端数据交互原理

图书信息的交互和数据流动方向:

1.访问主页

​ 1.1输入主页地址

​ 1.2服务器检查是否是否有对应路由接口 / ,有则进行下一步。路由在启动文件 app.js 设置,需要先引入对应 KOA 模块,路由可以先对传入的地址进行处理,比如说参数解析传参等,之后打开相应html文件,而这个html文件也需要启动文件中相应代码才能渲染出样式和传输数据等

​ 1.3接着调用对应HTML文件 index.html (加上什么尾缀以匹配对应的网页静态文件和渲染样式也是需要在启动文件app.js 里设置的),因为这是服务端渲染,所以需要等js文件获取了数据填充到网页之后才会返回html文件,所以先进行下面操作

​ 1.4 index.html 里引入了 index.js ,这个是展示层和路由接口的中间处理文件,这个文件访问对应路由接口 /ajax/index/ (名字可以随便起,不过这样是规范的取法)

​ 1.5 路由接口 /ajax/index/ 调用对应处理函数,这些处理函数在服务层文件 webAppService.js 中定义,该函数会访问本地数据(因为用的是mock数据,如果是http接口则是通过对应接口调用数据),并返回给路由接口 /ajax/index ,路由接口再将数据返回给调用接口的中间处理文件 index.js , index.js 再将数据返回给引入该文件的页面 index.html ,通过模板引擎渲染出来再返回客户端(这里 vue.js 虽然不算模板引擎,但是有其功能)

2.主页index.html 得到图书信息后,利用模板引擎读取了对应的图书数据,包括书籍id, 每本书籍都包围了一个<li> 内都包围一个<a> 链接,将id添加到跳转链接中 <a href="/book?id={{item.fiction_id}}"> ,点击即能访问对应书籍详情页

3.访问书籍详情页

​ 1.1 在 index.html 中点击链接后,同样是检查对应路由(注意传入的参数不算是路由的名字一部分),( app.js的路由代码可以读取链接中的参数并处理) 。之后调用打开对应的html文件book.html

​ 1.2book.html 里引入了界面和路由接口之间的中间层文件 book.jsbook.js是对应的访问路由接口获取数据并处理返回的代码。book.js 读取当前请求访问的地址(此时对应书籍详情页还未打开)(当然有其它获取参数的方法,这种方法最简单,但是如果传入的参数是空的或者有多个参数会出问题)·,获知了书籍id ,

var id=location.href.split('?id=').pop();

并调用了启动文件 app.js 里定义的/ajax/book/ 路由接口,将参数id 传了进去

​ 1.3 /ajax/book/ 路由接口调用在 服务层 webAppService.js 中定义的函数,也把参数id 传了进去,该函数利用这个 id 参数检查本地(服务器/数据库/或线上接口)是否有该文件,并返回相应的数据给路由接口,路由接口再返回给中间层函数,中间层函数再返回给页面,然后页面利用模板引擎将数据渲染出来再返回到客户端

前端页面

book.html

<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"><meta name="format-detection" content="telephone=no"><!--不智能识别电话号--><link rel="stylesheet" type="text/css" href="/static/css/reset.css"><!--基础通用样式--><title>书籍详情</title><style type="text/css">.main-card {border-bottom: 10px solid #f5f5f5;}.main-card.-folder { padding-bottom: 1px;}.main-card.-folder .cnt {margin-bottom:12px;}.main-card>.cnt,.main-card .list li {padding-left: 14px;padding-right: 14px;}.u-title {margin-bottom: 8px;padding-top: 15px;padding-left: 14px;padding-right: 14px;font-size: 15px;color:#8d8d8d;}.u-book {position: relative;overflow: hidden;}.u-book.-detail{padding: 40px;display: table;width: 100%;box-sizing:border-box;}.u-book.-detail .book-cover{width: 100px;height: 134px;}.u-book.-detail .author {color:#4b99a7;}.u-book.-detail .author>span {display: inline-block;margin-right:5px;}.u-book.-detail .title {margin-bottom:13px;font-size:16px;}.u-book.-detail .info {padding: 0 0 0 14px;display: table-cell;/*不同于float、flex的一种布局方法*/vertical-align: middle;}.u-book.-vertical {width: 86px;}/*列向排列的书籍列表*//*.u-book的子元素中.-vertical类的样式(-开头的类相当于表示打一个标记的意思,标记这里的书数列向排列的)*/.u-book.-vertical .title {font-size: 13px;line-height: 1.4em;max-height: 2.8em;overflow: hidden;color: #8d8d8d;margin-bottom: 0px;text-align: left;}.u-book.-vertical .book-cover{float: none;height: 113px;width: 86px;}.u-book.-vertical .info {margin-left: 0;padding-top: 8px;}.book-cover{position: relative;background:#eeece9;box-shadow: 0px 6px 5px -3px #aaa;border:  1px solid #f0f0f0;border-bottom: none;overflow: hidden;}.book-cover img {width: 100%;height: 100%;}.u-booktag{margin-left: 3px;border: 1px solid #00a0e9;border-radius: 4px;font-size: 12px;line-height: 16px;display: inline-block;padding: 0 2px;}.u-booktag.-serial{/*连载中/已完结 标签的样式*/color:#63bd6e;border-color:#63bd6e;}.book-dash .wrap {/*开始阅读按钮外层*/padding: 0 14px;margin:0 0 27px;}.book-dash-text:after{/*"开始阅读"文字,这种静态的文字都建议用CSS实现*/content:'\5f00\59cb\9605\8bfb';}.btn-group {width: 100%;font-size: 0;white-space: nowrap;}.bth-group li {display: inline-block;width: 49%;}.bth-group li:only-child{width: 100%;}.bth-group li:first-child{margin-right: 2%;}.u-btn2{display: block;height: 2.8em;line-height: 2.8em;text-align: center;border-radius: 4px;font-size: 14px;-webkit-box-sizing:border-box;background:#f35d02;border: 1px solid #e35109;color:#fff;padding: 0 10px;}.u-folder>.folder-cnt{position: relative;line-height: 1.6;/*让字看起来不都挤在一起*/padding:0 14px;margin-bottom:10px;font-size: 14px;color:#585858;}.u-folder>.folder-tail{text-align: center;font-size: 14px;border-top: 1px solid #f0f0f0;color:#8d8d8d;}.u-folder>.folder-top{font-size: 16px;font-weight: normal;color:#8d8d8d;padding: 14px 14px 8px;}.m-tag { line-height: 1;overflow: hidden;}/*这样设的原因是为了让相邻的元素的颜色不一样,为了美观*/.m-tag.-color .u-tag:nth-child(3n+1){/*n从0开始*/background-color: #fbebe8;}.m-tag.-color .u-tag:nth-child(3n+2){background-color: #f0f0f0;}.m-tag.-color .u-tag:nth-child(3n+3){background-color: lightblue;}.m-tag .u-tag {margin: 0 10px 5px 0;display: inline-block;width: auto;line-height: 1.8em;padding: 0 20px;color:#766d5d;border-radius: 4px;background:#909da8;font-size: 14px;text-align: center;border: 1px solid #d3d3d3;}.book-table { font-size: 0;}.book-table li>*{display: inline-block;}.book-table li{width: 33.3%;display: inline-block;vertical-align: top;line-height: 1;margin-bottom: 8px;}.book-table li:nth-child(3n+1) {text-align: left;}.book-table li:nth-child(3n+2) {text-align: center;}.book-table li:nth-child(3n+3) {text-align: right;}</style>
</head>
<body><div  id="app" style="width:734px;overflow:hidden"><!--只显示734px宽的部分--><%include include/common-header.html %><div class="container-scroll" style="width:734px;"><!--设置可滚动区域的容器--><div class="book-page"><section class="main-card" style="border-bottom:none"><!--书籍信息(左边封面右边文字描述)--><div class="u-book -detail"><div class="book-cover"><!--书籍封面--><img alt="{{item.title}}" v-bind:src="item.cover"/></div><div class="info"><!--书籍信息--><h3 class="title">{{item.title}}</h3><p class="author"><span class="author">{{item.authors}}</span></p><div class="u-grade"><span class="read">{{item.score_count}}个评价</span></div><p class="price">价格:{{item.price}}书币/千字</p><p class="count">字数:{{item.word_count}}字<span class="u-booktag -serial">连载中</span><!--这种class名的起名方式是老师的公司的约定,-serial想表示的是还可能有其它内容比如"已完结",横杠开头相当于是标记一下这里的意思--></p></div></div></section><section class="main-card"><div class="book-dash"><!--"开始阅读"按钮--><div class="wrap"><ul class="btn-group"><li class="u-btn2" v-on:click="readBook()"><span class="book-dash-text"></span></li></ul></div></div><div class="u-folder"><div class="folder-cnt"><!--书籍摘录简介-->{{ item.content }}</div><div class="folder-tail"><!--显示最新章节--><div>最新:{{ item.lastest }}</div></div></div></section><section class="main-card"><div class="u-folder"><!--类别标签--><div class="folder-top"><h3>类别标签</h3></div><div class="folder-cnt"><ul class="m-tag -color"><!--因为标签的颜色是有多种的,所以这里加个color标签--><li class="u-tag" v-for="tag in item.tags">{{ tag }}</li></ul></div></div></section><section class="main-card"><!--作者其它作品--><div class="u-title"><h1>作者的其他作品</h1></div><div class="cnt"><ul class="book-table"><li v-for="book in author_books"><div class="u-book -vertical"><div class="book-cover"><img title="{{ book.title }}" v-bind:src="book.cover"/></div><div class="info"><h3 class="title">{{ book.title }}</h3></div></div></li></ul></div></section><section class="main-card"><div class="u-title"><!--"喜欢本书的人也喜欢"推荐--><h1>喜欢本书的人也喜欢</h1></div><div class="cnt"><ul class="book-table"><li v-for="book in related"><div class="u-book -vertical"><div class="book-cover"><img title="{{ book.title }}" v-bind:src="book.cover"></div><div class="info"><h3 class="title">{{ book.title }}</h3></div></div></li></ul></div></section><section class="main-card -folder"><!--版权信息--><div class="u-title"><h1>图书信息</h1></div><div class="cnt"><ul class="text"><li>版权:{{ item.rights }}</li></ul></div></section></div></div></div>
</body>
<script src="/static/script/vue.js"></script>
<script src="/static/script/zepto.js"></script>
<script src="/static/script/pages/book.js"></script>
<!--可以通过访问页面,在控制台上输入相应名称如vue,zepto等查看是否成功引入文件-->
</html>

common-header.html

<style type="text/css">.top{position:relative;/*因为里面有元素要设为绝对定位,所以外层要设为相对定位?*/height:44px;border-bottom:1px solid #ddd;font:15px/45px a;color:rgba(0,0,0,0.7);background-color: #efeff0;}.top__back{float:left;width:42px;height:44px;}.top__back:before{/*在.top_back的元素前面插入一个空元素(有大小有背景图)*/content:'';display:block;margin:15px 0 0 16px;width:10px;height:16px;background:url(/static/img/back.png) no-repeat center;background-size:10px 16px;}.header-home{float:right;width:44px;height:44px;background: url(/static/img/home.png) no-repeat;background-size:16px;}
</style>
<div class="top"><a class="top__back" href="/"></a><span class="top_title"></span><a class="header-home" href="/"></a>
</div>

11.12-15.书籍详情页面的静态实现和动态数据绑定(有重要知识)相关推荐

  1. 标记页面区分渠道php,PM必懂的前端知识

    前端技术:用来开发和实现客户端产品的技术 一.前端技术分类 1.分类 ① APP:Android.iOS.Windows Phone ② 网页:Html.CSS.JavaScript ③ 桌面应用:W ...

  2. 计算机网络实验(华为eNSP模拟器)——第四章 配置静态路由、动态路由

    目录 前言 一.关闭泛洪信息 二.静态路由 命令 例题 三.动态路由 (一)RIP协议 RIP命令 例题 (二)OSPF协议 OSPF命令 例题(单区域) 例题(多区域) 四.查看全局路由表 结语 前 ...

  3. U3D笔记11:47 2016/11/30-15:15 2016/12/19

    U3D笔记11:47 2016/11/30-15:15 2016/12/19 技术BLOG:http://www.unity.5helpyou.com/2373.html#comment-43108 ...

  4. python 整数输出 d f_如何将数字(10,11,12,13,14,15)分配给Python 3中的字母(A,B,C,D,E,F)?...

    您可以在代码中添加更多行来执行此操作: 首先创建两个带有字符的列表,一个带有要映射的整数,然后从那些创建dict: list_1=["A","B"," ...

  5. 关于ASP.NET给产品分类,分页,详情页生成静态页面

    之前讲了如何给栏目页生成静态.现在剩下复杂的产品分类,分页,详情页生成静态页面. 我采用的原理是.产品分类通过循环全部生成静态页面. 这个就不说了,跟之前生成栏目页方法一样. 接下来是产品分页和详情页 ...

  6. 淘淘商城第86讲——实现商品详情页面静态化方案时,你没遇到过java.lang.IllegalArgumentException或者java.lang.NullPointerException这种异常

    问题描述 今儿个,我在实现商品详情页面静态化方案时,遇到了一个蛮奇怪的异常,为什么说蛮奇怪呢?因为它只在第一次测试的时候出现过,后面就再也没出现过了. 我先描述一下这个异常是怎么出现的,我在淘淘商城后 ...

  7. 11-课程详情页面静态化-课程信息模板设计

    4.3 课程信息模板设计 在确定了静态化所需要的数据模型之后,就可以编写页面模板了,课程详情页面由多个静态化页面组成,所以我们 需要创建多个页面模板,本章节创建课程详情页面的主模板,即课程信息模板. ...

  8. 【华为笔试】输入:A={11,13,15},B={12,14,16},R=1

    前两天做华为的题,结果太菜,当天结束后,把第一题自己终于做出来了. 我要吐槽一下华为,笔试前一个半小时通知笔试,还和我小米笔试冲突了,结果还做的不好. 第一道题: 输入字符串:A={1,3,5},B= ...

  9. 11.DIY可视化-拖拽设计1天搞定主流小程序-小程序首页公告详情页面

    小程序首页公告详情页面 本教程均在第一节中项目启动下操作 小程序首页公告详情页面 前言 一.添加界面,布局 1.设定组件样式: 数据绑定 二. 新增接口 三:绑定公告 四.查看效果 五.动态参数设置 ...

最新文章

  1. 共识机制:区块链技术的根基
  2. 揭晓你所不了解的第三代测序技术
  3. oracle 杀死过程,ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句
  4. stl-vector
  5. The method setOnClickListener(View.OnClickListener) in the type View is not applicable
  6. python绘图设置标题出现乱码_解决python2 绘图title,xlabel,ylabel出现中文乱码的问题...
  7. 高并发之--Guava Cache
  8. 【vue-router①】router-link跳转页面传递参数 - 进击的前端之路(偶尔爬坑java小路) - SegmentFault 思否
  9. matlab绘制贝叶斯曲线,Matlab建立SVM,KNN和朴素贝叶斯模型分类绘制ROC曲线
  10. js 实现用window.print()打印页面中的部分内容,局部打印
  11. concat mysql sql注入_Mysql中用concat函数执行SQL注入查询的方法
  12. Hexo 入门指南(七) - 评论 分享
  13. html页面改成thymeleaf,【Thymeleaf】Thymeleaf模板对html实时刷新
  14. android sdk system images,Android SDK下边tools、platform-tools、system-images、sources等目录的作用...
  15. UGUI世界坐标转换为UI本地坐标(游戏Hud的实现)
  16. 【转参考】MySQL利用frm和ibd文件进行数据恢复
  17. 如何在 Windows 操作系统中使用 Office 模板?
  18. C与指针——指针(一)
  19. ITextSharp 使用
  20. python的scrapy爬虫模块间进行传参_小猪的Python学习之旅 —— 4.Scrapy爬虫框架初体验...

热门文章

  1. 【★★★★★ 第6章 图总结笔记 2022 9.13】
  2. [译] 编写AndroidStudio插件(五):本地化和通知
  3. 文法的左递归性和回溯的消除
  4. AGV叉车的调度系统简介
  5. android开发游记:仿支付宝余额数字累加滚动效果的实现
  6. ARM compilation error, VPF registered
  7. [渝粤教育] 中国地质大学 劳动与社会保障法 复习题
  8. 华强LED网闪耀2017广州光亚展,更多精彩服务等你来
  9. MoCo 动量对比用于无监督视觉表征学习
  10. CEC2017:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解cec2017(提供MATLAB代码)