Vue集成原生Web组件时属性无响应的问题咨询及实现方案疑问
Vue集成原生Web组件时属性无响应的问题咨询及实现方案疑问
我正在尝试把一个原生JS的Web组件集成到Vue中,写了个很简单的Demo,用来渲染姓名作为概念验证。
class HelloWorld extends HTMLElement { static observedAttributes = ["name", "surname"]; constructor() { super(); } connectedCallback() { const shadow = this.attachShadow({ mode: 'closed' }), hwMsg = `Hello ${ this.name } ${ this.surname }`; shadow.append(hwMsg); } // attribute change attributeChangedCallback(property, oldValue, newValue) { console.log('property ', property, ' changed from ', oldValue, ' to ' newValue); if (oldValue === newValue) return; this[ property ] = newValue; } } customElements.define('hello-world', HelloWorld);
我已经在vite.config文件里把hello-world标签注册为自定义元素了:
export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.includes('hello-world') } } }) ...]
我在要使用这个Web组件的Vue组件里引入了它:
<script setup lang="ts"> import '@/web_components/prova_web'; import { ref } from 'vue'; const name = ref('John'); const surname = ref('Smith'); </script> <template> <main class="main-view"> <form> <input id="model_name" v-model="name"/> <input id="model_surname" v-model="surname"> </form> Current values: {{ name }} {{ surname }} <br/> <hello-world :name="name" :surname="surname"></hello-world> </main> </template> <style scoped> </style>
代码第一次渲染是正常的,attributeChangedCallback也正确触发了两个属性的变更。但当我通过表单输入框修改属性值时,attributeChangedCallback没有再次触发,虽然Vue的ref值已经更新了(并且在自定义标签上方正确渲染了最新值)。
很奇怪的是,第一次渲染时ref的值能正确传递给Web组件,但后续ref值的变更却没被Web组件识别到。我想知道能不能用纯JavaScript实现这种响应式属性绑定,还是说必须用Lit这类框架才行?
备注:内容来源于stack exchange,提问作者Fiorenza Oppici
相关产品推荐
相关产品推荐

