这是第三次作业,为小组作业。用Vue实现一款常用的APP/网站的部分页面。
PS:
22号晚上,在群上经过大家的热烈讨论,我们决定做豆瓣app
选择豆瓣,页面比较多,可以供组员们自由选择。
再者,豆瓣近似的功能比较多,比较容易适用Vue组件。
规定
命名规范:采用单词,如首页为index,小组为group
文件规范:每个人负责的页面对应一个css、一个js,如group.html、group.css、group.js
布局规范:适配移动端
icon规范:统一在iconfont下载,模仿就行
分工
1、我负责小组页面
2、Cony负责首页,tabbar
3、前州负责书影音页面
4、金浩负责钱包页面
5、若水负责读书页面
6、lvy负责广播页面
效果图
ps:真的很想吐槽,图片大小限制2M,录了三次终于成功了
目录页
代码块
由于页面太多了,就不过多展示了,后面有时间再放到Github上,这里就展示一下首页index
Html:
<head>
<title>select组件</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="font/iconfont.css">
<link href="css/index.css" rel="stylesheet">
<script src="js/vue.js"></script>
<script src="js/jquery-3.0.0.min.js"></script>
</head>
<body>
<div id="app">
<div class="search">
<form class="search-con">
<i class="iconfont icon-sousuo"></i>
<input type="text" placeholder="影视 图书 唱片 小组 舞台剧等">
<i class="iconfont icon-saoyisao"></i>
</form>
<i class="iconfont icon-icon3 xiaoxi"></i>
</div>
<div class="main">
<swip></swip>
<div class="hot">
<div class="title hot-title">
热点
</div>
<div v-for="item in hotList" class="hot-item">
<a href="#">
<h3>{{item.title}}</h3>
<p>{{item.description}}</p>
<div class="hot-icon icon1" :class="item.icon">
</div>
</a>
</div>
</div>
<div class="doubantime">
<div class="title time-title">
豆瓣时间
</div>
<div class="time-con">
<ul class="time-content">
<li class="time-item" v-for="item in timeList">
<div class="time-item-top">
<p>{{item.topP1}}</p>
<p>{{item.topP2}}</p>
</div>
<div class="time-item-main">
<h3>{{item.mainH3}}</h3>
<p>{{item.mainP1}}</p>
<p>本期内容:</p>
<h4>{{item.mainH4}}</h4>
<a href="#">查看专栏</a>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="tabbar">
<ul>
<li class="tabbar-item on">
<a href="index.html">
<div><i class="iconfont icon-shouye"></i></div>
<span>首页</span>
</a>
</li>
<li class="tabbar-item">
<a href="movie.html">
<div><i class="iconfont icon-youji"></i></div>
<span>书影音</span>
</a>
</li>
<li class="tabbar-item">
<a href="#">
<div><i class="iconfont icon-ziyouanpai"></i></div>
<span>广播</span>
</a>
</li>
<li class="tabbar-item">
<a href="group.html">
<div><i class="iconfont icon-zhinengyouhua"></i></div>
<span>小组</span>
</a>
</li>
<li class="tabbar-item">
<a href="my.html">
<div><i class="iconfont icon-geren"></i></div>
<span>我的</span>
</a>
</li>
</ul>
</div>
</div>
<script src="js/index.js"></script>
</body>
css:
* {
padding: 0;
margin: 0;
list-style: none;
box-sizing: border-box;
text-decoration: none;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
}
/*search搜索框*/
.search {
width: 100%;
height: 9%;
background: #42bd56;
padding: 4%;
position: fixed;
top: 0;
z-index: 100;
}
.search-con {
width: 87%;
height: 100%;
padding: 0 2%;
background: #fff;
float: left;
position: relative;
border-radius: 5px;
}
.search-con input {
height: 100%;
width: 80%;
outline: 0;
border: 0;
float: left;
}
.search-con .iconfont {
display: block;
height: 100%;
width: 10%;
float: left;
display: flex;
align-items: center;
}
.search .xiaoxi {
width: 10%;
height: 100%;
font-size: 28px;
color: #fff;
display: flex;
align-items: center;
float: right;
justify-content: center;
}
/*main*/
.main {
padding: 16% 0 14% 0;
}
/*swip*/
.swip {
width: 100%;
overflow: hidden;
position: relative;
height: 20vh;
}
.swip-con {
width: 500vw;
position: absolute;
overflow: hidden;
height: 100%;
}
.swip-item {
width: 100vw;
float: left;
height: 100%;
}
.swip-item a {
display: block;
height: 100%;
}
.swip img {
width: 100%;
height: 100%;
}
.swip-point {
width: 15%;
height: 1vh;
position: absolute;
bottom: 5%;
right: 5%;
}
.swip-point li {
height: 1vh;
width: 1vh;
background: #fff;
border-radius: 50%;
opacity: 0.4;
margin: 0 0.5vh;
float: left;
}
.swip-point .on {
opacity: 1;
}
/*公用的样式*/
.title {
height: 4vh;
border-left: 5px solid;
padding-left: 1vh;
line-height: 4vh;
}
/*热点*/
.hot {
margin-top: 1vh;
}
.hot-title {
border-color: darkorange;
color: darkorange;
}
.hot-item {
padding: 2vh;
border-bottom: 1px solid #eee;
position: relative;
}
.hot-item a {
display: block;
color: #aaa;
}
.hot-item p,
.hot-item h3 {
width: 65%;
}
.hot-item h3 {
font-size: 17px;
}
.hot-item p {
height: 8vh;
font-size: 14px;
padding: 1vh 0;
overflow: hidden;
}
.hot-icon {
width: 28vw;
height: 28vw;
position: absolute;
top: 2vh;
right: 2vh;
background-size: 28vh;
background-position: center center;
}
.icon1 {
background-image: url(../images/file-1492760868.jpg);
}
.icon2 {
background-image: url(../images/p2455522401.jpg);
}
.icon3 {
background-image: url(../images/p898938916.jpg);
}
/*豆瓣时间*/
.doubantime {
background: #f3f3f3;
padding: 1vh;
}
.time-title {
border-color: #00b600;
color: #00b600;
}
.time-con {
overflow-x: scroll;
}
.time-content {
width: 240vw;
overflow: hidden;
}
.time-item {
width: 76vw;
height: 45vh;
border-radius: 5px;
background: #fff;
border: 1px solid #ccc;
margin: 2vw;
float: left;
}
.time-item-top {
height: 13vh;
background: #42bd56;
padding: 2vh;
}
.time-item-top p {
text-align: center;
color: #fff;
}
.time-item-top p:nth-child(1) {
height: 4vh;
line-height: 4vh;
font-size: 14px;
}
.time-item-top p:nth-child(2) {
height: 6vh;
line-height: 6vh;
font-size: 12px;
}
.time-item-main {
padding: 3vh;
}
.time-item-main h3 {
font-size: 16px;
}
.time-item-main h4 {
font-size: 14px;
}
.time-item-main p {
font-size: 12px;
color: #aaa;
margin: 1.5vh 0;
}
.time-item-main a {
display: block;
width: 90%;
height: 5vh;
margin: 1vh auto;
line-height: 5vh;
color: #42bd56;
font-size: 12px;
border: 1px solid #42bd56;
text-align: center;
border-radius: 3px;
}
/*tabbar*/
.tabbar {
width: 100%;
height: 8%;
position: fixed;
bottom: 0;
background: #fff;
border-top: 1px solid #e3e3e3;
font-size: 8px;
}
.tabbar ul,
.tabbar-item {
height: 100%;
}
.tabbar ul {
display: flex;
}
.tabbar-item {
flex: 1;
text-align: center;
}
.tabbar-item.on a {
color: #00b600;
color: #42bd56;
}
.tabbar-item a {
display: block;
height: 100%;
color: #aaa;
padding: 10% 0;
}
.iconfont {
font-size: 20px;
}
Js:
// 轮播图
Vue.component("swip", {
data: function() {
return {
swipList: ["03a9580dbea5043_02.jpg", "3e6ddfae363ac2e_02.jpg", "a11c9de4be701d6_02.jpg", "a19fe074b049164_02.jpg"]
};
}, //data以函数形式传入
template: `<div class="swip">
<ul class="swip-con">
<li v-for="item of swipList" class="swip-item">
<a href="#">
<img :src='"images/"+item' alt="">
</a>
</li>
</ul>
<ul class="swip-point">
<li class="on"></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>`
})
new Vue({
el: "#app",
data: {
hotList: [{
title: "爹和摄影,波比娃娃、iPhone和黄金",
description: "小时候我真希望妈妈说:你是不是喜欢波比娃娃,给你买一个吧?",
icon: "icon1"
},
{
title: "今晚我有空|如此欢脱的惊悚片,竟成了北美..",
description: "惊悚片《逃出绝命镇》突破类型,创下今年小成本高票房的口碑佳作。",
icon: "icon2"
},
{
title: "爹和摄影,波比娃娃、iPhone和黄金",
description: "小时候我真希望妈妈说:你是不是喜欢波比娃娃,给你买一个吧?",
icon: "icon3"
}
],
timeList: [{
topP1: "常江和非主流电影人们",
topP2: "青年评论家,学者,邪典电影",
mainH3: "邪典电影本纪",
mainP1: "情色暴力的视觉冲击外,探索Cult亚文化的精神内核",
mainH4: "高智商电影问祖邪典片"
},
{
topP1: "杨照",
topP2: "作家、文学评论家,华文世界著作",
mainH3: "古今:杨照史记百讲",
mainP1: "经典“摆渡人”杨照通过解读《史记》,带你领略中国的大理石,先民的大智慧",
mainH4: "太平世里的战争奇才"
},
{
topP1: "北岛和朋友",
topP2: "当代著名诗人、译者及学者们",
mainH3: "醒来——北岛和朋友们的",
mainP1: "北岛和朋友们为你讲述诗人传奇故事,解读文化历史背景,细析诗句幽微妙处",
mainH4: "敬文东|何其芳《欢乐》(下)"
}
]
}
})
$(document).ready(function() {
var swip = $('.swip');
swiper(swip, true, 4);
})
function swiper(selector, autoplay, number) { //轮播函数
var i = 0;
var imgList = selector.find('ul').eq(0);
var dotList = selector.find('ul').eq(1);
var size = imgList.find('li').length; //获取imgList中图片的数量
var width = imgList.find('li').width();
var button = selector.find('div');
var clone = imgList.find('li').eq(0).clone(); //复制第一张图片
imgList.append(clone); //将复制的第一张图片加到最后一张图片后,以实现无缝轮播
if (autoplay == true) { //如果autoplay==true,设置定时器
var timer = setInterval(function() {
i++;
move();
}, 2000);
}
function move() { //图片移动的通用函数
if (i == size + 1) { //当移动到最后一张图片时,若再向右移,通过改变css将图片移动至第一张图片的位置,即left:0
imgList.css({
left: 0
});
i = 1;
};
imgList.stop().animate({
left: -width * i
}, 500); //图片移动的动画
if (i == size) {
dotList.find('li').eq(0).addClass("on").siblings().removeClass("on"); //移动到最后一张图片的时候,让第一个索引条处于on的状态
} else {
dotList.find('li').eq(i).addClass("on").siblings().removeClass("on");
}
}
}
感想
组长:
组员们真的很给力,虽然说大家的代码习惯,代码能力都不一样,但是我们每位都尽自己最大的力量去完成。
我觉得本次作业最大的成功不是说能作出多高仿的网站或者app,而是我们小组之间遇到不懂的问题,解决了多少个,又掌握了多少新的知识。
之前看录播课跟着老师走,一步一个脚印似乎觉得Vue也没想象中的难,本次作业最大的难点就是“组件化思维”,拿到一个页面,结合本页面的业务逻辑,怎么划分组件,细化后如何进行传数据,真的是绞尽脑汁,反反复复晕在数据上了,还有小组远程协同开发的时间太短了,很难统一!
在这十天里,坚持签到,坚持完成作业,协同组员,和组员们相互帮助合作,着实难忘,也辛苦小助手、Nostalgia等工作人员的辛苦付出。
IMWeb训练营学习计划十天之旅也告一段落了,希望后面有VueX和Vue Router的课程,最好再来个Vue实战!
Cony:没有学过Vue路由,来做豆瓣等web App存在比较多缺陷,组件化似乎运用起来也没想象中的行云流水,好在大家可以相互讨论学习,最享受这十天的问答交流环节了,大家遇到不懂的,直接截图求答,实在解决不了的就直接把代码打包发过来,帮大家解决问题不但巩固自己的知识,而且我们也乐享其中
若水:整个页面的结构,通过组件模板往里填参数会相对方便,可惜组件不熟,更加凌乱。自己动手做,比跟着老师做,麻烦多了;看着页面布局感觉还行,一上手又乱了。
前州:短短几天,说长不长说短不短,这几天了感觉学习到了很多东西,从一开始的模糊认识逐渐清晰,对于Vue有了初步的认识,这几天和大家学习收获蛮大
金浩:为期十天的IMWeb训练营学习计划已经到了结束阶段,自从参加了这个活动,每天都早起签到学习,完成老师的视频作业,这十天学习到很多,从一开始的一脸懵逼渐渐感觉到渐入佳境,本次活动对过来说收获巨大,比我自己自学的效率要提高50%,我让我知道如何更高效地学习,事后必定给自己定一个学习规划,希望能早日熟练地用vue!