一定要注意,事件处理分两类:1. 原生事件绑定 2.组件事件监听,两种方式传参不同,特别是第二种,是获取不到event的(触发事件对象)
在template中,直接通过attribute键值对方式就可绑定事件,不需要再去获取DOM,
当然着其中真正绑定还是VM在做,最关键的在于,如果一个VM销毁,它会自动的解绑事件。
如果你做过登入注册的登入和退出登入的切换,你一定能感受的vue的强大。
监听事件
v-on 事件监听围绕这一指令展开:
- 可直接在绑定内容是个JS代码执行,该内容和模板语法一致,注意是一个沙箱,扫描到的变量都会去vm实例上找,或者内置函数(Date等)
export default {
data() {
return {counter: 0}
},
// template: `<div>
// buttonClickTimes: {{counter}}
// <button v-on:click="console.log('a')">Add 1</button>
// </div>`,
template: `<div>
<button v-on:click="++counter">
click {{counter}} times
</button>
</div>`
}
- 绑定的是一个方法,其实这个方法仍然是vm实例的一个属性,你可以通过
vm.increaseCounter访问到
export default {
data() {
return {counter: 0}
},
template: `<div>
<button v-on:click="increaseCounter">
click {{counter}} times
</button>
</div>`,
methods: {
increaseCounter() {
this.counter++
}
}
}
- 绑定传参函数
export default {
data() {
return {counter: 0}
},
//注意这里不会在渲染的时候就调用
template: `<div>
<button v-on:click="increaseCounter('zix', $event)">
click {{counter}} times
</button>
</div>`,
methods: {
increaseCounter(name, event) {
//如果 v-on:click="increaseCounter" 正常绑定,那么increaseCounter方法第一个参数是event
// name 是参数, event是事件对象(做过处理的)
this.counter++
}
}
}
- 组件怎么监听事件?
在着之前我们应该先了解关于attribute的绑定机制。
- 为什么要template 一定要一个根元素呢
const component1 = {
template: `<div>
component1
<div>`
}
const vm = new Vue({
el: '#app',
components: {component1},
template: `<div>
<component1 class="component1" />
<div>`
})
//当渲染出来的DOM
/*
<div id="app">
<div class="component1">
component1
</div>
</div>
*/
/*
可以注意到 class 虽然是在组件上绑定的,但是最后作用在组件的根元素上,可以想象如果没有组件根元素,那么attribute很多值是无效的(或者说DOM节点值)。
*/
/*
如果你有过react的学习经验,你就肯定能理解,react的props相当于参数传值,但是有趣的是react可以使用空标签或者Fragment,它相当于一个虚拟的DOM,只存在于内存(DOM树上绑定VM实例),但是不展示而已,但是作用在组件标签上的属性不会传递给组件根元素,永远只是参数的传递
*/
- props有过滤功能,其实props也可以接受所有值,但是这样会非常的麻烦。
- 事件监听是监听整个子VM的事件,然而VM实例本身没有事件抛出,所以需要处理事务,并向上抛出冒泡事件。
const vModelInput = {
props: ['value', 'name'],
template: `<div>
<input v-bind:value="value" v-bind:name="name" @input="input($event)" />
</div>`,
methods:{
input(event) {
//event.target 就是获取的表单框元素
//注意第一个参数的名字就是抛出自定义组件事件的名称,组件标签要绑定事件是,必须v-on:proname监听
this.$emit('input', event.target.value)
}
}
}
const vm = new Vue({
el: '#app',
data: ()=>({
value: ''
}),
components: {vModelInput},
// 第一种
template: `<div>
name: {{value}}
<vModelInput v-bind:value="value" name="name"
v-on:input="value = $event" />
</div>`,
//第二种
template: `<div>
<vModelInput v-model="value" name="name" />
</div>`
})
- 其实上面的例子已经带大家手动写了一个v-model指令该如何做了,但是你又了解v-model怎么运作的吗,或者说怎么改变绑定
const myModelComponent = {
//v-model 绑定的属性值为传入给props名字叫做checked的属性并赋值,当事件change发生时,通知父组件改变v-model绑定的属性,实现数据双向绑定
model: {prop: 'value', event: 'input'},
props: {
checked: String,
name: String
},
template: `<div>
<input
type="checkbox"
v-bind:value="value"
:id="name"
v-on:input="$emit('input', $event.target.value)"
>
<label :for="name">{{name}}</label>
</div>`
}
附录
要学习计算属性和侦听器的小可爱点击这里 vue之计算属性和侦听器
要学习动态事件绑定点击这里 Vue之动态事件绑定