我想用来onMounted
启动第三方库。为此,我需要组件元素作为其上下文。在 Vue 2 中,我会得到它,this.$el
但不确定如何使用组合函数来完成它。setup
有两个参数,它们都不包含元素。
setup(props, context) {
onMounted(() => {
interact($el)
.resizable();
})
}
我想用来onMounted
启动第三方库。为此,我需要组件元素作为其上下文。在 Vue 2 中,我会得到它,this.$el
但不确定如何使用组合函数来完成它。setup
有两个参数,它们都不包含元素。
setup(props, context) {
onMounted(() => {
interact($el)
.resizable();
})
}
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' })
初步答案:
如文档中所述,
[...]反应式引用和模板引用的概念在 Vue 3 中是统一的。
您还有一个关于如何ref
创建“根”元素的示例。显然,您不需要将其命名为 root。命名它$el
,如果你愿意的话。但是,这样做并不意味着它将以 . 的形式提供this.$el
,而是以this.$refs.$el
.
<template>
<div ref="root"></div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup() {
const root = ref(null)
onMounted(() => {
// the DOM element will be assigned to the ref after initial render
console.log(root.value) // this is your $el
})
return {
root
}
}
}
</script>
在 Vue 3 中,您不再仅限于 中的一个根元素<template>
,因此您必须专门ref
指定要与之交互的任何元素。
$el
提供替代方案。即使您使用带有 Options API 的 Vue 3,由于 Fragments 的可用性,建议使用模板 refs 来直接访问 DOM 节点,而不是依赖this.$el
.
假设我们有一个用于第三方库的 div 元素:
<template>
Below we have a third-party-lib
<div class="third-party-lib"></div>
</template>
然后我们想从 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>
解决方案 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>