今天在看Element UI 源码的时候,发现有些地方通过v-bind传递函数给子组件,在子组件里面执行函数的时候,函数居然可以调用父组件的方法,后来查了一下发现:
在 Vue 中,当你使用 v-bind(或者更常见的简写 :)将一个函数从父组件传递到子组件时,该函数内部的 this 上下文将仍然指向定义该函数的组件,即父组件。
这是因为函数在 JavaScript 中是对象,当你传递一个函数时,你实际上是在传递这个函数的引用,而不是它的执行结果。因此,即使这个函数在子组件中被调用,它仍然保留了在父组件中定义时的上下文(this)。
下面是一个简单的例子来说明这一点:
<!-- 父组件 Parent.vue -->
<template>
<div>
<ChildComponent :handleClick="handleClick" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleClick() {
console.log(this); // 这里的 this 指向 Parent 组件的实例
}
}
}
</script>
<!-- 子组件 ChildComponent.vue -->
<template>
<button @click="handleClickFromProps">点击我</button>
</template>
<script>
export default {
props: {
handleClick: Function
},
methods: {
handleClickFromProps() {
this.handleClick(); // 调用父组件传递的函数,其内部的 this 指向父组件
}
}
}
</script>
在上面的例子中,当你在子组件中点击按钮时,会调用 handleClickFromProps 方法,该方法进而调用从父组件传递过来的 handleClick 函数。在这个 handleClick 函数内部,this 指向的是父组件的实例。
这也是平时容易理解出错的地方,因为我们平时习惯通过自定义函数传值实现子组件调用父组件的方法,但是在Vue中,也是可以通过传递函数,然后在子组件中调用父组件中的方法。