如何在 Svelte 中获取组件的 dom 节点?
How do I get the dom node of a component in Svelte?
假设我呈现以下对话框:
let dialog;
<MyDialog bind:this={dialog}/>
我想定位这个对话框(我猜是使用 afterUpdate
生命周期函数)。但是,dialog
不是 dom 元素。当我记录它时,它看起来像:
MyDialog {$$: {…}, left: 785, $set: ƒ, $capture_state: ƒ, $inject_state: ƒ}
$$: {fragment: {…}, ctx: Array(1), props: {…}, update: ƒ, not_equal: ƒ, …}
$capture_state: () => {…}
$inject_state: $$props => {…}
$set: $$props => {…}
someExportedProp: (...)
__proto__: SvelteComponentDev
如何访问其 dom 以便对其进行定位?
MyDialog
不是 DOM 元素,它是一个 Svelte 组件。因此,这就是您在 bind:this
上得到的:一个 Svelte 组件。
绑定到实际元素时,您只会得到一个 DOM 元素:
<div bind:this={el} />
如果您需要从其消费者(父)组件访问 MyDialog
的 DOM,则需要从 MyDialog
组件对其进行代理。
MyDialog.svelte
<script>
export let el
</script>
<div class="dialog" bind:this={el}>
<slot />
</div>
App.svelte
<script>
import MyDialog from './MyDialog.svelte'
let dialog
$: console.log(dialog) // here, DOM element!
</script>
<MyDialog bind:el={dialog}>
Hello!
</MyDialog>
话虽如此,在将 DOM 元素泄漏到组件外部之前,我会三思而后行。它有点破坏封装,这通常会使您的生活变得复杂...也许您可以想出一个更好的解决方案来控制您的对话位置,而不让消费者直接访问组件的内部结构?
编辑
用道具移动...
道具是“反应性的”,它们的值会自动反映在框架的 DOM 中,因此您不需要 运行 一个函数来移动东西。你可以只声明你想要的。这是这些声明性框架的首选样式。
<script>
export let top
export let left
$: style = `top: ${top}px; left: ${left}px`
</script>
<div class="dialog" {style}>
<slot />
</div>
如果你也需要,你仍然可以 运行 当 props 改变时(强制性地)使用 reactive blocks:
一些代码
<script>
export let top
export let left
let el
// reactive block will rerun each time el, top, or left changes
$: if (el) {
el.style.top = top + 'px'
el.style.left = left + 'px'
}
</script>
<div class="dialog" bind:this={el}>
<slot />
</div>
假设我呈现以下对话框:
let dialog;
<MyDialog bind:this={dialog}/>
我想定位这个对话框(我猜是使用 afterUpdate
生命周期函数)。但是,dialog
不是 dom 元素。当我记录它时,它看起来像:
MyDialog {$$: {…}, left: 785, $set: ƒ, $capture_state: ƒ, $inject_state: ƒ}
$$: {fragment: {…}, ctx: Array(1), props: {…}, update: ƒ, not_equal: ƒ, …}
$capture_state: () => {…}
$inject_state: $$props => {…}
$set: $$props => {…}
someExportedProp: (...)
__proto__: SvelteComponentDev
如何访问其 dom 以便对其进行定位?
MyDialog
不是 DOM 元素,它是一个 Svelte 组件。因此,这就是您在 bind:this
上得到的:一个 Svelte 组件。
绑定到实际元素时,您只会得到一个 DOM 元素:
<div bind:this={el} />
如果您需要从其消费者(父)组件访问 MyDialog
的 DOM,则需要从 MyDialog
组件对其进行代理。
MyDialog.svelte
<script>
export let el
</script>
<div class="dialog" bind:this={el}>
<slot />
</div>
App.svelte
<script>
import MyDialog from './MyDialog.svelte'
let dialog
$: console.log(dialog) // here, DOM element!
</script>
<MyDialog bind:el={dialog}>
Hello!
</MyDialog>
话虽如此,在将 DOM 元素泄漏到组件外部之前,我会三思而后行。它有点破坏封装,这通常会使您的生活变得复杂...也许您可以想出一个更好的解决方案来控制您的对话位置,而不让消费者直接访问组件的内部结构?
编辑
用道具移动...
道具是“反应性的”,它们的值会自动反映在框架的 DOM 中,因此您不需要 运行 一个函数来移动东西。你可以只声明你想要的。这是这些声明性框架的首选样式。
<script>
export let top
export let left
$: style = `top: ${top}px; left: ${left}px`
</script>
<div class="dialog" {style}>
<slot />
</div>
如果你也需要,你仍然可以 运行 当 props 改变时(强制性地)使用 reactive blocks:
一些代码<script>
export let top
export let left
let el
// reactive block will rerun each time el, top, or left changes
$: if (el) {
el.style.top = top + 'px'
el.style.left = left + 'px'
}
</script>
<div class="dialog" bind:this={el}>
<slot />
</div>