本篇內(nèi)容介紹了“如何用Vue3構(gòu)建Web Components”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)公司作為成都網(wǎng)站建設(shè)公司,專注成都網(wǎng)站建設(shè)公司、網(wǎng)站設(shè)計,有關(guān)成都定制網(wǎng)站方案、改版、費用等問題,行業(yè)涉及花箱等多個領(lǐng)域,已為上千家企業(yè)服務(wù),得到了客戶的尊重與認可。
vue 提供了一個 defineCustomElement方法,用來將 vue 組件轉(zhuǎn)換成一個擴展至HTMLElement的自定義函數(shù)構(gòu)造函數(shù),使用方式和 defineComponent參數(shù)api基本保持一致。
import { defineCustomElement } from 'vue' const MyVueElement = defineCustomElement({ // 在此提供正常的 Vue 組件選項 props: {}, emits: {}, template: `...`, // defineCustomElement 獨有特性: CSS 會被注入到隱式根 (shadow root) 中 styles: [`/* inlined css */`] }) // 注冊 Web Components customElements.define('my-vue-element', MyVueElement)
如果需要使用單文件,需要 @vitejs/plugin-vue@^1.4.0或 vue-loader@^16.5.0或更高版本工具。如果只是部分文件需要使用,可以將后綴改為 .ce.vue。若果需要將所有文件都構(gòu)建 Web Components可以將 @vitejs/plugin-vue@^1.4.0或 vue-loader@^16.5.0的 customElement配置項開啟。這樣不需要再使用 .ce.vue后綴名了。
vue 會把所有的的 props 自定義元素的對象的 property 上,也會將自定義元素標簽上的 attribute 做一個映射。
props:{ type:String }
因為 HTML 的 attribute的只能是字符串,除了基礎(chǔ)類型(Boolean、Number) Vue 在映射時會幫忙做類型轉(zhuǎn)換,其他復(fù)雜類型則需要設(shè)置到 DOM property 上。
在自定義元素中,通過 this.$emit或在 setup中的 emit發(fā)出的事件會被調(diào)度為原生 CustomEvents。附加的事件參數(shù) (payload) 會作為數(shù)組暴露在 CustomEvent 對象的 details property 上。
編寫組件時,可以想 vue 一樣,但是使用時只能原生的插槽語法,所以也不在支持作用域插槽。
使用子組件嵌套的時,有個坑的地方就是默認不會將子組件里的樣式抽離出來。
父組件
{{ title }}
子組件
{{ title }}
可以看到子組件的樣式?jīng)]有插入進去,但是樣式隔離的標識是有生成的 data-v-5e87e937。不知道vue官方后續(xù)會不會修復(fù)這個bug
查看組件是可以看到,子組件的樣式是有被抽離出來的,這樣就只需要自己注入進去了。
將子組件樣式抽離插入到父組件里,參考這個的實現(xiàn)
import ComDemo from '~/demo/index.vue' const deepStylesOf = ({ styles = [], components = {} }) => { const unique = array => [...new Set(array)]; return unique([...styles, ...Object.values(components).flatMap(deepStylesOf)]); } // 將子組件樣式插入到父組件里 ComDemo.styles = deepStylesOf(ComDemo) !customElements.get('com-demo') && customElements.define('com-demo', defineCustomElement(ComDemo))
完美解決子組件樣式問題
defineCustomElement構(gòu)建的組件默認是不會將方法掛到 customElement上的,看 Vue 源碼中,只有 _def(構(gòu)造函數(shù)),_instance(組件實例))。如果想調(diào)用組件內(nèi)的方法,dom._instance.proxy.fun(),感覺實在不太優(yōu)雅。
我們當然希望我們組件暴露的方法能像普通dom那樣直接 dom.fun() 去掉用,我們對 defineCustomElement稍作擴展。
import { VueElement, defineComponent } from 'vue' const defineCustomElement = (options, hydate) => { const Comp = defineComponent(options); class VueCustomElement extends VueElement { constructor(initialProps) { super(Comp, initialProps, hydate); if (Comp.methods) { Object.keys(Comp.methods).forEach(key => { // 將所有非下劃線開頭方法 綁定到 元素上 if(!/^_/.test(key)){ this[key] = function (...res) { if (this._instance) { // 將方法thi改為 組件實例的proxy return Comp.methods[key].call(this._instance.proxy, ...res) } else { throw new Error('未找到組件實例') } } } }) } } } VueCustomElement.def = Comp; return VueCustomElement; }
undefined
“如何用Vue3構(gòu)建Web Components”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!