一、案例描述
制作一个选项卡,如下图,当我们选择对应的页签时展示对应的图片,比如我们选择orange则展示橘子的图片。
二、实现静态UI效果
这里我们使用已经准备好的静态页面,也比较简单,默认是展示苹果的页面。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor: pointer;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab"> <!-- tab栏 -->
<ul>
<li class="active">apple</li>
<li class="">orange</li>
<li class="">lemon</li>
</ul> <!-- 对应显示的图片 -->
<div class="current"><img src="img/apple.png"></div>
<div class=""><img src="img/orange.png"></div>
<div class=""><img src="img/lemon.png"></div>
</div>
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
}
});
</script>
</body>
</html>
静态效果如下:
三、 基于数据重构UI效果
1、将静态的结构和样式重构为基于Vue模板语法的形式
我们需要将静态页面中的所需要的数据抽取出来,用vue模板语法来重构。页签和图片的展示我们使用v-for循环来展示。修改如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor: pointer;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab"> <!-- tab栏 -->
<ul>
// 为了提高性能,:key也应该加上
<li :key="item.id" v-for="(item,idnex) in list">{{item.title}}</li>
</ul> <!-- 对应显示的图片 -->
<div :key="item.id" v-for="(item,index) in list">
<img :src="item.path">
</div>
</div>
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
list:[{
id:1,
title:"apple",
path:"img/apple.png"
},
{
id:2,
title:"orange",
path:"img/orange.png"
},
{
id:3,
title:"lemon",
path:"img/lemon.png"
}]
}
});
</script>
</body>
</html>
效果如下:
我们可以看到,三个图片的div都是存在的,为什么没展示呢?因为目前它们还有默认的样式,display都是none。要想展示,要加一个类名.current。另外,标题栏选中后底色要变成橙色,对应的类是.active。
那么,这俩个样式类添加的原则是什么呢?
重点: 我们选中那个标题页签,就给该页签添加这两个类。那如何区分出当前我们选中的是谁呢?所以我们需要记录下当前索引的位置。因此,我们在数据中添加一个额外的自定义属性currentIndex。通过三目运算符来判断currentIndex是否与当前title的索引一致,如果一致,我们就给它添加样式,否则就是“”。图片的处理也是类似的套路。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor: pointer;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab"> <!-- tab栏 -->
<ul>
<li :class='currentIndex==index?"active":""':key="item.id" v-for="(item,index) in list">{{item.title}}</li>
</ul> <!-- 对应显示的图片 -->
<div :class='currentIndex==index?"current":""' :key="item.id" v-for="(item,index) in list">
<img :src="item.path">
</div>
</div>
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
currentIndex:0, //选项卡当前索引
list:[{
id:1,
title:"apple",
path:"img/apple.png"
},
{
id:2,
title:"orange",
path:"img/orange.png"
},
{
id:3,
title:"lemon",
path:"img/lemon.png"
}]
}
});
</script>
</body>
</html>
效果如下:
至此,样式的处理就完成了。
2、处理事件绑定和js控制逻辑
接下来实现选项卡切换操作:本质就是操作类名。 如何操作类名?就是通过currentIndex,通过Vue的点击事件来实现。完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor: pointer;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab"> <!-- tab栏 -->
<ul>
<li v-on:click="change(index)" :class='currentIndex==index?"active":""':key="item.id" v-for="(item,index) in list">{{item.title}}</li>
</ul> <!-- 对应显示的图片 -->
<div :class='currentIndex==index?"current":""' :key="item.id" v-for="(item,index) in list">
<img :src="item.path">
</div>
</div>
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
currentIndex:0, //选项卡当前索引
list:[{
id:1,
title:"apple",
path:"img/apple.png"
},
{
id:2,
title:"orange",
path:"img/orange.png"
},
{
id:3,
title:"lemon",
path:"img/lemon.png"
}]
},
methods:{
change:function (index) {
// 在这里实现选项卡切换操作:本质就是操作类名
// 如何操作类名?就是通过currentIndex
this.currentIndex=index;
}
}
});
</script>
</body>
</html>
可以实现tab选项卡的切换。
3、声明式编程
模板的结构和最终显示的效果基本一致