우선 개발 시 다음 세 가지 사항을 고려해야 합니다.
1. 팝업 애니메이션 효과 입력 및 팝업.
2. Z-index 제어
3. 오버레이 마스킹 레이어
애니메이션에 대하여
vue's 애니메이션 처리는 상대적으로 간단합니다. CSS 전환 애니메이션을 구성 요소에 추가하기만 하면 됩니다
<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>
외부는 v-if 또는 v-show를 사용하여 디스플레이를 제어하여 사용자가 제어할 수 있습니다
Z-index 제어
Z-index 제어와 관련하여 다음 사항을 완료해야 합니다
1. 팝업의 Z-index가 올바른지 확인합니다. 상자가 다시 팝업될 만큼 높음 가장 바깥쪽 레이어
2. 나중에 나타나는 팝업 상자의 z-index가 이전에 나타난 팝업 상자보다 높습니다.
위의 두 가지 사항을 충족하려면
const zIndex = 20141223 // 先预设较高值 const getZIndex = function () { return zIndex++ // 每次获取之后 zindex 自动增加 }
를 구현하는 다음 코드가 필요합니다. 그런 다음 z-index를 구성 요소
<template> <div class="modal" :style="{'z-index': zIndex}" transition="modal-scale"> <!--省略其它内容--> </div> </template> <script> export default { data () { return { zIndex: getZIndex() } } } </script>
에 바인딩합니다.
마스킹 레이어 오버레이 제어
팝업창 컴포넌트에서 가장 다루기 어려운 부분이 커버링 레이어입니다. 완벽한 커버링 레이어 제어를 위해서는 다음 사항이 충족되어야 합니다. :
1. 커버링 레이어와 팝업 레이어 사이의 애니메이션이 평행해야 합니다.
2. 커버링 레이어의 z-index가 더 작아야 합니다. 팝업 레이어보다
3. 커버링 레이어가 팝업되면 컴포넌트 페이지를 스크롤해야 합니다
4. 커버링 레이어를 클릭하려면 다음이 필요합니다. 팝업 레이어 피드백
5. 전체 페이지에 최대 하나의 커버 레이어가 있을 수 있는지 확인하세요. (여러 개 겹쳐 쌓으면 커버 레이어의 색상이 깊어집니다.)
이러한 문제를 처리하고 모든 팝업 상자 구성 요소를 개별적으로 해결할 필요가 없도록 하기 위해 우리는 vue의 믹스인 메커니즘을 사용하여 이러한 팝업 레이어의 공개 로직을 믹스인 레이어로 캡슐화하기로 결정했습니다. , 각 팝업 상자 구성 요소를 직접 참조할 수 있습니다.
vue-popup-mixin
위의 문제를 모두 명확히 한 후 믹스인 개발을 시작했습니다. 먼저 오버레이(커버 레이어 구성 요소)가 필요합니다.
<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>
그런 다음 오버레이 표시 및 숨기기를 관리하려면 js가 필요합니다.
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
가 드디어 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) } }
으로 패키징되었습니다. >위의 코드는 모두 모든 팝업 레이어의 공통 로직을 완성하므로 사용 시 필요한 사항은 다음과 같습니다. 믹스인으로 로드
<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>
위는 vue에 대한 것입니다. .js 팝업 구성 요소에 대한 몇 가지 지식 포인트입니다. 모든 사람에게 도움이 되기를 바랍니다. 공부나 업무에 궁금한 점이 있으면 메시지를 남겨서 소통하세요. PHP 중국어 웹사이트에 대한 지원에 감사드립니다.
vue.js 팝업 구성요소에 대한 더 많은 지식 포인트 요약 및 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!