ホームページ  >  記事  >  ウェブフロントエンド  >  Vue3 を使用して Web コンポーネントを構築する方法について話しましょう

Vue3 を使用して Web コンポーネントを構築する方法について話しましょう

青灯夜游
青灯夜游転載
2022-09-08 20:20:582767ブラウズ

Vue3 を使用して Web コンポーネントを構築するにはどうすればよいですか?以下の記事ではVue3でWebコンポーネントを構築する方法を紹介していますので、ぜひ参考にしてください。

Vue3 を使用して Web コンポーネントを構築する方法について話しましょう

場合によっては、フレームワークに依存しないコンポーネントを書きたいことがありますが、ネイティブや Jquery を使用して書きたくないこともあります。また、スタイルの競合も避ける必要があります。これを行うには Web コンポーネントを使用するのが適切だと思います。非常に適切です。しかし、Web Components はまだ柔軟性が低く、不便なところも多いので、MVVM と組み合わせて利用できると良いですね。 Angular は以前から Web コンポーネントへのコンポーネントの構築をサポートしていましたが、Vue3 3.2 ではついに Web コンポーネントへのコンポーネントの構築をサポートしました。最近たまたまコメントプラグインを再構築したくなったので試してみました。

Web コンポーネントの構築

vue には、vue コンポーネントを HTMLElement に拡張されるカスタム関数構造に変換する defineCustomElement メソッドが用意されています。 関数と使用法基本的には、defineComponent パラメータ API と同じです。 [関連する推奨事項: vuejs ビデオ チュートリアル ]

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 に変更できます。すべてのファイル Web コンポーネント をビルドする必要がある場合は、@vitejs/plugin-vue@^1.4.0 または vue-loader@^16.5.0 を実行できます。 customElement 構成項目が有効になります。これにより、.ce.vue というサフィックス名を使用する必要がなくなりました。

Attributes

vue は、すべてのプロパティをカスタム要素オブジェクトのプロパティにマップし、カスタム要素タグの属性もマップします。

<com-demo></com-demo>

props:{
  type:String
}

HTML の attribute は、基本型 (Boolean、Number) を除き、文字列のみにすることができるため、Vue はマッピング中の型変換に役立ち、他の複雑な型は DOM に設定する必要があります。 . 敷地内にあります。

イベント

カスタム要素で、this.$emit または setup を介して Emit によって発行されるイベント はネイティブ CustomEvent として送出されます。追加のイベント パラメーター (ペイロード) は、CustomEvent オブジェクトの詳細プロパティの配列として公開されます。

スロット

コンポーネントを作成する場合、vue と同様に使用できますが、ネイティブ スロット構文のみを使用できるため、スコープ スロットはサポートされなくなりました。

サブコンポーネントのスタイルの問題

ネストされたサブコンポーネントを使用する場合、サブコンポーネント内のスタイルがデフォルトでは抽出されないという落とし穴があります。

親コンポーネント

<template>
    <div>{{ title }}</div>
    <childer></childer>
</template>
<script>
import Childer from "./childer.vue"
export default {
    components: { Childer },
    data() {
        return {
            title: "父组件"
        }
    },
}
</script>
<style>
.title {
    padding: 10px;
    background-color: #eee;
    font-weight: bold;
}
</style>

サブコンポーネント

<template>
    <div>{{ title }}</div>
</template>
<script>
export default {
    data() {
        return {
            title: "子组件"
        }
    },
}
</script>
<style>
.childer {
    padding: 10px;
    background-color: #222;
    color: #fff;
    font-weight: bold;
}
</style>

サブコンポーネントのスタイルが挿入されていないことがわかりますが、スタイル分離識別子はdata-v-5e87e937として生成されます。 Vue 公式が今後このバグを修正するかどうかはわかりません

Vue3 を使用して Web コンポーネントを構築する方法について話しましょう
コンポーネントを見ると、サブコンポーネントのスタイルが抽出されていることがわかります。自分で注射するだけで済みます。

Vue3 を使用して Web コンポーネントを構築する方法について話しましょう

サブコンポーネント スタイルを抽出して親コンポーネントに挿入します。この実装を参照してください

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))

サブコンポーネント スタイルの問題を完全に解決します

Vue3 を使用して Web コンポーネントを構築する方法について話しましょう

Method

defineCustomElement デフォルトでは、ビルドされたコンポーネントは customElement## にメソッドをアタッチしません。 #. Vueのソースコードを見ると、_def(コンストラクタ)、_instance(コンポーネントインスタンス)のみです。コンポーネント内のメソッド dom._instance.proxy.fun() を呼び出したい場合、それは非常に洗練されていないように感じられます。
Vue3 を使用して Web コンポーネントを構築する方法について話しましょう もちろん、コンポーネントによって公開されるメソッドが通常の dom と同様に dom.fun() から直接削除できることを望んでいます。

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;
}
概要

一般的に言えば、落とし穴はまだた​​くさんありますが、比較的単純なクロスフレーム プラグインを構築するだけの場合は、次のことも可能です。この方法を使用して Web コンポーネントを構築するのは良い解決策です。

プログラミング関連の知識について詳しくは、

プログラミング入門

をご覧ください。 !

以上がVue3 を使用して Web コンポーネントを構築する方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。