Dam*_*nov 15 vue.js vuejs3 vue-composition-api
我想用来onMounted启动第三方库。为此,我需要组件元素作为其上下文。在 Vue 2 中,我会使用它,this.$el但不确定如何使用组合函数来实现。setup有两个参数,没有一个包含元素。
setup(props, context) {
onMounted(() => {
interact($el)
.resizable();
})
}
Run Code Online (Sandbox Code Playgroud)
And*_*hiu 18
tl;博士:
在 Vue 3 中,组件不再仅限于 1 个根元素。隐含地,这意味着您不再拥有$el.
您必须使用ref与模板中的任何元素进行交互。
正如@AndrewSee 在评论中指出的那样,当使用渲染函数(不是模板)时,您可以ref在createElement选项中指定所需的内容:
render: function (createElement) {
return createElement('div', { ref: 'root' })
}
// or, in short form:
render: h => h('div', { ref: 'root' })
Run Code Online (Sandbox Code Playgroud)
初步回答:
正如文档中所述,
[...]响应式引用和模板引用的概念在 Vue 3 中是统一的。
你还有一个关于如何ref“根”元素的例子。显然,您不需要将其命名为 root。命名它$el,如果你愿意。但是,这样做并不意味着它将作为 提供this.$el,而是作为this.$refs.$el.
render: function (createElement) {
return createElement('div', { ref: 'root' })
}
// or, in short form:
render: h => h('div', { ref: 'root' })
Run Code Online (Sandbox Code Playgroud)
在 Vue 3 中,您不再仅限于 中的一个根元素<template>,因此您必须特别确定ref要与之交互的任何元素。
$el提供替代方案。即使您使用带有Options API的Vue 3,由于Fragments的可用性,建议使用模板引用来直接访问DOM节点,而不是依赖于this.$el.
假设我们有一个用于第三方库的 div 元素:
<template>
Below we have a third-party-lib
<div class="third-party-lib"></div>
</template>
Run Code Online (Sandbox Code Playgroud)
然后我们想从 Javascript 启动它:
解决方案 1(推荐):使用模板引用
<script setup>
import { ref, onMounted } from 'vue';
const $thirdPartyLib = ref(null); // template ref
onMounted(() => {
$thirdPartyLib.value.innerText = 'Dynamically loaded';
});
</script>
<template>
Below we have a third-party-lib
<div ref="$thirdPartyLib" class="third-party-lib"></div>
</template>
Run Code Online (Sandbox Code Playgroud)
解决方案2(不推荐):使用未记录的
@VnodeMounted
<script setup>
function initLib({ el }) {
el.innerText = 'Dynamic content';
}
</script>
<template>
Below we have a third-party-lib
<div class="third-party-lib" @VnodeMounted="initLib"></div>
</template>
Run Code Online (Sandbox Code Playgroud)
只是在这里添加我的 2 美分,并想纠正其他一些答案所说的 Vue 3 不再有的内容$el。
它仍然有它: https: //vuejs.org/api/component-instance.html#el。
$el在多根元素无法确定为特定根元素的情况下,不鼓励使用它,并且为了与单根组件保持一致(其中 $el 的工作方式与 Vue 2 相同),文档建议您使用 $refs 代替。
对于多根组件,$el引用位于元素之前最近的文本节点(或 SSR 水合的注释)。
$el相反,这并不意味着不可靠,因为这种机制是内部使用的,用于 SSR 水合。
在大多数情况下,您可以使用$refs并且应该使用。
但如果你不能,就像下面的例子一样,你仍然可以依靠$el:
<template>
# an empty text node exists here in the DOM.
<slot name="activator" :on="activatorEventHandlers">
<other-component />
</template>
Run Code Online (Sandbox Code Playgroud)
在这种情况下(工具提示和上下文菜单的情况,其中事件侦听器附加到用户槽),第一个元素是槽,并且您无法在槽上添加引用。
因此 using$el将指向第一个文本节点,因此this.$el.nextElementSibling将指向通过用户槽给出的元素。