使用 portal-vue 控制 Vue.js 应用程序外部的 DOM

Vue.js的最大优势之一是它可以用于改进或更换旧应用程序或甚至静态页面的部分,这种渐进性使得Vue可以逐步采用或仅用于改进现有应用程序。

安装

通过 Yarn 或 NPM 安装门户视图。

1# Yarn
2$ yarn add portal-vue
3# NPM
4$ npm install portal-vue --save

现在,启用 PortalVue 插件。

 1[label main.js]
 2import Vue from 'vue';
 3import PortalVue from 'portal-vue';
 4import App from 'App.vue';
 5
 6Vue.use(PortalVue);
 7
 8new Vue({
 9  el: '#app',
10  render: h => h(App)
11});

目标组件

所以,让我们创建创建原始门户组件的源组件,它也可以拥有自己的内容,只有门户组件内部的东西才能移动。

 1[label AComponent.vue]
 2<template>
 3  <div>
 4    <portal to="other-component">
 5      <p>{{message}}</p>
 6    </portal>
 7    <p>Other stuff stays here.</p>
 8  </div>
 9</template>
10
11<script>
12
13export default {
14  data() {
15    return {
16      message: 'I get rendered in OtherComponent!'
17    }
18  }
19}
20
21</script>

现在,只要 AComponent 和 OtherComponent 都被渲染,AComponent 门户的内容将最终被渲染到 OtherComponent 中。

1[label AComponent.vue]
2<template>
3  <div>
4    <portal-target name="other-component">
5    </portal-target>
6    <p>I have my own stuff too!</p>
7  </div>
8</template>

在家中的任何地方瞄准

有了微小的变化,我们可以将门户内容输出到整个网页的DOM中的任何地方!

 1[label AComponent.vue]
 2<template>
 3  <div>
 4    <portal target-el="#place-on-the-page">
 5      <p>{{message}}</p>
 6    </portal>
 7    <p>Other stuff stays here.</p>
 8  </div>
 9</template>
10
11<script>
12
13export default {
14  data() {
15    return {
16      message: 'I get rendered in the element with the id #place-on-the-page!'
17    }
18  }
19}
20
21</script>

现在,只要 AComponent 和 OtherComponent 都被渲染,AComponent 门户的内容将最终被渲染到 OtherComponent 中。

 1[label index.html]
 2<!DOCTYPE html>
 3<html lang="en">
 4  <head>
 5    <meta charset="utf-8">
 6    <title>Vue-Portal Example</title>
 7  </head>
 8  <body>
 9    <!-- Vue app -->
10    <div id="app">
11      ...
12    </div>
13    <script src="/dist/build.js"></script>
14
15    <!-- Other random stuff on the page -->
16    <section class="something-else">
17      <h4>What is going on here! Who let the Vue app out?</h4>
18
19      <!-- Contents of the portal replace the div here -->
20      <div id="place-on-the-page">
21      </div>
22    </section>
23  </body>
24</html>

尼克,是吗?

选择

  • 如果设置为假,它会将内容转换为门户组件内部,而不是门户目标或目标-el。这个门户是反动的,所以你可以随意改变它
  • 如果门户被禁用,你也可以添加薄型门户,以避免添加额外的包装元素 *你也可以使用标签 prop来确定门户组件在禁用时将哪个元素转换为

潜在问题

(详情请参见此处)。

  • Portal 和 PortalTarget 组件可能表现得很奇怪,因为它们是抽象的组件,所以不要试图像正常组件一样操纵或访问它们 *使用 SSR 时,门户目标组件必须在 DOM 中的门户组件之后出现。否则,Vue 会感到困惑并重新渲染整个应用程序
  • 使用 SSR 时,您可能应该确保 DOM 以外的任何目标元素不是实际的 HTML 元素。
Published At
Categories with 技术
Tagged with
comments powered by Disqus