方法与事件
基本用法
v-on,在事件绑定上,类似原生 JavaScript的 onclick 等写法,也是在 HTML 上进行监昕的。
<div id="app">
点击次数:{{counter}}
<button @click="counter++">+1</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
counter:0;
}
})
</script>
@click 的表达式可以直接使用 JavaScript 语句,也可以是一个在 Vue 实例中 methods 选项内的函数名
<div id="app">
点击次数:{{counter}}
<button @click="handleAdd()">+1</button>
<button @click="handleAdd(10)">+10</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
counter:0;
},
methods:{
handleAdd:function(count){
count = count || 1;
this.counter +=count;
}
}
})
</script>
在 methods 中定义了我们需要的方法供@click 调用, 需要注意的是,@click 调用的方法名后可以不跟括号“()” 。 此时,如果该方法有参数,默认会将原生事件对象 event 传入,可以尝试修改为@click=”handleAdd”,然后在 handleAdd 内打印出 count 参数看看。在大部分业务场景中,如果方法不需要传入参数,为了简便可以不写括号。
这种在 HTML 元素上监听事件的设计看似将 DOM 与 JavaScript 紧耦合,违背分离的原理,实则刚好相反。因为通过 HTML 就可以知道调用的是哪个方法,将逻辑与 DOM 解耦,便于维护。最重要的是 , 当 ViewModel 销毁时,所有的事件处理器都会自动删除,无须自己清理 。
<div id="app">
<a href="http://www.apple.com" @click="handleClick('禁止打开',$event)">打开链接</a>
</div>
<script>
var app = new Vue({
el:'#app',
methods:{
handleClick:function(message,event){
event.preventDefault();
window.alert(message);
}
}
})
</script>
修饰符
在上面使用的 event.preventDefault()也可以用 Vue 事件的修饰符来实现,在@绑定的事件后加小圆点“.”,再跟一个后缀来使用修饰符。 Vue 支持以下修饰符:
• .stop
• .prevent
• .capture
• .self
• .once
<!--阻止单击事件冒泡-->
<a @click.stop="handle"></a>
<!--提交事件不再重载页面-->
<form @submit.prevent="handle"></form>
<!--修饰符可以串联-->
<a @click.stop.prevent="handle"></a>
<!--只有修饰符-->
<form @submit.prevent></form>
<!--添加事件侦听器时使用事件捕获模式-->
<div @click.capture="handle">...</div>
<!--只当事件在该元素本身触发时触发问题-->
<div @click.self="handle">...</div>
<!--只触发一次,组件同样适用-->
<div @click.once="handle">...</div>
<!--在表单元素上监昕键盘事件时,还可以使用按键修饰符-->
<!--只有在keyCode是13时调用vm.submit()-->
<input @keyup.13="submit">
除了具体的某个 keyCode 外, Vue 还提供了一些快捷名称,以下是全部的别名:
• .enter
• .tab
• .delete (捕获“删除”和“退格”键)
• .esc
• .space
• .up
• .down
• .left
• .right
这些按键修饰符也可以组合使用,或和鼠标一起配合使用:
• .ctrl
• .alt
• .shift
• .meta (Mac 下是 Command 键, Windows 下是窗口键)
<!--Shift + S -->
<input @keyup.shift.83="handleSave">
<!--Ctrl + Click -->
<div @cllick.ctrl="doSomething">Do something</div>
利用计算属性、指令等知识开发购物车
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Shopping Cart Demo</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="app" v-cloak>
<template v-if="list.length">
<table>
<thead>
<th></th>
<th>商品名称</th>
<th>商品单价</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="(item,index) in list">
<td>{{index+1}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<button
@click="handleReduce(index)"
:disabled="item.count===1">-</button>
{{item.count}}
<button @click="handleAdd(index)">+</button>
</td>
<td>
<button @click="handleRemove(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<div>总价:¥{{totalPrice}}</div>
</template>
<div v-else>购物车为空</div>
</div>
<!--注意,这里将vue.min.js和 index.js 文件写在<body>的最底部,如果写在<head>里 , Vue 实例
将无法创建,因为此时 DOM 还没有被解析完成,除非通过异步或在事件 DOMContentLoaded(IE是
onreadystatechange)触发时再创建 Vue 实例,这有点像 jQuery 的$(document).ready()方法。-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="index.js"></script>
</body>
</html>
index.js
var app = new Vue({
el:'#app',
data:{
list:[
{
id: 1,
name: 'iPhone 7',
price: 6188,
count: 1
},
{
id: 2,
name: 'iPad Pro',
price: 5888,
count: 1
},
{
id: 3,
name: 'MacBook Pro',
price: 21488,
count: 1
}
]
},
computed:{
totalPrice:function(){
var total = 0;
for(var i=0;i<this.list.length;i++){
var item = this.list[i];
total += item.price*item.count;
}
return total.toString().replace(/\B(?=(\d{3})+$)/g,',')
}
},
methods:{
handleReduce:function(index){
if(this.list[index].count===1)return;
this.list[index].count--;
},
handleAdd(index){
this.list[index].count++;
},
handleRemove:function(index){
this.list.splice(index,1);
}
}
});
style.css
[v-cloak]{
display: none;
}
table{
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
empty-cells: show;
}
th,td{
background: #f7f7f7;
color: #5c6b77;
font-weight: 600;
white-space: nowrap;
}