Home  >  Article  >  Web Front-end  >  Summary of knowledge points about vue.js pop-up component

Summary of knowledge points about vue.js pop-up component

高洛峰
高洛峰Original
2017-01-16 12:44:131315browse

First of all, the following three points need to be considered during development:

1. Entering and pop-up animation effects.

2. Z-index control

3. Overlay masking layer

About animation

vue's processing of animation is relatively simple, just add css transition animation to the component

<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>

The external can be controlled by the user, using v-if or v-show to control the display

Z-index control

Regarding the control of z-index, the following points need to be completed
1. Ensure that the z-index of the pop-up box is high enough to make it The outermost layer

2. The z-index of the pop-up box that pops up later is higher than the one that pops up before

To satisfy the above two points, we need the following code to implement

const zIndex = 20141223 // 先预设较高值
 
const getZIndex = function () {
 return zIndex++ // 每次获取之后 zindex 自动增加
}

Then bind the z-index to the component

<template>
<div class="modal" :style="{&#39;z-index&#39;: zIndex}" transition="modal-scale">
 <!--省略其它内容-->
</div>
</template>
<script>
export default {
 data () {
  return {
   zIndex: getZIndex()
  }
 }
}
</script>

Overlay control of the covering layer

The covering layer is the most difficult part to handle in the pop-up window component. A perfect covering layer control needs to complete the following points:

1. The animation between the covering layer and the pop-up layer needs to be parallel

2. The z-index of the covering layer should be smaller than the pop-up layer

3. When the covering layer pops up, the component page needs to be scrolled

4. Clicking on the covering layer requires feedback on the pop-up layer

5. Ensure that there can be at most one covering layer on the entire page (multiple stacking together will deepen the color of the covering layer)

In order to deal with these problems and ensure that all pop-up box components do not need to be solved individually, we decided to use vue's mixins mechanism to encapsulate the public logic of these pop-up layers into a mixin layer, and each pop-up box component can be directly referenced. .

vue-popup-mixin

After clarifying all the above problems and starting to develop mixin, we first need an overlay (covering layer component);

<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: &#39;#000&#39;
 }
 },
 computed: {
 style () {
  return {
  &#39;opacity&#39;: this.opacity,
  &#39;background-color&#39;: 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>

Then you need a js to manage the display and hiding of overlay.

import Vue from &#39;vue&#39;
import overlayOpt from &#39;../overlay&#39; // 引入 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(&#39;div&#39;)
 })
 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 = &#39;hidden&#39;
 },
 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(&#39;keydown&#39;, 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

Finally encapsulate it into a mixin

import PopupManager from &#39;./popup-manager&#39;
 
export default {
 props: {
 show: {
  type: Boolean,
  default: false
 },
 // 是否显示遮盖层
 overlay: {
  type: Boolean,
  default: true
 },
 overlayOpacity: {
  type: Number,
  default: 0.4
 },
 overlayColor: {
  type: String,
  default: &#39;#000&#39;
 }
 },
 // 组件被挂载时会判断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)
 }
}


##Use


All the above codes complete the common logic of all pop-up layers. When using it, you only need to load it as a mixin

<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 &#39;../src&#39;
 
export default {
 mixins: [Popup],
 methods: {
 // 响应 overlay事件
 overlayClick () {
  this.show = false
 },
 // 响应 esc 按键事件
 escPress () {
  this.show = false
 }
 }
}
</script>

Summary

The above is about vue Some knowledge points about the .js pop-up component, I hope it will be helpful to everyone’s study or work. If you have any questions, you can leave a message for communication. Thank you for your support to the PHP Chinese website.

For more knowledge points summary about vue.js pop-up component, please pay attention to the PHP Chinese website for related articles!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn