阶段练习旨在学习完Vue 指令、计算属性、侦听器-CSDN博客后,进行自我检测,每个练习分为效果显示、需求分析、静态代码、完整代码、总结 四个部分,效果显示和准备代码已给出,我们需要完成“完整代码”部分。
练习1:tab栏的动态高亮显示
效果显示
静态代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>022(1)练习:tab栏的active效果</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
display: flex;
border-bottom: 2px solid #e01222;
padding: 0 10px;
}
li {
width: 100px;
height: 50px;
line-height: 50px;
list-style: none;
text-align: center;
}
li a {
display: block;
text-decoration: none;
font-weight: bold;
color: #333333;
}
li a.active {
background-color: #e01222;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li><a class="active" href="#">京东秒杀</a></li>
<li><a href="#">每日特价</a></li>
<li><a href="#">品类秒杀</a></li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: '京东秒杀' },
{ id: 2, name: '每日特价' },
{ id: 3, name: '品类秒杀' }
]
}
})
</script>
</body>
</html>
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>022(1)练习:tab栏的动态高亮显示</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
display: flex;
border-bottom: 2px solid #e01222;
padding: 0 10px;
}
li {
width: 100px;
height: 50px;
line-height: 50px;
list-style: none;
text-align: center;
}
li a {
display: block;
text-decoration: none;
font-weight: bold;
color: #333333;
}
li a.active {
background-color: #e01222;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item,index) in list" :key="item.id" @click="activeIndex = index">
<a :class="{active : index===activeIndex}" href="#">{{item.name}}</a>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
activeIndex: 2,
list: [
{ id: 1, name: '京东秒杀' },
{ id: 2, name: '每日特价' },
{ id: 3, name: '品类秒杀' }
]
}
})
</script>
</body>
</html>
错误代码
<li><a :class="{active : activeIndex===item.id}" v-for="(item,index) in list" :key="item.id"
@click="activeIndex=id" v-model="activeIndex" href="#">{{item.name}}</a></li>
总结
- 列表渲染
- 点击事件
- v-bind对样式进行控制
练习2:进度条
静态代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>022(2)练习:进度条</title>
<style>
.progress {
height: 25px;
width: 400px;
border-radius: 15px;
background-color: #272425;
border: 3px solid #272425;
box-sizing: border-box;
margin-bottom: 30px;
}
.inner {
width: 50%;
height: 20px;
border-radius: 10px;
text-align: right;
position: relative;
background-color: #409eff;
background-size: 20px 20px;
box-sizing: border-box;
transition: all 1s;
}
.inner span {
position: absolute;
right: -20px;
bottom: -25px;
}
</style>
</head>
<body>
<div id="app">
<div class="progress">
<div class="inner">
<span>50%</span>
</div>
</div>
<button>设置25%</button>
<button>设置50%</button>
<button>设置75%</button>
<button>设置100%</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
</html>
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>022(2)练习:进度条</title>
<style>
.progress {
height: 25px;
width: 400px;
border-radius: 15px;
background-color: #272425;
border: 3px solid #272425;
box-sizing: border-box;
margin-bottom: 30px;
}
.inner {
width: 50%;
height: 20px;
border-radius: 10px;
text-align: right;
position: relative;
background-color: #409eff;
background-size: 20px 20px;
box-sizing: border-box;
transition: all 1s;
}
.inner span {
position: absolute;
right: -20px;
bottom: -25px;
}
</style>
</head>
<body>
<div id="app">
<div class="progress">
<div class="inner" :style="{width: percent+ '%' }">
<span>{{percent}}%</span>
</div>
</div>
<button v-for="(item, index) in list" :key="index" @click="percent = item">设置{{item}}%</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
percent: 25,
list: [25, 50, 75, 100]
}
})
</script>
</body>
</html>
总结
- 列表渲染
- 点击事件
- v-bind对样式进行控制:操作style
注意
:style="{width: percent+ '%' }"
如果没有将百分比值与单位分开并添加单引号,例如
:style="{width: percent + %}"
,那么Vue.js将会尝试将百分比值与JavaScript表达式中的%
一起解析为字符串,而这不是一个有效的CSS值,会导致样式设置失败。
练习3:购物车
静态代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/inputnumber.css" />
<link rel="stylesheet" href="./css/index.css" />
<title>028练习:购物车</title>
</head>
<body>
<div class="app-container" id="app">
<!-- 顶部banner -->
<div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" /></div>
<!-- 面包屑 -->
<div class="breadcrumb">
<span>🏠</span>
/
<span>购物车</span>
</div>
<!-- 购物车主体 -->
<div class="main">
<div class="table">
<!-- 头部 -->
<div class="thead">
<div class="tr">
<div class="th">选中</div>
<div class="th th-pic">图片</div>
<div class="th">单价</div>
<div class="th num-th">个数</div>
<div class="th">小计</div>
<div class="th">操作</div>
</div>
</div>
<!-- 身体 -->
<div class="tbody">
<div class="tr active">
<div class="td"><input type="checkbox" checked /></div>
<div class="td"><img src="http://autumnfish.cn/static/火龙果.png" alt="" /></div>
<div class="td">6</div>
<div class="td">
<div class="my-input-number">
<button class="decrease"> - </button>
<span class="my-input__inner">2</span>
<button class="increase"> + </button>
</div>
</div>
<div class="td">12</div>
<div class="td"><button>删除</button></div>
</div>
<div class="tr">
<div class="td"><input type="checkbox" /></div>
<div class="td"><img src="http://autumnfish.cn/static/荔枝.png" alt="" /></div>
<div class="td">7</div>
<div class="td">
<div class="my-input-number">
<button disabled class="decrease"> - </button>
<span class="my-input__inner">1</span>
<button class="increase"> + </button>
</div>
</div>
<div class="td">14</div>
<div class="td"><button>删除</button></div>
</div>
</div>
</div>
<!-- 底部 -->
<div class="bottom">
<!-- 全选 -->
<label class="check-all">
<input type="checkbox" />
全选
</label>
<div class="right-box">
<!-- 所有商品总价 -->
<span class="price-box">总价 : ¥ <span class="price">24</span></span>
<!-- 结算按钮 -->
<button class="pay">结算( 6 )</button>
</div>
</div>
</div>
<!-- 空车 -->
<div class="empty">🛒空空如也</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
// 水果列表
fruitList: [
{
id: 1,
icon: 'http://autumnfish.cn/static/火龙果.png',
isChecked: true,
num: 2,
price: 6,
},
{
id: 2,
icon: 'http://autumnfish.cn/static/荔枝.png',
isChecked: false,
num: 7,
price: 20,
},
{
id: 3,
icon: 'http://autumnfish.cn/static/榴莲.png',
isChecked: false,
num: 3,
price: 40,
},
{
id: 4,
icon: 'http://autumnfish.cn/static/鸭梨.png',
isChecked: true,
num: 10,
price: 3,
},
{
id: 5,
icon: 'http://autumnfish.cn/static/樱桃.png',
isChecked: false,
num: 20,
price: 34,
},
],
},
})
</script>
</body>
</html>
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="028inputnumber.css" />
<link rel="stylesheet" href="028index.css" />
<title>028练习:购物车</title>
</head>
<body>
<div class="app-container" id="app">
<!-- 顶部banner -->
<div class="banner-box"><img src="#" alt="" /></div>
<!-- 面包屑 -->
<div class="breadcrumb">
<span>🏠</span>
/
<span>购物车</span>
</div>
<!-- 购物车主体 -->
<div class="main">
<div class="table">
<!-- 头部 -->
<div class="thead">
<div class="tr">
<div class="th">选中</div>
<div class="th th-pic">图片</div>
<div class="th">单价</div>
<div class="th num-th">个数</div>
<div class="th">小计</div>
<div class="th">操作</div>
</div>
</div>
<!-- 身体 -->
<div class="tbody">
<div class="tr" :class="{active: item.isChecked==true }" v-for="(item, index) in fruitList" :key="item.id">
<div class="td"><input type="checkbox" @click="item.isChecked=!item.isChecked" /></div>
<div class="td"><img src="#" alt="" /></div>
<div class="td">{{item.price}}</div>
<div class="td">
<div class="my-input-number">
<button class="decrease" @click="item.num--"> - </button>
<span class="my-input__inner">{{item.num}}</span>
<button class="increase" @click="item.num++"> + </button>
</div>
</div>
<div class="td">{{subTotalCount(index)}}</div>
<div class="td"><button @click="del(item.id)">删除</button></div>
</div>
</div>
</div>
<!-- 底部 -->
<div class="bottom">
<!-- 全选 -->
<label class="check-all">
<input type="checkbox" @click="allClickFlag=!allClickFlag" />
全选
</label>
<div class="right-box">
<!-- 所有商品总价 -->
<span class="price-box">总价 : ¥ <span class="price">{{totalCount}}</span></span>
<!-- 结算按钮 -->
<button class="pay">结算( {{totalKind}} )</button>
</div>
</div>
</div>
<!-- 空车 -->
<div class="empty" v-show="flag===0">🛒空空如也</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
flag: 0,
allClickFlag: false,
// 水果列表
fruitList: [
{
id: 1,
icon: '#',
isChecked: false,
num: 2,
price: 6,
},
{
id: 2,
icon: '#',
isChecked: false,
num: 7,
price: 20,
},
{
id: 3,
icon: '#',
isChecked: false,
num: 3,
price: 40,
},
{
id: 4,
icon: '#',
isChecked: false,
num: 10,
price: 3,
},
{
id: 5,
icon: '#',
isChecked: false,
num: 20,
price: 34,
},
],
},
methods: {
subTotalCount(index) {
return this.fruitList[index].num * this.fruitList[index].price
},
del(id) {
this.fruitList = this.fruitList.filter(item => item.id != id)
},
allClick() {
if (this.allClickFlag == true) {
this.fruitList.forEach(item => {
item.isChecked = false;
});
} else {
this.fruitList.forEach(item => {
item.isChecked = true;
});
}
}
},
computed: {
totalCount() {
let total = this.fruitList.reduce((sum, item) => {
if (item.isChecked === true) {
return sum + item.num * item.price;
} else {
return sum;
}
}, 0);
return total;
},
totalKind() {
let kind = this.fruitList.reduce((sum, item) => {
if (item.isChecked === true) {
return sum + item.num;
} else {
return sum;
}
}, 0);
return kind;
}
},
watch: {
'allClickFlag': {
immediate: true,
handler(newVal) {
if (newVal === true) {
this.fruitList.forEach(item => {
item.isChecked = true;
});
} else {
this.fruitList.forEach(item => {
item.isChecked = false;
});
}
}
}
}
})
</script>
</body>
</html>