--- title: Vue.js 3.0 の新機能を試す。 〜 Teleport 編〜 tags: Vue.js TypeScript author: ryo2132 slide: false --- 2020/05/04 追記 `portal` は `teleport` にリネームされたようです。 記事内容も修正しました。 https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md#300-alpha11-2020-04-04 -- 2020年Q1リリース予定のVue.js 3.0の新機能 `Teleport` を試してみたのでまとめます。 (参考) 以下でVue 3.0(vue-next)の環境構築、他の新機能についてもまとめています。 * [vue\-next(Vue\.js 3\.0 wip)\+ TypeScript \+ webpackでの開発環境を構築する](https://qiita.com/ryo2132/items/2b10f03e3d4ea04be649) * [Vue.js 3.0 の新機能を試す。 〜 Suspense 編〜](https://qiita.com/ryo2132/items/7225d60768a15dabfb9f) # Teleportとは? 定義したコンポーネントが属するDOMツリーとは別の場所に、まるでテレポートしたかのようにコンポーネントを移動できる機能です。 直接指定の位置に表示できるので、 * Modal、Tooltipなど要素の上部レイヤーに表示したいコンテンツでもz-indexでのCSSハックが不要になる * Modalなどの独立したコンポーネントに対して親要素のstyle干渉を防げる などの利点があります。 Vue.js 2系でもサードパーティのプラグイン [LinusBorg/portal\-vue](https://github.com/LinusBorg/portal-vue) を使えば実現できます。 Vue.js 3.0ではそれを仮想DOMレベルでサポートするようです。(実装詳細まではあまり理解してない) ![Feb-04-2020 20-13-33.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/489ec9ef-286d-0d95-0174-ea11cb8ae0d6.gif) (PortalVueのロゴ。概念を表していてとても良い。) # Teleportの書き方 ``コンポーネントにtargetを指定した上で、内部に別箇所で描画したい要素を記載するだけです。それだけで、targetで指定したセレクタの要素内部に、``内部の要素が移動して描画されます。 セレクタで指定する要素は、VueのDOMツリー外部のものでも可能です。 ```sample.vue ``` # Teleportのサンプルアプリの実装 下記画像のようなサンプルアプリを作っていきます。 画像右側のデバックコンソールをみると、モーダル要素は`App.vue`がマウントされている`
`ではなく、`
`内部に表示されるのがわかると思います。 一応動作コードはこちらのリポジトリにあります。 https://github.com/kawamataryo/vue-next-ts-webpack-preview/tree/portal-demo ![Feb-04-2020 07-06-45 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/59e70d9e-25b2-00ef-c948-4dd40e805da1.gif) ## App.vue まずTeleportを定義するApp.vueの実装です。 ``コンポーネントの要素として`to="#teleport-target"`を指定しています。 そして内部に`v-if`で表示制御するモーダル要素を配置しています。 ```App.vue ``` ## main.ts 次にApp.vueをマウントするmain.tsです。 サンプルアプリでは、`id="app"`をApp.vueのマウント対象としています。 ```main.ts import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ``` ## index.html 最後にTeleportの移動先となるindex.htmlです。 App.vueのマウント対象の`
`、Teleportのtargetとしてた`
`を配置します。 `
`自体は通常のDOM要素ですが、ここにApp.vueの``内部に指定した要素が移動して描画されます。 ```index.html Vue3.0 demo
``` # 終わりに 以上、Vue.js 3.0 の新機能を試す。 〜Teleport 編〜 でした z-indexや親スタイルの干渉防ぐをCSSをハックしなくて良いのは便利ですね。コードを綺麗に保てそうです。 portal-vueを使えばVue 2系の現行プロジェクトでも使えるので積極的に使っていきたいです。 # 参考 - https://speakerdeck.com/kazupon/mamonakuyatutekuru-vue-dot-js-3 - https://vueschool.io/articles/vuejs-tutorials/portal-a-new-feature-in-vue-3/