1. 自定义事件
除了可以处理原生的DOM事件, v-on指令也可以处理组件内部触发的自定义的事件,调用this.$emit()
函数就可以触发一个自定义事件
$emit()
触发事件函数接受一个自定义事件的事件名以及其他任何给事件函数传递的参数. 然后就可以在组件上使用v-on
来绑定这个自定义事件
js
{
methods: {
handleClick(){
this.clicks++
this.$emit("count",this.clicks )
}
}
}
所以我们就可以利用自定事件来处理子组件触发父组件数据的更改和向父组件传值
2. 子组件触发父组件数据的改变
通过父组件向子组件传值的学习,我们已经知道了Vue是单向下行数据流, 子组件更改props
中的数据不会触发父组件数据的改变, 但是由于响应式原理,父组件数据的改变会导致子组件props
中值的改变
那么我们怎样才能在子组件中改变显示的结果呢.
思路:
- 子组件中没法更改父组件中的数据,那么我们就让父组件自己的函数改自己的数据
- 如何在子组件中触发父组件中的函数呢, 就可以通过自定义事件
- 子组件在函数中触发自定义事件, 将父组件中更改数据的函数绑定为自定义事件的函数
- 然后父组件中的数据一变,因为响应式,所以子组件中的数据会自动改变
示例代码如下:
html
<div id="app">
<!-- 使用组件 -->
<!-- 3.在子组件中绑定自定义事件, 将父组件的方法绑定为自定义事件的处理函数-->
<my-component
:clicks="clicks"
@count="handleParentClick"
></my-component>
</div>
<!-- 组件模板 -->
<template id="MyComponent">
<div>
被点击了{{clicks}}次
<!-- 1. 子组件通过原生click事件触发子组件自己的函数 -->
<button @click="handleClick">点击</button>
</div>
</template>
<script>
// 组件选项对象
let MyComponent = {
props:["clicks"],
template: `#MyComponent`,
methods:{
handleClick(){
// 2.子组件函数中触发自定义事件
this.$emit("count")
}
}
}
// 实例中注册组件
const vm = new Vue({
el:"#app",
data: {
clicks:0
},
components: {
"MyComponent": MyComponent
},
methods:{
handleParentClick(){
// 4. 在父组件函数中修改父组件中的数据
this.clicks++
}
}
})
</script>
示例结果
最后父组件数据一变,子组件显示结果自然变化
我们也知道$emit
方法在触发自定义事件的时候,还可以给自定义事件传参, 这样就可以实现子组件向父组件传参
3. 子组件向父组件传参
上一小节,我们是在子组件中通过自定义事件触发父组件中的函数, 在父组件中修改数据,
同样我们也可以在子组件中修改数据,然后将修改后的数据通过自定义事件传参的方式,传递给父组件函数,在父组件函数中直接用子组件传过来修改后的数据直接替换父组件中的数据
示例代码如下:
html
<div id="app">
<!-- 使用组件 -->
<!-- 3.在子组件中绑定自定义事件, 将父组件的方法绑定为自定义事件的处理函数-->
<my-component
:clicks="clicks"
@count="handleParentClick"
></my-component>
</div>
<!-- 组件模板 -->
<template id="MyComponent">
<div>
被点击了{{clicks}}次
<!-- 1. 子组件通过原生click事件触发子组件自己的函数 -->
<button @click="handleClick">点击</button>
</div>
</template>
<script>
// 组件选项对象
let MyComponent = {
props:["clicks"],
template: `#MyComponent`,
data(){
return {
count: this.clicks
}
},
methods:{
handleClick(){
// 2.子子组件函数中触发自定义事件
// 2.1 在触发自定义事件的时候向自定事件传参
this.count+=2
this.$emit("count",this.count)
}
}
}
// 实例中注册组件
const vm = new Vue({
el:"#app",
data: {
clicks:0
},
components: {
"MyComponent": MyComponent
},
methods:{
handleParentClick(count){
// 4. 在父组件函数中修改父组件中的数据
// 4.1 接受自定义事件触发时传递的参数
console.log(count)
this.clicks = count
}
}
})
</script>