记录学习过程中的Vue小案例
1、购物车案例
效果图:
需要的文件布局截图:
1)index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in books">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>{{item.price | showPrice}}</td>
<td>
<button @click="decrement(index)" :disabled="item.count <= 1">-</button>
{{item.count}}
<button @click="increment(index)">+</button>
</td>
<td>
<button @click="removeHandle(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<h2>总价: {{totalPrice | showPrice}}</h2>
</div>
<h2 v-else>购物车为空</h2>
</div>
<script src="../js/vue.js"></script>
<script src="main.js"></script>
</body>
</html>
2)main.js
const app = new Vue({
el: '#app',
data: {
books: [
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 1
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 1
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128.00,
count: 1
}
]
},
computed: {
totalPrice() {
let totalPrice = 0
for(let i = 0; i < this.books.length; i++) {
totalPrice += this.books[i].price * this.books[i].count;
}
return totalPrice;
}
},
methods: {
increment(index) {
this.books[index].count++;
},
decrement(index) {
this.books[index].count--;
},
removeHandle(index) {
this.books.splice(index, 1)
}
},
filters: {
showPrice(price) {
return '¥' + price.toFixed(2);
}
}
})
computed中的totalPrice()改进:使用reduce函数
const app = new Vue({
el: '#app',
data: {
books: [
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 1
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 1
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128.00,
count: 1
}
]
},
computed: {
totalPrice() {
// let totalPrice = 0
// for(let i = 0; i < this.books.length; i++) {
// totalPrice += this.books[i].price * this.books[i].count;
// }
// return totalPrice;
return this.books.reduce(function (pre, book) {
return pre + book.price * book.count;
}, 0)
}
},
methods: {
increment(index) {
this.books[index].count++;
},
decrement(index) {
this.books[index].count--;
},
removeHandle(index) {
this.books.splice(index, 1)
}
},
filters: {
showPrice(price) {
return '¥' + price.toFixed(2);
}
}
})
3)style.css
table {
border: 1px solid black;
border-collapse: collapse;
border-spacing: 0;
}
th, td {
padding: 8px 16px;
border: 1px solid black;
text-align: left;
}
th {
background-color: gainsboro;
}
2、列表点谁 谁变色
代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点谁谁变色</title>
</head>
<style>
.active {
color: #42b983;
}
</style>
<body>
<div id="app">
<li v-for="(item, index) in movies"
:class="{active: index == currentIndex}"
@click="liClick(index)">
{{item}}
</li>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
currentIndex: 0,
movies: ['星际穿越', '哈尔的移动城堡', '千与千寻']
},
methods: {
liClick(index) {
this.currentIndex = index;
}
}
})
</script>
</body>
</html>
显示效果:
3、父子之间通信结合双向绑定
具体实现的效果:子组件获得父组件传递的数据,并且子组件改变这些数据时,父组件对应的数据也发生改变。改变某一个数据时,对应的另一个数据b变为它的100倍,改变另一个数据时,某一个数据变为它的100/1。(注意:这里改变数据时,父组件中对应传递的数据也要发生改变)
代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件间通信案例</title>
</head>
<body>
<div id="app">
<cpn :number1="num1"
:number2="num2"
@num1change="fnum1change"
@num2change="fnum2change"/>
</div>
<template id="cpn">
<div>
<h2>props中的number1:{{number1}}</h2>
<h2>data中的dnumber1: {{dnumber1}}</h2>
<input type="text" :value="dnumber1" @input="num1Input">
<h2>props中的number2:{{number2}}</h2>
<h2>data中的dnumber2:{{dnumber2}}</h2>
<input type="text" :value="dnumber2" @input="num2Input">
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: `#cpn`,
props: {
number1: Number,
number2: Number
},
data() {
return {
dnumber1: this.number1,
dnumber2: this.number2
}
},
methods: {
num1Input(event) {
this.dnumber1 = event.target.value;
//给父组件发送数据,更改父组件中的对应数据
this.$emit('num1change', this.dnumber1);
//向父组件传送修改后的dnumber2的数据,父组件的number2要增大100倍
this.dnumber2 = this.dnumber1 * 100;
this.$emit('num2change', this.dnumber2)
},
num2Input(event) {
this.dnumber2 = event.target.value;
this.$emit('num2change', this.dnumber2);
this.dnumber1 = this.dnumber2 / 100;
this.$emit('num1change', this.dnumber1);
}
}
}
const app = new Vue({
el: '#app',
data: {
num1: 1,
num2: 2
},
components: {
cpn
},
methods: {
fnum1change(value) {
//注意:要进行类型转换,文本框输入的默认是字符串类型,而传出去的数据是Number类型,
// 如果不处理,会报错,使用parseInt也行,但是自动会做一些转换,可能显示的值有所不同
this.num1 = value * 1;
},
fnum2change(value) {
this.num2 = value * 1;
}
}
})
</script>
</body>
</html>
效果显示:
注意:这里也可以在子组件中使用 watch() 来监听props中数据的变化,可以使用v-model,有时间会进行watch()方法的补充。