如果我正在使用import SearchBarPopper from './xxx'
:导入组件
import SearchBarPopper from './search-bar-popper';
export default {
components: {
SearchBarPopper,
},
};
在模板中定义引用名称:
<search-bar-popper ref="popper" />
然后在其他组件触发@click
:时调用其函数
methods: {
onClick(index) {
console.log(this.$refs.popper);
if (this.$refs.popper) {
this.$refs.popper.setSearchListIndex(index);
}
},
}
它是有效的。我有这样的代理:
[[Target]]: Object
searchBar: Proxy {setPopperRelativeIndex: ƒ, onInputFocus: ƒ, onInputBlur: ƒ, onInputKeyUp: ƒ,
onInputKeyDown: ƒ, …}
setSearchListIndex: ƒ ()
show: (...)
$: (...)
$attrs: (...)
$data: (...)
$el: (...)
$emit: (...)
$forceUpdate: (...)
$nextTick: (...)
$options: (...)
$parent: (...)
$props: (...)
$refs: (...)
$root: (...)
$router: (...)
$slots: (...)
$store: (...)
$watch: (...)
_: (...)
它有我需要的功能。
现在让我们重试,让我们用defineAsyncComponent()
:导入组件
export default {
components: {
SearchBarPopper: defineAsyncComponent(() => import('./search-bar-popper'))
},
};
仍然在手动事件@click
中触发,而不是从mounted()
或其他什么中触发。
这一次我不能正确地得到参考:
[[Target]]: Object
$: (...)
$attrs: (...)
$data: (...)
$el: (...)
$emit: (...)
$forceUpdate: (...)
$nextTick: (...)
$options: (...)
$parent: (...)
$props: (...)
$refs: (...)
$root: (...)
$router: (...)
$slots: (...)
$store: (...)
$watch: (...)
_: (...)
参考内容仍然打印,但在里面我找不到setSearchListIndex()
的功能。
顺便说一下,组件SearchBarPopper
看起来是这样的:
<template>
<div class="ls-view-home-search__popper">
<ls-collapse class="ls-view-home-search__popper__wrap" :show="show">
<search-bar-list ref="search-bar-list" />
</ls-collapse>
</div>
</template>
这是怎么回事?
这是因为当您将组件定义为async(使用defineAsyncComponent
(时,您得到的是包装器组件。包装器组件作为父组件的直接子组件安装,它管理SeachBarPopper组件的异步加载。
如果您查看vue devtools中的组件树,您会发现在真正的SearchBarPopper
周围有一个额外的AsyncComponentWrapper
组件。在这种情况下,您的ref
指向的是AsyncComponentWrapper
,而不是其中的SearhBarPopper
。
在版本3.0.4+中
当您将ref绑定到异步组件(使用defineAsyncComponent
(时,他们解决了这个问题。
ref将绑定到CCD_ 15内部的实际组件。
顺便说一句,如果您在自定义组件中使用<script setup>
。应该使用defineExpose
来公开要在父上下文中使用的方法或其他内容。
// child component
import { defineExpose } from 'vue'
// cannot be accessed from outside
function hello(){
console.log('hello')
}
// can be accessed from outside cause defineExpose
function hello2(){
console.log('hello2')
}
defineExpose({ hello2 })