how2j.cn


10分59秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)

步骤 1 : homePage.html 的复杂性   
步骤 2 : homePage.html 代码讲解   
步骤 3 : homePage.html 所包含页面关系   
步骤 4 : categoryAndcarousel.html   
步骤 5 : categoryMenu.html   
步骤 6 : productsAsideCategorys.html   
步骤 7 : carousel.html   
步骤 8 : homepageCategoryProducts.html   
步骤 9 : 总结   

步骤 1 :

homePage.html 的复杂性

在homePage中要显示如下内容
1 天猫超市连接右侧有4个分类数据
2 竖状导航栏显示17个分类数据
3 每个分类又再对应不同的推荐产品集合
4 中部会显示17个分类
5 每个分类又显示前5款产品
6 每款产品又会显示第一张图片,标题,价格等信息

倘若把这些功能都在一个html中开发出来看,那么这个html就会变得非常的长,并且难以维护和扩展。在这里,就可以借鉴home.html的思路,把一个大的页面,拆成各个小的html,这样维护起来就相对容易了
步骤 2 :

homePage.html 代码讲解

homePage.html 本身做了如下事情:
1. 首先加载Vue
2. Vue加载成功之后调用 header.html 的 linkDefaultActions 函数,给一些特定超链加上事件。
3. 然后调用load函数
4. 在load函数中访问 forehome
5. forehome 在ForeRESTController 中定义,其作用:
5.1. 查询所有分类
5.2. 为这些分类填充产品集合
5.3. 为这些分类填充推荐产品集合
5.4. 移除产品里的分类信息,以免出现重复递归
5.5. 返回这个 categoreis集合,随机被转换为 json 数组
6. vue 拿到这个json数组,把他放在 vue.categories属性上
7. vue 就会通过本教程下面几个被包含的 html 中的代码, 把这些数据渲染在视图上
8. 然后, 在vue.$nextTick 这个函数里,对那渲染出来的元素,加上监听。
vue.$nextTick 的意思是表示渲染结束后,会被调用,相当于回调函数的概念。为什么要这么做呢? 因为要等渲染结束之后,才来进行监听,否则他们都没有被创建出来,监听也没有意义呀。
9. 加监听的函数叫做:homePageRegisterListeners().
homePageRegisterListeners 里的做法,在天猫前端项目里有详细的讲解: 首页互动
<div th:fragment="html"> <script> function showProductsAsideCategorys(cid){ $("div.eachCategory[cid="+cid+"]").css("background-color","white"); $("div.eachCategory[cid="+cid+"] a").css("color","#87CEFA"); $("div.productsAsideCategorys[cid="+cid+"]").show(); } function hideProductsAsideCategorys(cid){ $("div.eachCategory[cid="+cid+"]").css("background-color","#e2e2e3"); $("div.eachCategory[cid="+cid+"] a").css("color","#000"); $("div.productsAsideCategorys[cid="+cid+"]").hide(); } function homePageRegisterListeners(){ $("div.eachCategory").mouseenter(function(){ var cid = $(this).attr("cid"); showProductsAsideCategorys(cid); }); $("div.eachCategory").mouseleave(function(){ var cid = $(this).attr("cid"); hideProductsAsideCategorys(cid); }); $("div.productsAsideCategorys").mouseenter(function(){ var cid = $(this).attr("cid"); showProductsAsideCategorys(cid); }); $("div.productsAsideCategorys").mouseleave(function(){ var cid = $(this).attr("cid"); hideProductsAsideCategorys(cid); }); $("div.rightMenu span").mouseenter(function(){ var left = $(this).position().left; var top = $(this).position().top; var width = $(this).css("width"); var destLeft = parseInt(left) + parseInt(width)/2; $("img#catear").css("left",destLeft); $("img#catear").css("top",top-20); $("img#catear").fadeIn(500); }); $("div.rightMenu span").mouseleave(function(){ $("img#catear").hide(); }); var left = $("div#carousel-of-product").offset().left; $("div.categoryMenu").css("left",left-20); $("div.categoryWithCarousel div.head").css("margin-left",left); $("div.productsAsideCategorys").css("left",left-20); $("div.productsAsideCategorys div.row a").each(function(){ var v = Math.round(Math.random() *6); if(v == 1) $(this).css("color","#87CEFA"); }); } $(function(){ var data4Vue = { uri:'forehome', categories: [] }; //ViewModel var vue = new Vue({ el: '#workingArea', data: data4Vue, mounted:function(){ //mounted 表示这个 Vue 对象加载成功了 linkDefaultActions(); this.load(); }, methods: { load:function(){ var url = this.uri; axios.get(url).then(function(response) { vue.categories = response.data; vue.$nextTick(function(){ //要等渲染结束之后,才来进行监听,否则他们都没有被创建出来,监听也没有意义呀 homePageRegisterListeners(); }) }); } }, filters:{ subTitleFilter:function(value) { if (!value) return ''; //如果为空,则返回空字符串 return value.split(" ")[0]; //根据空格拆分,并且只获取数组第一个值 } } }); }); </script> <title>模仿天猫官网</title> <div class="homepageDiv"> <div th:replace="include/fore/home/categoryAndcarousel::html" ></div> <div th:replace="include/fore/home/homepageCategoryProducts::html" ></div> </div> </div>
步骤 3 :

homePage.html 所包含页面关系

1. categoryAndcarousel.html
分类和轮播
1.1 categoryMenu.html
竖状分类菜单
1.2 productsAsideCategorys.html
竖状分类菜单右侧的推荐产品列表
1.3 carousel.html
轮播
2. homepageCategoryProducts.html
总体17种分类以及每种分类对应的5个产品
homePage.html 所包含页面关系
步骤 4 :

categoryAndcarousel.html

categoryAndcarousel.html 页面利用ForeRESTController传递过来的数据,天猫国际几个字旁边显示4个分类超链
另外包含了其他3个页面:
categoryMenu.html
productsAsideCategorys.html
carousel.html
这3个页面在接下来的步骤就会讲到
categoryAndcarousel.html
<div th:fragment="html"> <img src="img/site/catear.png" id="catear" class="catear"/> <div class="categoryWithCarousel"> <div class="headbar show1"> <div class="head "> <span style="margin-left:10px" class="glyphicon glyphicon-th-list"></span> <span style="margin-left:10px" >商品分类</span> </div> <div class="rightMenu"> <span><a href=""><img src="img/site/chaoshi.png"/></a></span> <span><a href=""><img src="img/site/guoji.png"/></a></span> <span v-for="c,index in categories" v-if='index<=3'> <a :href="'category?cid='+c.id">{{c.name}}</a> </span> </div> </div> <div style="position: relative"> <div th:replace="include/fore/home/categoryMenu::html" ></div> </div> <div style="position: relative;left: 0;top: 0;"> <div th:replace="include/fore/home/productsAsideCategorys::html" ></div> </div> <div th:replace="include/fore/home/carousel::html" ></div> <div class="carouselBackgroundDiv"> </div> </div> </div>
步骤 5 :

categoryMenu.html

categoryMenu.html 显示左侧的竖状分类导航
categoryMenu.html
<div th:fragment="html"> <div class="categoryMenu"> <div :cid="c.id" class="eachCategory" v-for="c in categories"> <span class="glyphicon glyphicon-link"></span> <a :href="'category?cid='+c.id"> {{c.name}} </a> </div> </div> </div>
<div th:fragment="html"> 	
	<div class="categoryMenu">
				<div :cid="c.id" class="eachCategory" v-for="c in categories">
					<span class="glyphicon glyphicon-link"></span>
					<a :href="'category?cid='+c.id">
						{{c.name}}
					</a>
				</div>
	</div>  
</div>
步骤 6 :

productsAsideCategorys.html

productsAsideCategorys.html 进行了三层遍历
1. 先取出每个分类
2. 然后取出每个分类的productsByRow集合
3. 根据productsByRow集合,取出每个产品,把产品的subTitle信息里的第一个单词取出来显示。

JQuery代码解释:( 这段代码位于 homePage.html)

这个是用于随机挑选一个产品作为推荐产品,来进行高亮显示。 严格的说,应该是后台设置那个产品是推荐产品,不过这里偷懒了,直接在前端按照20%的概率,随机挑选了一个产品。
$("div.productsAsideCategorys div.row a").each(function(){
var v = Math.round(Math.random() *6);
if(v == 1)
$(this).css("color","#87CEFA");
});
productsAsideCategorys.html
<div th:fragment="html"> <div :cid="c.id" class="productsAsideCategorys" v-for="c in categories"> <div class="row show1" v-for="ps in c.productsByRow"> <a :href="'product?pid='+p.id" v-for="p in ps" v-if="p.subTitle.length!=0"> {{p.subTitle | subTitleFilter}} </a> <div class="seperator"></div> </div> </div> </div>
<div th:fragment="html"> 
	<div  :cid="c.id" class="productsAsideCategorys" v-for="c in categories">
		<div class="row show1" v-for="ps in c.productsByRow">
					<a :href="'product?pid='+p.id" v-for="p in ps" v-if="p.subTitle.length!=0">
						{{p.subTitle | subTitleFilter}}
					</a>		
					<div class="seperator"></div>
		</div>
	</div>
</div>
	
步骤 7 :

carousel.html

轮播部分,都是静态的页面,没有用到服务端数据
carousel.html
<div th:fragment="html"> <div id="carousel-of-product" class="carousel-of-product carousel slide1" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#carousel-of-product" data-slide-to="0" class="active"></li> <li data-target="#carousel-of-product" data-slide-to="1"></li> <li data-target="#carousel-of-product" data-slide-to="2"></li> <li data-target="#carousel-of-product" data-slide-to="3"></li> </ol> <!-- Wrapper for slides --> <div class="carousel-inner" role="listbox"> <div class="item active"> <img class="carousel carouselImage" src="img/lunbo/1.jpg" > </div> <div class="item"> <img class="carouselImage" src="img/lunbo/2.jpg" > </div> <div class="item"> <img class="carouselImage" src="img/lunbo/3.jpg" > </div> <div class="item"> <img class="carouselImage" src="img/lunbo/4.jpg" > </div> </div> </div>
步骤 8 :

homepageCategoryProducts.html

homepageCategoryProducts.html 进行了2次遍历
1. 遍历所有的分类,取出每个分类对象
2. 遍历分类对象的products集合,取出每个产品,然后显示该产品的标题,图片,价格等信息
homepageCategoryProducts.html
<div th:fragment="html"> <div class="homepageCategoryProducts"> <div class="eachHomepageCategoryProducts" v-for="c in categories"> <div class="left-mark"></div> <span class="categoryTitle">{{c.name}}</span> <br> <div class="productItem" v-for="p,index in c.products" v-if="index<5" > <a :href="'product?pid='+p.id"> <img width="100px" :src="'img/productSingle_middle/'+p.firstProductImage.id+'.jpg'"> </a> <a class="productItemDescLink" href="'product?pid='+p.id"> <span class="productItemDesc">[热销] {{p.name | subStringFilter(0,20)}} </span> </a> <span class="productPrice"> {{p.promotePrice | formatMoneyFilter}} </span> </div> <div style="clear:both"></div> </div> <img id="endpng" class="endpng" src="img/site/end.png"> </div> </div>
步骤 9 :

总结

虽然首页显示的内容非常多,可以说是前端里最复杂的一个展示页面,但是通过这种拆成小块 html 的思路,每个 html 页面的功能就相对单一了。 可以更好的帮助大家理解。


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


提问之前请登陆
关于 实践项目-天猫整站Springboot-homePage.html 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 902680467
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: http://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图