好了,我知道这个问题已经有了一些变化,在不同版本和API的Vue中...但我一直没能弄清楚,所以这里的背景下,为什么我认为我的是不同的:
我正在尝试构建一些组件:
1.内部足够复杂,使用Vue而不仅仅是native web components构建是有帮助的,但是...
1.将在页面上的Vue上下文之外运行(而不是在Vue应用程序中),因此被打包为Web组件/自定义元素from Vue,并且...
1.实现将在<form>
s中使用的数据输入(同样,不在Vue应用程序中)。
其中一个挑战是Vue Web Components使用shadow DOM,表单不会自动遍历shadow根来查找输入:因此,使表单实际看到并提交组件的内部数据并不是自动的。
看起来有一些希望,如this helpful blog post中详细说明的那样:一个新的ElementInternals API和element-internals-polyfill NPM包,通过它组件可以指示数据直到表单。实现一个“表单关联的自定义元素”需要设置一个静态的只读布尔属性(很简单),但也需要链接如下内容:
// (`this` == the custom HTMLElement itself)
const _internals = this.attachInternals();
_internals.setFormValue(value);
*问题是,我真的很难弄清楚我可以在哪里挂接以访问 * 两者 :
- 挂载的DOM元素(影子根上方的元素,即
<my-custom-element>
,不是只是模板中的一些ref()
),和 - 要获得
value
的组件的无功状态
……到目前为止,我主要使用Vue的composition and script setup
APIs,无可否认地感觉他们让这变得更难:例如,onMounted
根本没有定义this
。但即使使用等效的选项API mounted: () => {}
,我看到this.$el
似乎是模板/影子根中的第一个元素,而不是拥有影子根的父自定义元素。
我还考虑了另一种方法--从创建的CustomElement类开始,并尝试返回到有用的Vue数据和钩子。但在这里也找不到路:
import { defineCustomElement } from "vue";
import MyCustomComponent from "./components/MyCustomComponent.ce.vue"
const MyCustomElement = defineCustomElement(MyCustomComponent);
class MyCustomElementFormAssoc extends MyCustomElement {
static get formAssociated() {
return true;
}
constructor(initialProps?: Record<string, any> | undefined) {
super(initialProps);
const _internals = this.attachInternals();
// But here the component isn't even mounted yet - this._instance doesn't
// exist and presumably reactive state doesn't either, so can't do:
// _internals.setFormValue(someValueState);
}
}
customElements.define("my-custom-element", MyCustomElementFormAssoc);
因此,一般来说,与其他Vue 3的答案"there is no single root element and we should use refs instead"一致,在我的例子中,我特别试图访问 * 定义组件的自定义元素 * -而不是模板中的元素。呈现的DOM看起来像这样:
<my-custom-element class="this-one-is">
#shadow-root (open)
<div class="custom-element-template-can-have-multiple-roots"></div>
<div class="but-these-are-not-the-elements-im-looking-for"></div>
</my-custom-element>
有人知道怎么做吗?
1条答案
按热度按时间rkue9o1l1#
同意这是一个糟糕的代码气味,也是一个评估Vue是否真的适合一般用例的信号:使用混合的Web组件进行黑客攻击,这些组件不是很原生,但也不是很Vue,即使它在今天工作,也可能是一个维护负担。
但是需求必须-我目前的解决方法是通过DOM从模板中的一些引用元素(并不重要)进行跟踪,就像这样: