Skip to content

Commit

Permalink
feat: Micro front-end pop-up mount container
Browse files Browse the repository at this point in the history
  • Loading branch information
wangdaodao committed Sep 5, 2023
1 parent 290e68e commit d7ef11c
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 17 deletions.
3 changes: 2 additions & 1 deletion build/bin/build-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ const install = function(Vue, opts = {}) {
Vue.prototype.$ELEMENT = {
size: opts.size || '',
zIndex: opts.zIndex || 2000
zIndex: opts.zIndex || 2000,
content: opts.content || ''
};
Vue.prototype.$loading = Loading.service;
Expand Down
23 changes: 22 additions & 1 deletion examples/docs/en-US/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ Vue.prototype.$message = Message;

### Global config

When importing Element, you can define a global config object. For now this object has two properties: `size` and `zIndex`. The property `size` sets the default size for all components and the property `zIndex` sets the initial z-index (default: 2000) for modal boxes:
When importing Element, you can define a global config object. For now this object has three properties: `size` | `zIndex` | `content`. The property `size` sets the default size for all components and the property `zIndex` sets the initial z-index (default: 2000) for modal boxes, `content` is used in the micro front-end to solve the problem of sub application floating windows being mounted in the main application' body 'container, resulting in uncontrollable styles :

Fully import Element:

Expand All @@ -276,6 +276,27 @@ Vue.use(Button);

With the above config, the default size of all components that have size attribute will be 'small', and the initial z-index of modal boxes is 3000.

#### For micro front-end floating window escape sub applications

If the `content` field is set, all floating windows will be mounted in the `content` container:

```js
Vue.use(Element, { content: 'content' });
```

```html
<template>
<div id="app">
<!-- The original logic -->
...
<!-- Mount the container, if forgotten, it will automatically be mounted to the body -->
<div id="content"></div>
</div>
</template>
```

According to the above settings, all floating windows in the project will be mounted to the `content` container.

### Start coding

Now you have implemented Vue and Element to your project, and it's time to write your code. Please refer to each component's documentation to learn how to use them.
Expand Down
22 changes: 21 additions & 1 deletion examples/docs/es/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ Vue.prototype.$message = Message;

### Configuración global

Cuando importa Element, puede definir un objeto global de configuración. Por ahora este elemento solo contiene dos propiedades: `size`, `zIndex`. `size` define el tamaño por defecto de todos los componentes.
Cuando importa Element, puede definir un objeto global de configuración. Por ahora este elemento solo contiene dos propiedades: `size`, `zIndex`. `size` define el tamaño por defecto de todos los componentes. 'content' en la parte delantera del micro, se utiliza para resolver el problema de que las ventanas flotantes de la subaplicación se montan en el contenedor de la aplicación principal 'body' y el estilo no se puede controlar.

La propiedad `zIndex` indica el z-index inicial (por defecto: 2000) para los modal:

Expand All @@ -278,6 +278,26 @@ Vue.use(Button);

Con la anterior configuración, el tamaño por defecto de todos los componentes que tienen el atributo `size` será `small`. El valor inicial de z-index para los modals se ha establecido a 3000.

#### Para la aplicación de escape de ventanas flotantes en la parte delantera del micro

Si se establece el campo `content`, la ventana flotante se montará en el contenedor `content`:

```js
Vue.use(Element, { content: 'content' });
```

```html
<template>
<div id="app">
<!-- La lógica original -->
...
<!-- Montaje del contenedor, si se olvida, se monta automáticamente en el cuerpo -->
<div id="content"></div>
</div>
</template>
```

Siguiendo la configuración anterior, todas las ventanas flotantes del proyecto se montarán en el contenedor `content`.
### Empiece ya!

Ahora ha incorporado Vue y Element a su proyecto y es el momento para comenzar a programar. Por favor, refiérase a la documentación de cada componente para aprender cómo usarlos.
Expand Down
22 changes: 21 additions & 1 deletion examples/docs/fr-FR/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ Vue.prototype.$message = Message;

### Configuration globale

Lors de l'import d'Element, vous pouvez définir un objet de configuration global. Actuellement il possède de propriétés: `size` et `zIndex`. La propriété `size` détermine la taille par défaut de tout les composants et `zIndex` règle le z-index initial (default: 2000) des fenêtres modales:
Lors de l'import d'Element, vous pouvez définir un objet de configuration global. Actuellement il possède de propriétés: `size` et `zIndex`. La propriété `size` détermine la taille par défaut de tout les composants et `zIndex` règle le z-index initial (default: 2000) des fenêtres modales, `content` dans le microfrontal pour résoudre le problème de la fenêtre flottante de la Sous - application montée dans le conteneur `body` de l'application principale provoquant un style incontrôlable:

Import total d'Element:

Expand All @@ -276,6 +276,26 @@ Vue.use(Button);

Avec la configuration ci-dessus, la taille par défaut des composants ayant l'attribut size sera 'small', et le z-index initial des fenêtres modales est 3000.

#### Pour la Sous - application micro front Floating Window Escape

Si vous définissez le champ `content`, les fenêtres flottantes sont toutes montées dans le conteneur `content`:

```js
Vue.use(Element, { content: 'content' });
```

```html
<template>
<div id="app">
<!-- La logique originale -->
...
<!-- Monter le conteneur, automatiquement dans le corps si oublié -->
<div id="content"></div>
</div>
</template>
```
En suivant les paramètres ci - dessus, toutes les fenêtres flottantes du projet sont montées dans le conteneur `content`.

### Commencer à développer

Maintenant que vous avez ajouté Vue et Element à votre projet, vous pouvez commencer à coder. Référez-vous à la documentation de chaque composant pour savoir comment les utiliser.
Expand Down
23 changes: 22 additions & 1 deletion examples/docs/zh-CN/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ Vue.prototype.$message = Message;

### 全局配置

在引入 Element 时,可以传入一个全局配置对象。该对象目前支持 `size``zIndex` 字段。`size` 用于改变组件的默认尺寸,`zIndex` 设置弹框的初始 z-index(默认值:2000)。按照引入 Element 的方式,具体操作如下:
在引入 Element 时,可以传入一个全局配置对象。该对象目前支持 `size``zIndex``content` 字段。`size` 用于改变组件的默认尺寸,`zIndex` 设置弹框的初始 z-index(默认值:2000)`content` 在微前端中,用于解决子应用浮窗挂载到主应用 `body` 容器中导致样式无法控制。按照引入 Element 的方式,具体操作如下:

完整引入 Element:

Expand All @@ -276,6 +276,27 @@ Vue.use(Button);

按照以上设置,项目中所有拥有 `size` 属性的组件的默认尺寸均为 'small',弹框的初始 z-index 为 3000。

#### 针对微前端浮窗逃逸子应用

如果设置 `content` 字段,浮窗都会挂载到 `content` 容器中:

```js
Vue.use(Element, { content: 'content' });
```

```html
<template>
<div id="app">
<!-- 原来的逻辑 -->
...
<!-- 挂载容器,如果忘记,会自动挂载到 body 中 -->
<div id="content"></div>
</div>
</template>
```

按照以上设置,项目中所有的浮窗都会挂载到 `content` 容器中。

### 开始使用

至此,一个基于 Vue 和 Element 的开发环境已经搭建完毕,现在就可以编写代码了。各个组件的使用方法请参阅它们各自的文档。
Expand Down
1 change: 1 addition & 0 deletions packages/cascader/src/cascader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ const PopperMixin = {
popperOptions: Popper.props.popperOptions,
transformOrigin: Popper.props.transformOrigin
},
computed: Popper.computed,
methods: Popper.methods,
data: Popper.data,
beforeDestroy: Popper.beforeDestroy
Expand Down
1 change: 1 addition & 0 deletions packages/date-picker/src/picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const NewPopper = {
arrowOffset: Popper.props.arrowOffset,
transformOrigin: Popper.props.transformOrigin
},
computed: Popper.computed,
methods: Popper.methods,
data() {
return merge({ visibleArrow: true }, Popper.data);
Expand Down
8 changes: 6 additions & 2 deletions packages/dialog/src/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
this.$refs.dialog.scrollTop = 0;
});
if (this.appendToBody) {
document.body.appendChild(this.$el);
this.elementContent.appendChild(this.$el);
}
} else {
this.$el.removeEventListener('scroll', this.updatePopper);
Expand All @@ -151,6 +151,10 @@
}
}
return style;
},
elementContent() {
const content = this.$ELEMENT && this.$ELEMENT.content && document.getElementById(this.$ELEMENT.content);
return content || document.body;
}
},
Expand Down Expand Up @@ -197,7 +201,7 @@
this.rendered = true;
this.open();
if (this.appendToBody) {
document.body.appendChild(this.$el);
this.elementContent.appendChild(this.$el);
}
}
},
Expand Down
8 changes: 6 additions & 2 deletions packages/drawer/src/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ export default {
},
drawerSize() {
return typeof this.size === 'number' ? `${this.size}px` : this.size;
},
elementContent() {
const content = this.$ELEMENT && this.$ELEMENT.content && document.getElementById(this.$ELEMENT.content);
return content || document.body;
}
},
data() {
Expand All @@ -132,7 +136,7 @@ export default {
this.closed = false;
this.$emit('open');
if (this.appendToBody) {
document.body.appendChild(this.$el);
this.elementContent.appendChild(this.$el);
}
this.prevActiveElement = document.activeElement;
} else {
Expand Down Expand Up @@ -191,7 +195,7 @@ export default {
this.rendered = true;
this.open();
if (this.appendToBody) {
document.body.appendChild(this.$el);
this.elementContent.appendChild(this.$el);
}
}
},
Expand Down
6 changes: 5 additions & 1 deletion packages/image/src/image-viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ export default {
viewerZIndex() {
const nextZIndex = PopupManager.nextZIndex();
return this.zIndex > nextZIndex ? this.zIndex : nextZIndex;
},
elementContent() {
const content = this.$ELEMENT && this.$ELEMENT.content && document.getElementById(this.$ELEMENT.content);
return content || document.body;
}
},
watch: {
Expand Down Expand Up @@ -314,7 +318,7 @@ export default {
mounted() {
this.deviceSupportInstall();
if (this.appendToBody) {
document.body.appendChild(this.$el);
this.elementContent.appendChild(this.$el);
}
// add tabindex then wrapper can be focusable via Javascript
// focus wrapper so arrow key can't cause inner scroll behavior underneath
Expand Down
1 change: 1 addition & 0 deletions packages/menu/src/submenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
popperOptions: Popper.props.popperOptions
},
data: Popper.data,
computed: Popper.computed,
methods: Popper.methods,
beforeDestroy: Popper.beforeDestroy,
deactivated: Popper.deactivated
Expand Down
4 changes: 3 additions & 1 deletion packages/message-box/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ const showNextMsg = () => {
instance[prop] = true;
}
});
document.body.appendChild(instance.$el);
const content = Vue.prototype.$ELEMENT && Vue.prototype.$ELEMENT.content && document.getElementById(Vue.prototype.$ELEMENT.content);
const targetElement = content || document.body;
targetElement.appendChild(instance.$el);

Vue.nextTick(() => {
instance.visible = true;
Expand Down
4 changes: 3 additions & 1 deletion packages/message/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const Message = function(options) {
instance.message = null;
}
instance.$mount();
document.body.appendChild(instance.$el);
const content = Vue.prototype.$ELEMENT && Vue.prototype.$ELEMENT.content && document.getElementById(Vue.prototype.$ELEMENT.content);
const targetElement = content || document.body;
targetElement.appendChild(instance.$el);
let verticalOffset = options.offset || 20;
instances.forEach(item => {
verticalOffset += item.$el.offsetHeight + 16;
Expand Down
4 changes: 3 additions & 1 deletion packages/notification/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const Notification = function(options) {
const userOnClose = options.onClose;
const id = 'notification_' + seed++;
const position = options.position || 'top-right';
const content = Vue.prototype.$ELEMENT && Vue.prototype.$ELEMENT.content && document.getElementById(Vue.prototype.$ELEMENT.content);
const targetElement = content || document.body;

options.onClose = function() {
Notification.close(id, userOnClose);
Expand All @@ -30,7 +32,7 @@ const Notification = function(options) {
}
instance.id = id;
instance.$mount();
document.body.appendChild(instance.$el);
targetElement.appendChild(instance.$el);
instance.visible = true;
instance.dom = instance.$el;
instance.dom.style.zIndex = PopupManager.nextZIndex();
Expand Down
4 changes: 3 additions & 1 deletion src/utils/popup/popup-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ const PopupManager = {
if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) {
dom.parentNode.appendChild(modalDom);
} else {
document.body.appendChild(modalDom);
const content = Vue.prototype.$ELEMENT && Vue.prototype.$ELEMENT.content && document.getElementById(Vue.prototype.$ELEMENT.content);
const targetElement = content || document.body;
targetElement.appendChild(modalDom);
}

if (zIndex) {
Expand Down
13 changes: 10 additions & 3 deletions src/utils/vue-popper.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ export default {
}
},

computed: {
elementContent() {
const content = Vue.prototype.$ELEMENT && Vue.prototype.$ELEMENT.content && document.getElementById(Vue.prototype.$ELEMENT.content);
return content || document.body;
}
},

methods: {
createPopper() {
if (this.$isServer) return;
Expand All @@ -96,7 +103,7 @@ export default {

if (!popper || !reference) return;
if (this.visibleArrow) this.appendArrow(popper);
if (this.appendToBody) document.body.appendChild(this.popperElm);
if (this.appendToBody) this.elementContent.appendChild(this.popperElm);
if (this.popperJS && this.popperJS.destroy) {
this.popperJS.destroy();
}
Expand Down Expand Up @@ -185,9 +192,9 @@ export default {

beforeDestroy() {
this.doDestroy(true);
if (this.popperElm && this.popperElm.parentNode === document.body) {
if (this.popperElm && this.popperElm.parentNode === this.elementContent) {
this.popperElm.removeEventListener('click', stop);
document.body.removeChild(this.popperElm);
this.elementContent.removeChild(this.popperElm);
}
},

Expand Down

0 comments on commit d7ef11c

Please sign in to comment.