一、认识侦听器watch
侦听器的用法如下:
选项:
watch
类型:
{ [key: string]: string | Function | Object | Array}
侦听器watch的配置选项
我们先来看一个例子:
当我们点击按钮的时候会修改info.name的值;
这个时候我们使用watch来侦听info,可以侦听到吗?答案是不可以。
这是因为默认情况下,watch只是在侦听info的引用变化,对于内部属性的变化是不会做出响应的:
这个时候我们可以使用一个选项deep进行更深层的侦听;
注意前面我们说过watch里面侦听的属性对应的也可以是一个Object;
还有另外一个属性,是希望一开始的就会立即执行一次:
这个时候我们使用immediate选项;
这个时候无论后面数据是否有变化,侦听的函数都会有限执行一次;
<template id="cart">
<div>
<template v-if="books.length > 0">
<table>
<thead>
<th>序号</th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="(book, index) in books" :key = "index">
<td>{{index + 1}}</td>
<td>{{book.name}}</td>
<td>{{book.date}}</td>
<td>{{formatPrice(book.price)}}</td>
<td>
<button :disabled="book.count <= 1" @click="decrement(index)">-</button>
<span class="counter">{{book.count}}</span>
<button @click="increment(index)">+</button>
</td>
<td>
<button @click="removeBook(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<h2>总价格: {{formatPrice(totalPrice)}}</h2>
</template>
<template v-else>
<h2>购物车为空。。。。</h2>
</template>
</div>
</template>
<script>
export default({
template:"#cart",
data() {
return {
books: [
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 1
},{
id: 2,
name: '《算法导论》',
date: '2007-9',
price: 78.00,
count: 1
},{
id: 3,
name: '《算法导论》',
date: '2008-9',
price: 54.00,
count: 1
},{
id: 4,
name: '《算法导论》',
date: '2009-9',
price: 66.00,
count: 1
}
]
}
},
methods: {
increment(index) {
// 通过索引值做运算
this.books[index].count++;
},
decrement(index) {
this.books[index].count--;
},
removeBook(index) {
this.books.splice(index, 1);
},
formatPrice(price) {
return "¥" + price;
}
},
computed: {
totalPrice() {
let finalPrice = 0;
for (let book of this.books) {
finalPrice += book.price * book.count;
}
return finalPrice;
},
// vue3不支持过滤器了,推荐两种做法:使用计算属性/使用全局的方法
// filterBooks() {
// // map高阶函数
// // 有时候后台返回的值不是我们想要的,就用map来转化一下
// return this.books.map(item => {
// const newItem = Object.assign({}, item);
// newItem.price = "¥" + newItem.price;
// return newItem;
// })
// }
}
})
</script>
<style scoped>
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td{
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th {
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
.counter{
margin: 0 5px;
}
</style>