<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          vue3.0新特性teleport是啥,用起來(lái)真香

          共 4628字,需瀏覽 10分鐘

           ·

          2021-07-05 08:42

          前言

          vue2.0時(shí)代,我們經(jīng)常會(huì)有這樣的需求,寫(xiě)代碼邏輯的時(shí)候希望將組件寫(xiě)在某個(gè)模板之下,因?yàn)檫@樣我們很好的使用組件內(nèi)部的狀態(tài)數(shù)據(jù),控制組件的展示形態(tài)。但是從技術(shù)的角度上我們又希望將這段代碼移到DOMVue app之外的其他位置。

          舉個(gè)簡(jiǎn)單的例子,我們?cè)谑褂?code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">modal組件的時(shí)候,我們將它放在了我們的模板template里面,但是由于modal組件希望位于頁(yè)面的最上方,這時(shí)候我們將modal組件掛載在body上面是最好控制的,我們能夠很好的通過(guò)zIndex來(lái)控制modal的位置,當(dāng)他嵌套在templat里面的時(shí)候就不那么容易了。

          vue2.0中的實(shí)現(xiàn)

          vue2.0中我在寫(xiě)這個(gè)組件的時(shí)候是通過(guò)手動(dòng)的形式來(lái)進(jìn)行掛載的,我寫(xiě)了一個(gè)vue指令來(lái)進(jìn)行這個(gè)操作,幫助我將modal組件掛載到body上面去,專(zhuān)這樣也能夠很好的通過(guò)控制zIndex來(lái)控制modal的展示。

          function insert(el{
            const parent = el.parentNode;
            if (parent && parent !== document.body) {
                parent.removeChild(el);
                document.body.appendChild(el);
            }
          }

          export default (typeof window !== 'undefined' ? {
            inserted(el, { value }) {
                if (value) {
                    insert(el);
                }
            },
            componentUpdated(el, { value }) {
                if (value) {
                    insert(el);
                }
            },
          } : {});

          上面的代碼其實(shí)就是簡(jiǎn)單的將modal從他原始掛載的父節(jié)點(diǎn)移除,然后掛載到body上去,通過(guò)手動(dòng)的形式來(lái)重新掛載,能夠很好的解決這種問(wèn)題,當(dāng)然上面只是簡(jiǎn)單的邏輯,如果需要考慮卸載等其他邏輯代碼還得增加。

          <template>
            <div class="modal" v-to-body="show" v-if="show">
              <div class="modal-mask" @click="close"></div>
              <slot></slot>
            </div>

          </template>

          <script>
          import "./
          style.scss";
          import toBody from "
          ../directives/to-body";
          export default {
            props: {
              show: Boolean,
            },
            directives: {
              toBody,
            },
            methods: {
              close() {
                this.$emit("
          close");
              },
            },
          };
          </script>

          說(shuō)實(shí)話vue2.0中的實(shí)現(xiàn)其實(shí)是沒(méi)啥問(wèn)題的,只是不是很優(yōu)雅,需要額外的代碼控制,所以vue3.0中直接帶來(lái)了Teleport-任意傳送門(mén)

          具體代碼參考vue2.0-modal: https://codesandbox.io/s/vue20-modal-sc1rq

          什么是Teleport

          Teleport能夠直接幫助我們將組件渲染后頁(yè)面中的任意地方,只要我們指定了渲染的目標(biāo)對(duì)象。Teleport使用起來(lái)非常簡(jiǎn)單。

          <template>
            <teleport to="body" class="modal" v-if="show">
              <div class="modal-mask" @click="close"></div>
              <slot></slot>
            </teleport>

          </template>

          <script>
          import "./
          style.scss";
          export default {
            props: {
              show: Boolean,
            },
            methods: {
              close() {
                this.$emit("
          close");
              },
            },
          };
          </script>

          上面的代碼我們就能夠很簡(jiǎn)單的實(shí)現(xiàn)之前vue2.0所實(shí)現(xiàn)的功能。

          具體代碼參考vue3.0-modal: https://codesandbox.io/s/vue3-modal-x2lud

          注意點(diǎn)

          與 Vue components 一起使用

          在這種情況下,即使在不同的地方渲染child-component,它仍將是parent-component的子級(jí),并將從中接收name prop

          這也意味著來(lái)自父組件的注入按預(yù)期工作,并且子組件將嵌套在Vue Devtools中的父組件之下,而不是放在實(shí)際內(nèi)容移動(dòng)到的位置。

          const app = Vue.createApp({
            template`
              <h1>Root instance</h1>
              <parent-component />
            `

          })

          app.component('parent-component', {
            template`
              <h2>This is a parent component</h2>
              <teleport to="#endofbody">
                <child-component name="John" />
              </teleport>
            `

          })

          app.component('child-component', {
            props: ['name'],
            template`
              <div>Hello, {{ name }}</div>
            `

          })
          在同一目標(biāo)上使用多個(gè)teleport

          當(dāng)我們將多個(gè)teleport送到同一位置時(shí)會(huì)發(fā)生什么?

          <teleport to="#modals">
            <div>A</div>
          </teleport>
          <teleport to="#modals">
            <div>B</
          div>
          </teleport>

          <!-- result-->
          <div id="modals">
            <div>A</
          div>
            <div>B</div>
          </div>

          我們可以看到對(duì)于這種情況,多個(gè)teleport組件可以將其內(nèi)容掛載到同一個(gè)目標(biāo)元素。順序?qū)⑹且粋€(gè)簡(jiǎn)單的追加——稍后掛載將位于目標(biāo)元素中較早的掛載之后。

          總結(jié)

          一句話來(lái)描述Teleport就是一種將代碼組織邏輯依舊放在組件中,這樣我們能夠使用組件內(nèi)部的數(shù)據(jù)狀態(tài),控制組件展示的形式,但是最后渲染的地方可以是任意的,而不是局限于組件內(nèi)部


          - END -

          點(diǎn)贊 + 在看 + 分享,一鍵三連,幸福滿(mǎn)滿(mǎn)!

          瀏覽 53
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧洲久久网 | 亚洲精品成人无码AV在线 | 国产寡妇婬乱A毛片91精品 | 欧美成人一区二区三区在线视频 | 国产精品久久久久久爽爽爽麻豆色哟哟 |