Vue2 と Vue3 の両方に、コンポーネント ビルドなどの組み込みコンポーネントがあります。 -in コンポーネント、トランジション組み込みコンポーネントなど。組み込みコンポーネントは、公式にカプセル化されたグローバル コンポーネントであり、直接使用できます。
Vue3 に Teleport 組み込みコンポーネントが追加されました。まずは公式ドキュメントでどのように説明されているかを見てみましょう。
は、コンポーネント内のテンプレートの一部をコンポーネントの DOM 構造の外側の場所に「送信」できる組み込みコンポーネントです。
一般的な説明:
teleport は組み込みコンポーネントです。HTML には階層関係があることは誰もが知っており、Vue3 のコンポーネントにも階層関係があります。上下関係。
サブコンポーネントが親コンポーネント内で参照されている場合、サブコンポーネントの HTML は、ページにレンダリングされた後、親コンポーネントの HTML に確実に組み込まれます。
ただし、サブコンポーネントがテレポート コンポーネントに配置されている場合は、サブコンポーネントが親コンポーネント以外の他の DOM ノード (本体や他の DOM など) の下でレンダリングされるように指定できます。これは「テレポーテーション」に似ています。
Vue の UI コンポーネント ライブラリを使用する場合、モーダル ボックス コンポーネントを使用することがよくあります。例: Element-plus のモーダル ボックスを使用します。
<template> <el-button @click="dialogVisible = true">打开弹窗</el-button> <el-dialog v-model="dialogVisible" append-to-body title="我是弹窗" width="30%"> </el-dialog> </template> <script> import { ref } from 'vue'; export default { setup(){ const dialogVisible = ref(false); return { dialogVisible } } } </script>
上記のコードでは、Element-plus ポップアップ コンポーネントが App.vue コンポーネントで参照され、append-to-body 属性が追加されます。
ポップアップ コンポーネントは App.vue コンポーネントに記述されていますが、レンダリングされた結果では、ポップアップ コンポーネントが body ノードに属していることがわかります。これは、Element-plus のポップアップ ウィンドウの append-to-body 属性を削除した後、この属性を削除して結果がどうなるかを見てみましょう:
App.vue コンポーネントの下に移動すると、ポップアップ ウィンドウ コンポーネントが再び正常に動作することがわかります。
なぜこれを行うのでしょうか?
これは非常に簡単で、ポップアップ ウィンドウが多数ある場合に、それらの Z インデックス、つまりウィンドウが同時にポップアップしたときの階層関係をどのように管理するかです。ポップアップ ウィンドウが独自の親コンポーネント内にある場合、それを制御することはできません。階層関係を簡単に設定できるように、すべてのウィンドウを外して同じ親要素の下に配置する必要があります。
これはテレポート コンポーネントとどのような関係があるのでしょうか?上のポップアップ ウィンドウの append-to-body 属性効果は、Element によって行われます。そのような効果を自分で実現したい場合はどうすればよいでしょうか?組み込みのコンポーネント テレポートを使用できます。
<template> <div class="app"> App组件 <Teleport to="body"> <div>我是被 teleport 包裹的元素</div> </Teleport> </div> </template>
上図からわかるように、 Teleport パッケージは app.vue コンポーネントに属しますが、レンダリング後は body dom 要素の下にレンダリングされます。
これは Teleport の送信機能のおかげです。使い方は非常に簡単です。構文コードは次のとおりです。
where to は「送信」の宛先、つまりパッケージの中身の場所です。送信する必要があります。
<Teleport to="body"> </Teleport> to 允许接收值: 期望接收一个 CSS 选择器字符串或者一个真实的 DOM 节点。 提示: <Teleport> 挂载时,传送的 to 目标必须已经存在于 DOM 中。理想情况下,这应该是整个 Vue 应用 DOM 树外部的一个元素。 如果目标元素也是由 Vue 渲染的,你需要确保在挂载 <Teleport> 之前先挂载该元素。
< テレポート > は、レンダリングされた DOM 構造を変更するだけで、コンポーネント間の論理関係には影響しません。
つまり、< Teleport > にコンポーネントが含まれている場合、そのコンポーネントは、< teleport > を使用するコンポーネントとの論理的な親子関係を常に維持します。受信したプロパティとトリガーされたイベントも通常どおり機能します。
これは、親コンポーネントからの注入も期待どおりに機能し、子コンポーネントは実際のコンテンツの移動先ではなく、Vue Devtools の親コンポーネントの下にネストされることも意味します。
// 父组件 <template> <div class="app"> <Teleport to="body"> <div>被 teleport 包裹的组件-- {{count}}</div> <ChildComponent v-model="count"/> </Teleport> </div> </template> <script> import { ref } from 'vue'; import ChildComponent from '@/components/childComponent'; export default { components:{ ChildComponent }, setup(){ const count = ref(100); return { count, } } } </script>
// 子组件 <template> 子组件:<input type="text" v-model.number="inputVal" @input="userInput"> </template> <script> import { ref, watch } from 'vue'; export default { props:{ modelValue:{ default:0, } }, setup(props,{emit}) { const inputVal = ref(null); const userInput = () => { emit('update:modelValue', inputVal.value) }; watch(props,(newVal,oldVal) => { inputVal.value = props.modelValue; },{immediate:true}) return { userInput, inputVal, } }, } </script>
一部のシナリオでは、状況に応じて < テレポート > を無効にする必要がある場合があります。 < Teleport > ; これら 2 つの異なる状況を処理するために無効なプロパティを動的に渡します (disabled プロパティはブール値を受け取り、true は送信が許可されていないことを意味し、false は送信を意味します)。
<template> <div class="app"> app组件 <Teleport to="body" :disabled="true"> <p>我是被 teleport 包裹的元素</p> <p>{{ message }}</p> </Teleport> </div> </template> <script> import { ref } from 'vue'; export default { setup(){ const message = ref('我是在 App 组件内部'); return { message, } } } </script>
複数の コンポーネントは、そのコンテンツを同じターゲット要素にマウントできます。単にそれらを順番に追加するだけであり、後でマウントされたものはターゲット要素のさらに後ろに配置されます。
リーリーリーリー以上がVue3 で組み込みコンポーネント Teleport を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。