Zunächst müssen bei der Entwicklung die folgenden drei Punkte berücksichtigt werden:
1. Eingabe- und Popup-Animationseffekte.
2. Z-Index-Steuerung
3. Overlay-Maskierungsebene
Über Animation
Vue's Die Verarbeitung von Animationen ist relativ einfach. Fügen Sie der Komponente einfach eine CSS-Übergangsanimation hinzu.
<template> <div class="modal" transition="modal-scale"> <!--省略其它内容--> </div> </template> <script> // ... </script> <style> .modal-scale-transition{ transition: transform,opacity .3s ease; } .modal-scale-enter, .modal-scale-leave { opacity: 0; } .modal-scale-enter { transform: scale(1.1); } .modal-scale-leave { transform: scale(0.8); } </style>
Die externe Steuerung kann vom Benutzer mithilfe von v-if oder v-show gesteuert werden Anzeige
Z-Index-Steuerung
Bezüglich der Z-Index-Steuerung müssen Sie die folgenden Punkte ausführen
1. Stellen Sie sicher, dass der Z-Index des Pop -up-Box ist hoch genug, um ihre äußerste Ebene zu aktivieren
2. Der Z-Index der später angezeigten Popup-Box ist höher als der zuvor angezeigte
Um die beiden oben genannten Punkte zu erfüllen, benötigen wir Folgendes: Der Code implementiert
const zIndex = 20141223 // 先预设较高值 const getZIndex = function () { return zIndex++ // 每次获取之后 zindex 自动增加 }
und bindet dann z-index an die Komponente
<template> <div class="modal" :style="{'z-index': zIndex}" transition="modal-scale"> <!--省略其它内容--> </div> </template> <script> export default { data () { return { zIndex: getZIndex() } } } </script>
Overlay-Steuerung des Overlays
Die Deckschicht ist der am schwierigsten zu handhabende Teil in der Popup-Fensterkomponente. Eine perfekte Deckschichtsteuerung muss die folgenden Punkte erfüllen :
1. Zwischen der Deckschicht und der Popup-Ebene Die Animation muss parallel sein
2. Der Z-Index der Deckschicht sollte kleiner sein als die der Popup-Ebene
3. Wenn die Abdeckebene angezeigt wird, muss die Komponentenseite gescrollt werden
4. Beim Klicken auf die Abdeckebene ist eine Rückmeldung erforderlich auf der Popup-Ebene
5. Stellen Sie sicher, dass auf der gesamten Seite höchstens eine Deckschicht vorhanden sein kann (mehrere Stapel zusammen intensivieren die Farbe der Deckschicht)
Um diese Probleme zu lösen und sicherzustellen, dass nicht alle Popup-Box-Komponenten einzeln gelöst werden müssen, haben wir uns entschieden, den Mixins-Mechanismus von Vue zu verwenden, um die gemeinsame Logik dieser Popup-Ebenen in einer Mixin-Ebene zu kapseln. und jedes Popup-Feld Verweisen Sie einfach direkt auf die Rahmenkomponente.
vue-popup-mixin
Nachdem wir alle oben genannten Probleme geklärt hatten, begannen wir mit der Entwicklung des Mixins. Zuerst benötigen wir ein Overlay (Abdeckschichtkomponente);
<template> <div class="overlay" @click="handlerClick" @touchmove="prevent" :style="style" transition="overlay-fade"></div> </template> <script> export default { props: { onClick: { type: Function }, opacity: { type: Number, default: 0.4 }, color: { type: String, default: '#000' } }, computed: { style () { return { 'opacity': this.opacity, 'background-color': this.color } } }, methods: { prevent (event) { event.preventDefault() event.stopPropagation() }, handlerClick () { if (this.onClick) { this.onClick() } } } } </script> <style lang="less"> .overlay { position: fixed; left: 0; right: 0; top: 0; bottom: 0; background-color: #000; opacity: .4; z-index: 1000; } .overlay-fade-transition { transition: all .3s linear; &.overlay-fade-enter, &.overlay-fade-leave { opacity: 0 !important; } } </style>
Dann wird ein js benötigt, um das Anzeigen und Ausblenden von Overlays zu verwalten.
import Vue from 'vue' import overlayOpt from '../overlay' // 引入 overlay 组件 const Overlay = Vue.extend(overlayOpt) const getDOM = function (dom) { if (dom.nodeType === 3) { dom = dom.nextElementSibling || dom.nextSibling getDOM(dom) } return dom } // z-index 控制 const zIndex = 20141223 const getZIndex = function () { return zIndex++ } // 管理 const PopupManager = { instances: [], // 用来储存所有的弹出层实例 overlay: false, // 弹窗框打开时 调用此方法 open (instance) { if (!instance || this.instances.indexOf(instance) !== -1) return // 当没有遮盖层时,显示遮盖层 if (this.instances.length === 0) { this.showOverlay(instance.overlayColor, instance.overlayOpacity) } this.instances.push(instance) // 储存打开的弹出框组件 this.changeOverlayStyle() // 控制不同弹出层 透明度和颜色 // 给弹出层加上z-index const dom = getDOM(instance.$el) dom.style.zIndex = getZIndex() }, // 弹出框关闭方法 close (instance) { let index = this.instances.indexOf(instance) if (index === -1) return Vue.nextTick(() => { this.instances.splice(index, 1) // 当页面上没有弹出层了就关闭遮盖层 if (this.instances.length === 0) { this.closeOverlay() } this.changeOverlayStyle() }) }, showOverlay (color, opacity) { let overlay = this.overlay = new Overlay({ el: document.createElement('div') }) const dom = getDOM(overlay.$el) dom.style.zIndex = getZIndex() overlay.color = color overlay.opacity = opacity overlay.onClick = this.handlerOverlayClick.bind(this) overlay.$appendTo(document.body) // 禁止页面滚动 this.bodyOverflow = document.body.style.overflow document.body.style.overflow = 'hidden' }, closeOverlay () { if (!this.overlay) return document.body.style.overflow = this.bodyOverflow let overlay = this.overlay this.overlay = null overlay.$remove(() => { overlay.$destroy() }) }, changeOverlayStyle () { if (!this.overlay || this.instances.length === 0) return const instance = this.instances[this.instances.length - 1] this.overlay.color = instance.overlayColor this.overlay.opacity = instance.overlayOpacity }, // 遮盖层点击处理,会自动调用 弹出层的 overlayClick 方法 handlerOverlayClick () { if (this.instances.length === 0) return const instance = this.instances[this.instances.length - 1] if (instance.overlayClick) { instance.overlayClick() } } } window.addEventListener('keydown', function (event) { if (event.keyCode === 27) { // ESC if (PopupManager.instances.length > 0) { const topInstance = PopupManager.instances[PopupManager.instances.length - 1] if (!topInstance) return if (topInstance.escPress) { topInstance.escPress() } } } }) export default PopupManager
Verkapseln Sie es schließlich in einem Mixin
import PopupManager from './popup-manager' export default { props: { show: { type: Boolean, default: false }, // 是否显示遮盖层 overlay: { type: Boolean, default: true }, overlayOpacity: { type: Number, default: 0.4 }, overlayColor: { type: String, default: '#000' } }, // 组件被挂载时会判断show的值开控制打开 attached () { if (this.show && this.overlay) { PopupManager.open(this) } }, // 组件被移除时关闭 detached () { PopupManager.close(this) }, watch: { show (val) { // 修改 show 值是调用对于的打开关闭方法 if (val && this.overlay) { PopupManager.open(this) } else { PopupManager.close(this) } } }, beforeDestroy () { PopupManager.close(this) } }
Verwenden Sie
Alle oben genannten Codes vervollständigen die gemeinsame Logik aller Popup-Ebenen. Wenn Sie sie verwenden, müssen Sie sie nur als Mixin laden
<template> <div class="dialog" v-show="show" transition="dialog-fade"> <div class="dialog-content"> <slot></slot> </div> </div> </template> <style> .dialog { left: 50%; top: 50%; transform: translate(-50%, -50%); position: fixed; width: 90%; } .dialog-content { background: #fff; border-radius: 8px; padding: 20px; text-align: center; } .dialog-fade-transition { transition: opacity .3s linear; } .dialog-fade-enter, .dialog-fade-leave { opacity: 0; } </style> <script> import Popup from '../src' export default { mixins: [Popup], methods: { // 响应 overlay事件 overlayClick () { this.show = false }, // 响应 esc 按键事件 escPress () { this.show = false } } } </script>
Zusammenfassung
Die oben genannten Punkte sind einige Wissenspunkte zur vue.js-Popup-Komponente. Ich hoffe, dass sie für das Studium oder die Arbeit aller hilfreich sein werden. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen Ihre Unterstützung für die chinesische PHP-Website.
Weitere Zusammenfassungen der Wissenspunkte zur Popup-Komponente von vue.js und verwandte Artikel finden Sie auf der chinesischen PHP-Website!