Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

TIP 👉, better move the heart of the old; Poor and stronger, do not fall qingyun ambition. — Preface to The Pavilion of King Teng by Wang Bo

preface

Main purpose is to some of the common business scenarios encapsulation for components, avoid to repeat the code, focusing on more core part, so you need to put these duplicated code is extracted and packaged into public components, improve the efficiency of development, the component was the result, the API is not much, welcome to point out problems.

1. Pop-up window component (PC only available)

1. The Popup components

Popup attribute

1. value
  • Whether to display the dialog box
  • The value is a Boolean type
  • Default value: false
2. showClose
  • Whether to display the close button
  • The value is a Boolean type
  • The default value is true
3. title
  • Popover title
  • The value is string
  • Popup defaults to ‘prompt’ and Alert and Confirm default to null
4. showClose
  • Whether to display the close button in the upper right corner
  • The value is a Boolean type
  • Popup defaults to true, Alert and Confirm to false
5. message
  • Information content
  • The value is string

If there is a default slot, the configuration is invalid

6. html
  • HTML content
  • The value is string

This configuration is invalid if there is a default slot and invalid if message has a value

7. content
  • The content component of the box
  • Value is Vue component

This configuration is invalid if there is a default slot and invalid if message or HTML has a value

8. contentProps
  • Props for the popover content component
  • Value of type Object and property named props for the component

The configuration is valid only when content has a value

9. contentEvents
  • Popover content component events
  • Value is of type Object, property name is component event name, and property value is event callback method

The configuration is valid only when content has a value

10. contentWrapperStyle
  • Content wrapper style
  • The value is of type Object and the property name is style
<BasePopup v-model="isShow" message=" Save successfully!" :contentWrapperStyle="{ fontWeight: 'bold' }"></BasePopup>Copy the code
11. width
  • Popover width
  • The value is of a numeric type
  • Default: 500, in pixels
12. height
  • Popover width
  • The value is of a numeric type
  • Default value: 300, in pixels
13. className
  • Custom style name of the popbox
  • The value is string
14. scroll
  • Does the content area require a scroll bar? (If scroll is false, the scroll bar will automatically display if the content overflows.)
  • The value is a Boolean type
  • Default value: false
15. cover
  • Coverage of mask layer
  • The value is string
  • Default value: full
    • Full covers the entire screen
    • TAB overwrites the TAB page function area. The left menu bar, top area, and TAB TAB selection area are not overwritten

slot

1. default
  • The default slot is the content of the pop-up box
2. bottom
  • Slot at the bottom of the frame for storing operation buttons

Script invocation specific properties

1.store
  • Vuex store object, set when Vuex global data needs to be used in the popup

When using vm.$popup() or vm.$popupAlert() or vm.$popupConfirm(), the default is set to $Store for the current Vue instance

2.router
  • The Router object of Vue Router, set when a route is needed in the popup

When using vm.$popup() or vm.$popupAlert() or vm.$popupConfirm(), the default is set to $Router for the current Vue instance

Alert component specific properties

1.btnText
  • Button text
  • The value is string
  • Default: ‘OK’

Alert component-specific events

1.ok
  • The event triggered when a button is clicked
  • There is no parameter

Confirm Indicates the specific property of the component

1.okBtnText
  • Ok button text
  • The value is string
  • Default: ‘OK’
2.cancelBtnText
  • Cancel button text
  • The value is string
  • Default: ‘cancel’

Confirm component specific events

1.ok
  • The event that is triggered when the OK button is clicked
  • There is no parameter
2.cancel
  • The event triggered when the Cancel button is clicked
  • There is no parameter
Copy the code

Two, the pop-up window example

1. The Popup example

A simple example

<template>
  <div>
    <BaseButton @click="doOpen()">Simple popup window</BaseButton>

    <! -- Simple popbox -->
    <BasePopup v-model="isShow" title="Warning message" message="Modified successfully!"></BasePopup>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import BasePopup from '@/components/pc/popup/Popup.vue'

export default {
  name: 'PcPopupSimpleDemo'.components: {
    BaseButton,
    BasePopup
  },
  data () {
    return {
      isShow: false}},methods: {
    doOpen () {
      this.isShow = true}}}</script>
Copy the code

Custom content examples

<template> <div> <BaseButton @click="doOpen()"> </BaseButton> <! <BasePopup v-model="isShow" title=" tip ":width="300" :height="280"> <div class="info-content"> <p><Icon </p> </p> </p> </div> </template> <script> import BaseButton </p> </div> </template> <script> import BaseButton  from '@/components/base/button/index.vue' import BasePopup from '@/components/pc/popup/Popup.vue' export default { name: 'PcPopupDemo', components: { BaseButton, BasePopup }, data () { return { isShow: false } }, methods: { doOpen () { this.isShow = true } } } </script> <style lang="scss" scoped px2rem="false"> .info-content{ padding: 50px 24px; font-size: 16px; text-align: center; .info-icon{ font-size: 84px; @include primary-font-color(); margin-bottom: 10px; } } </style>Copy the code

Example with scroll bar

<template>
  <div>
    <BaseButton @click="doOpen()">With the scroll bar</BaseButton>

    <! -- Custom content popbox with scroll bar -->
    <BasePopup v-model="isShow" title=List of banks :width="260" :height="320" :scroll="true">
      <div class="info-content">
        <ul>
          <li>China Construction Bank</li>
          <li>Industrial and Commercial Bank of China</li>
          <li>Agricultural Bank of China</li>
          <li>Bank of Communications of China</li>
          <li>The bank of China,</li>
          <li>China Merchants Bank</li>
          <li>Postal Savings Bank</li>
        </ul>
      </div>
    </BasePopup>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import BasePopup from '@/components/pc/popup/Popup.vue'

export default {
  name: 'PcPopupScrollDemo'.components: {
    BaseButton,
    BasePopup
  },
  data () {
    return {
      isShow: false}},methods: {
    doOpen () {
      this.isShow = true}}}</script>
<style lang="scss" scoped px2rem="false">
.info-content{
  padding: 24px;
  font-size: 16px;
  line-height: 50px;
  ul {
    list-style: none; }}</style>
Copy the code

Dynamically specify components as content examples

<template>
  <div>
    <BaseButton @click="doOpen()">Dynamically specify components as content</BaseButton>

    <! -- Dynamically specify components as content pop-ups -->
    <BasePopup v-model="isShow" title="User Information" :width="300" :height="200" :scroll="true"
               :content="contentComponent" :contentProps="contentProps"
               :contentEvents="contentEvents" :contentWrapperStyle="contentWrapperStyle"></BasePopup>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import BasePopup from '@/components/pc/popup/Popup.vue'
import Content from './Content.vue'

export default {
  name: 'PcPopupDynamicDemo'.components: {
    BaseButton,
    BasePopup
  },
  data () {
    return {
      isShow: false.contentComponent: Content,
      contentProps: {
        name: 'Tom'.phone: 18399998888
      },
      contentEvents: {
        click () {
          console.log('Click on user info')}},contentWrapperStyle: {
        padding: '30px 20px 30px 50px'.textAlign: 'left'}}},methods: {
    doOpen () {
      this.isShow = true}}}</script>
Copy the code

2. Alert example

A simple button example

<template>
  <div>
    <BaseButton @click="doOpen()">With a button</BaseButton>

    <! -- Warning box with one button -->
    <BaseAlert v-model="isShow" message="Saved successfully!" btnText="Continue" @ok="doOK"></BaseAlert>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import BaseAlert from '@/components/pc/popup/Alert.vue'

export default {
  name: 'PcAlertDemo'.components: {
    BaseButton,
    BaseAlert
  },
  data () {
    return {
      isShow: false}},methods: {
    doOpen () {
      this.isShow = true
    },
    doOK () {
      console.log('Trigger OK event')}}}</script>
Copy the code

With a button (captioned, closed) example

<template>
  <div>
    <BaseButton @click="doOpen()">With one button (captioned and closed)</BaseButton>

    <! -- Warning box with a button (titled, can be closed) -->
    <BaseAlert v-model="isShow" message="Saved successfully!" title="Tip" :showClose="true" btnText="Sure" @ok="doOK"></BaseAlert>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import BaseAlert from '@/components/pc/popup/Alert.vue'

export default {
  name: 'PcAlertHeaderDemo'.components: {
    BaseButton,
    BaseAlert
  },
  data () {
    return {
      isShow: false}},methods: {
    doOpen () {
      this.isShow = true
    },
    doOK () {
      console.log('Trigger OK event')}}}</script>
Copy the code

3. Confirm the sample

Examples with confirm and cancel buttons

<template> <div> <BaseButton @click="doOpen()"> </BaseButton> <! <BaseConfirm V-model ="isShow" message=" Confirm delete order?" @ok="doOK" @cancel="doCancel"></BaseConfirm> </div> </template> <script> import BaseButton from '@/components/base/button/index.vue' import BaseConfirm from '@/components/pc/popup/Confirm.vue' export default { name: 'PcConfirmDemo', components: { BaseButton, BaseConfirm }, data () { return { isShow: false } }, methods: {doOpen () {this.isshow = true}, doOK () {console.log(' trigger OK event ')}, DoCancel () {console.log(' triggers cancel event ')}}} </script>Copy the code

Examples with confirm, cancel buttons (captioned, close)

<template> <div> <BaseButton @click="doOpen()"> </BaseButton> <! <BaseConfirm V-model ="isShow" message=" Sure to delete order?" Title =" prompt ":showClose="true" @ok="doOK" @cancel="doCancel"></BaseConfirm> </div> </template> <script> import BaseButton from '@/components/base/button/index.vue' import BaseConfirm from '@/components/pc/popup/Confirm.vue' export default { name: 'PcConfirmHeaderDemo', components: { BaseButton, BaseConfirm }, data () { return { isShow: false } }, methods: {doOpen () {this.isshow = true}, doOK () {console.log(' trigger OK event ')}, DoCancel () {console.log(' triggers cancel event ')}}} </script>Copy the code

3. Examples of script invocation

1. The Popup example

Simple popover example

<template>
  <div>
    <BaseButton @click="doOpen()">Simple popup window</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popup } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsPopupSimpleDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popup('Saved successfully! ')}}}</script>
Copy the code

Example of setting pop-up parameters

<template>
  <div>
    <BaseButton @click="doOpen()">Set popover parameters</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popup } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsPopupDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popup({
        title: 'Prompt message'.message: 'Saved successfully! '.width: 250.height: 200})}}}</script>
Copy the code

HTML as an example of content

<template>
  <div>
    <BaseButton @click="doOpen()">HTML as content</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popup } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsHtmlPopupDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popup({ html: `
         

< span style = "max-width: 100%; clear: both;

Line 1: ID number cannot be empty!

Line 3: Mobile phone number cannot be empty!

`
})}}}
</script>
Copy the code

2. Alert example

A simple button example

<template>
  <div>
    <BaseButton @click="doOpen()">With a button</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popupAlert } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsAlertDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popupAlert({
        message: 'Sure you want to delete it? '.btnText: 'confirm',
        onOK () {
          console.log('Trigger OK event')}})}}}</script>
Copy the code

With a button (captioned, closed) example

<template>
  <div>
    <BaseButton @click="doOpen()">With one button (captioned and closed)</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popupAlert } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsAlertHeaderDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popupAlert({
        title: 'tip'.showClose: true.message: 'Sure you want to delete it? '.btnText: 'confirm',
        onOK () {
          console.log('Trigger OK event')}})}}}</script>
Copy the code

3. Confirm the sample

Examples with confirm and cancel buttons

<template>
  <div>
    <BaseButton @click="doOpen()">With confirm and cancel buttons</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popupConfirm } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsConfirmDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popupConfirm({
        message: 'Continue? '.okBtnText: '继续'.cancelBtnText: '不了'.onOK: () = > {
          console.log('Trigger OK event')},onCancel: () = > {
          console.log('Trigger cancel event')}})}}}</script>
Copy the code

Examples with confirm, cancel buttons (captioned, close)

<template>
  <div>
    <BaseButton @click="doOpen()">With confirm and cancel buttons (with title and can be closed)</BaseButton>
  </div>
</template>
<script>
import BaseButton from '@/components/base/button/index.vue'
import { popupConfirm } from '@/components/pc/popup/index.js'

export default {
  name: 'PcJsConfirmHeaderDemo'.components: {
    BaseButton
  },
  methods: {
    doOpen () {
      popupConfirm({
        title: 'tip'.showClose: true.message: 'Continue? '.okBtnText: '继续'.cancelBtnText: '不了'.onOK: () = > {
          console.log('Trigger OK event')},onCancel: () = > {
          console.log('Trigger cancel event')}})}}}</script>
Copy the code

, etc.

implementation

Implement a popup.vue

<! -- Popup widget --><template>
  <div class="popup" :class="{'full-screen': fullScreen, 'fold-menu': foldMenu, 'show-tabs': isShowTabs, 'cover-full': cover==='full', 'cover-tab': cover==='tab'}">
    <transition name="mask">
      <div ref="popupMask" class="popup-mask" v-show="visible"></div>
    </transition>
    <transition name="pop">
      <div class="popup-box" v-show="visible" :class="className" :style="popupStyle" ref="popBox">
        <div class="close" v-show="showClose" @click="doClose"><Icon name="close" class="close-icon"></Icon></div>
        <div class="popup-pane" :class="noHeader? 'no-header' : ''">
          <div class="title" v-show="title">{{title}}</div>
          <div ref="contentWrap" class="content-wrap" :style="{overflow: needScroll ? 'auto' : 'hidden', ... contentWrapperStyle}">
            <slot>
              <div v-if="message" :class="needScroll ? 'scroll-message' : 'center-message'">{{message}}</div>
              <div v-else-if="html" class="html-message" v-html="html"></div>
              <component v-else-if="content" :is="content" v-bind="contentProps" v-on="contentEvents"></component>
            </slot>
          </div>
          <div class="bottom">
            <slot name="bottom"></slot>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>
<script>
/* eslint-disable no-undef */
const isShowTabs = APP_SHOW_TABS // Whether to display the function switch TAB

export default {
  name: 'Popup'.props: {
    // Whether to display the dialog box
    value: {
      type: Boolean.default: false
    },
    / / title
    title: String.// Whether to display the close button
    showClose: {
      type: Boolean.default: true
    },
    // Information content
    message: String.// HTML string content
    html: String.// Popover content component
    content: Object.// Props for the popup content component
    contentProps: Object.// Popover content component events
    contentEvents: Object.// Content wrapper style
    contentWrapperStyle: Object.// Frame width
    width: {
      type: Number.default: 300
    },
    // The height of the frame
    height: {
      type: Number.default: 220
    },
    / / the style name
    className: {
      type: String.default: ' '
    },
    // Whether the content area needs scroll bars
    scroll: {
      type: Boolean.default: false
    },
    // Mask layer coverage (full: covers the entire page, TAB: covers the current TAB function area)
    cover: {
      type: String.default: 'full'
    }
  },
  data () {
    return {
      // Whether to display
      visible: this.value,
      // Whether the content overflows
      contentOverflow: false.// Popover width
      boxWidth: this.width,
      // Popover height
      boxHeight: this.height,
      // Whether to display the function switch TAB
      isShowTabs: isShowTabs,
      // scrollEventId: 'popup' + new Date().getTime()
      // Timer ID
      timeoutId: null}},computed: {
    // Whether the header is not displayed (title and close button)
    noHeader () {
      return !this.title && !this.showClose
    },
    // Calculate the width and height of the frame
    popupStyle () {
      let styleObj = {}
      let boxWidth = this.boxWidth
      let boxHeight = this.boxHeight
      styleObj.width = boxWidth + 'px'
      styleObj.height = boxHeight + 'px'
      styleObj.marginLeft = ` -${boxWidth / 2}px`
      styleObj.marginTop = ` -${boxHeight / 2}px`
      if (boxWidth < 150) {
        styleObj.display = 'none'
      }
      return styleObj
    },
    // Whether the scroll bar should be displayed
    needScroll () {
      return this.scroll || this.contentOverflow
    },
    fullScreen () {
      if (this.$store && this.$store.getters && this.$store.getters.fullScreen) {
        return true
      }
      return false
    },
    foldMenu () {
      if (this.$store && this.$store.getters && this.$store.getters.foldMenu) {
        return true
      }
      return false}},watch: {
    value (val) {
      this.visible = val
    },
    visible (val) {
      if (val && !this.scroll) {
        setTimeout(() = > {
          const contentWrap = this.$refs.contentWrap
          const content = this.$refs.contentWrap.firstChild
          const contentWrapHeight = contentWrap.getBoundingClientRect().height
          const contentHeight = content.getBoundingClientRect().height
          console.log('Popover content wrap element height =', contentWrapHeight, ', popover content element height =', contentHeight)
          if (contentHeight > contentWrapHeight) {
            this.contentOverflow = true}},100)}/* if (val && this.scroll) { this.$nextTick(() => { this.$eventBus.$emit('init-scroll-' + this.scrollEventId) }) } */
    },
    cover (val) {
      if (val === 'tab') {
        // The event controls the horizontal scroll bar when the popover in the function area of the mask TAB pops up
        setTimeout(() = > {
          this.$eventBus.$emit('TAB_POPUP')},0)
      }
    },
    width (val) {
      this.initSize()
    },
    height (val) {
      this.initSize()
    },
    fullScreen (val) {
      if (this.cover === 'tab') {
        setTimeout(() = > {
          this.initSize()
        }, 300)
      }
    },
    foldMenu (val) {
      if (this.cover === 'tab') {
        setTimeout(() = > {
          this.initSize()
        }, 300)
      }
    }
  },
  mounted () {
    // Initialize the popover size, set the popover size to no larger than the browser window size
    setTimeout(() = > {
      this.initSize()
    }, 50)

    window.addEventListener('resize'.this.initSize)
    // Close the pop-up window to redirect to the login page when the user login fails
    this.$eventBus.$on('NO_AUTH_EVENT'.this.doClose)
  },
  beforeDestroy () {
    if (this.timeoutId) {
      clearTimeout(this.timeoutId)
    }
    window.removeEventListener('resize'.this.initSize)
    this.$eventBus.$off('NO_AUTH_EVENT'.this.doClose)
    // Close the popup window, if it is only the popup window of the TAB function area, trigger the event control horizontal scroll bar
    if (this.cover === 'tab') {
      this.$eventBus.$emit('TAB_POPUP')}},methods: {
    // Initialize the popover size, set the popover size to no larger than the browser window size
    initSize () {
      let maxWidth = window.innerWidth
      let maxHeight = window.innerHeight

      let coverElement = document.getElementById('tabsViewContent')
      if(! coverElement) { coverElement =document.getElementById('viewContent')}if (this.cover === 'tab' && coverElement) {
        if (coverElement.clientWidth < maxWidth) {
          maxWidth = coverElement.clientWidth
        }
        if (coverElement.clientHeight < maxHeight) {
          maxHeight = coverElement.clientHeight
        }

        let offsetLeft = coverElement.getBoundingClientRect().left
        let winWidth = window.innerWidth
        let mainViewWidth = winWidth - offsetLeft
        if (mainViewWidth < maxWidth) {
          maxWidth = mainViewWidth
        }
      }

      if (maxWidth && (maxWidth - 10) < this.width) {
        this.boxWidth = maxWidth - 10
      } else {
        this.boxWidth = this.width
      }
      if (maxHeight && (maxHeight - 10) < this.height) {
        this.boxHeight = maxHeight - 10
      } else {
        this.boxHeight = this.height
      }
    },
    doClose () {
      this.visible = false
      this.$emit('input'.this.visible)
      this.$emit('close')
    },
    close (timeout) {
      if (typeof timeout === 'number' && timeout > 0) {
        this.timeoutId = setTimeout(() = > {
          this.doClose()
        }, timeout)
      } else {
        this.doClose()
      }
    }
  }
}
</script>
<style lang="scss" scoped px2rem="false">$box-border-radius: 3px; $title-height: 54px; $close-size: 12px; $content-tb-padding: 18px; $content-lr-padding: 24px; .popup{ z-index: 1000; .popup-mask{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; Background - color: rgba (0, 0, 5); transition: all .3s ease; z-index: 1000; } .popup-box{ position: fixed; width: 500px; height: 300px; top: 50%; left: 50%; margin-left: -250px; margin-top: -150px; background-color: #FFF; border-radius: $box-border-radius; transition: all .2s ease; z-index: 1000; .close{ height: $title-height; width: $title-height; position: absolute; top: 0; right: 0; text-align: center; padding-top: ($title-height - $close-size) / 2; z-index: 1003; .close-icon{ line-height: 1; font-size: $close-size; color: #666; } } .popup-pane{ height: 100%; padding: 20px 0; .title{ margin-top: -20px; height: $title-height; line-height: $title-height; border-bottom: solid 1px #E5E5E5; font-size: 16px; text-align: left; padding: 0 ($content-lr-padding * 2 + $close-size) 0 $content-lr-padding; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #666; font-weight: bold; } .content-wrap{ position: absolute; top: $title-height; bottom: 0; left: 0; right: 0; .center-message{ position: absolute; width: 100%; top: 50%; transform: translateY(-50%); padding: $content-tb-padding $content-lr-padding; box-sizing: border-box; font-size: 16px; The line - height: 1.5; text-align: center; word-break: break-all; white-space: pre-wrap; } .scroll-message { padding: $content-tb-padding $content-lr-padding; font-size: 16px; The line - height: 1.5; } .html-message { font-size: 16px; The line - height: 1.5; ::v-deep .message{ padding: $content-tb-padding $content-lr-padding; text-align: center; } } } &.no-header .content-wrap { top: 0; } .scroll{ overflow-y: auto; } .bottom{ position: absolute; bottom: 0; left: 0; right: 0; text-align: center; } } } &.cover-tab { .popup-mask { left: $app-menu-width; top: $app-header-height; transition: all .2s ease; transition-delay: .1s; } .popup-box { transform: translate($app-menu-width / 2, ($app-header-height) / 2); } &.fold-menu { .popup-mask { left: $app-menu-fold-width; } .popup-box { transform: translate($app-menu-fold-width / 2, $app-header-height / 2); } } &.show-tabs { .popup-mask { top: $app-header-height + $app-tabs-height; } .popup-box { transform: translate($app-menu-width / 2, ($app-header-height + $app-tabs-height) / 2); } &.fold-menu { .popup-box { transform: translate($app-menu-fold-width / 2, ($app-header-height + $app-tabs-height) / 2); } } &.full-screen { .popup-mask { left: 0; top: $app-tabs-height; transition-delay: .1s; } .popup-box { transform: translate(0, $app-tabs-height / 2); } } } } } .pop-enter-active, .pop-leave{ transform: scale(1); opacity: 1; } .pop-enter, .pop-leave-active{ transform: scale(.5); opacity: 0; } .mask-leave-active{ opacity: 0; }</style>
Copy the code

alert.vue

<template>
  <BasePopup v-model="visible" ref="basePop" class="alert-popup" :message="message" :title="title"
             :showClose="showClose" :width="width" :height="height" :scroll="scroll" :cover="cover"
             :contentWrapperStyle="contentWrapperStyle"
             :content="content" :contentProps="contentProps" :contentEvents="contentEvents"
             @close="doClose">
    <div slot="bottom" class="buttons">
      <BaseButton @click="doOK" type="primary" :text="btnText"></BaseButton>
    </div>
  </BasePopup>
</template>
<script>
import BasePopup from './Popup.vue'
import BaseButton from '.. /.. /base/button/index.vue'
export default {
  name: 'BaseAlert'.components: {
    BasePopup,
    BaseButton
  },
  props: {
    // Whether to display the dialog box
    value: {
      type: Boolean.default: false
    },
    / / title
    title: String.// Whether to display the close button
    showClose: {
      type: Boolean.default: false
    },
    // Message content
    message: String.// Popover content component
    content: Object.// Props for the popup content component
    contentProps: Object.// Popover content component events
    contentEvents: Object.// Content wrapper style
    contentWrapperStyle: Object.// Frame width
    width: {
      type: Number.default: 300
    },
    // The height of the frame
    height: {
      type: Number.default: 220
    },
    // Whether the content area needs scroll bars
    scroll: {
      type: Boolean.default: false
    },
    // Mask layer coverage (full: covers the entire page, TAB: covers the current TAB function area)
    cover: {
      type: String.default: 'full'
    },
    // Button text
    btnText: {
      type: String.default: 'sure'
    }
  },
  data () {
    return {
      // Whether to display
      visible: this.value
    }
  },
  watch: {
    value (val) {
      this.visible = val
    }
  },
  methods: {
    doClose () {
      this.visible = false
      this.$emit('input'.this.visible)
      this.$emit('close')
    },
    doOK () {
      this.visible = false
      this.$emit('input'.this.visible)
      this.$emit('ok')}}}</script>
<style lang="scss" scoped px2rem="false">$content-padding: 24px; $bottom-height: 54px; $bottom-height: 54px; .alert-popup { .buttons{ padding: (($bottom-height - 32px) / 2) $content-padding; } ::v-deep .popup-box { .popup-pane { .content-wrap { bottom: $bottom-height; } .bottom { border-top: solid 1px $border-color-light; }}}}</style>

Copy the code

confirm.vue

<template>
  <BasePopup v-model="visible" ref="basePop" class="confirm-popup" :message="message" :title="title"
             :showClose="showClose" :width="width" :height="height" :scroll="scroll" :cover="cover"
             :contentWrapperStyle="contentWrapperStyle"
             :content="content" :contentProps="contentProps" :contentEvents="contentEvents"
             @close="doClose">
    <div slot="bottom" class="buttons">
      <BaseButton :class="'cancel-btn'" @click="doCancel" :text="cancelBtnText"></BaseButton>
      <BaseButton :class="'ok-btn'" @click="doOK" type="primary" :text="okBtnText"></BaseButton>
    </div>
  </BasePopup>
</template>
<script>
import BasePopup from './Popup.vue'
import BaseButton from '.. /.. /base/button/index.vue'
export default {
  name: 'BaseConfirm'.components: {
    BasePopup,
    BaseButton
  },
  props: {
    // Whether to display the dialog box
    value: {
      type: Boolean.default: false
    },
    / / title
    title: String.// Whether to display the close button
    showClose: {
      type: Boolean.default: false
    },
    // Message content
    message: String.// Popover content component
    content: Object.// Props for the popup content component
    contentProps: Object.// Popover content component events
    contentEvents: Object.// Content wrapper style
    contentWrapperStyle: Object.// Frame width
    width: {
      type: Number.default: 300
    },
    // The height of the frame
    height: {
      type: Number.default: 220
    },
    // Whether the content area needs scroll bars
    scroll: {
      type: Boolean.default: false
    },
    // Mask layer coverage (full: covers the entire page, TAB: covers the current TAB function area)
    cover: {
      type: String.default: 'full'
    },
    // Determine the button text
    okBtnText: {
      type: String.default: 'sure'
    },
    // Cancel button text
    cancelBtnText: {
      type: String.default: 'cancel'
    }
  },
  data () {
    return {
      // Whether to display
      visible: this.value
    }
  },
  watch: {
    value (val) {
      this.visible = val
    }
  },
  methods: {
    doClose () {
      this.visible = false
      this.$emit('input'.this.visible)
      this.$emit('close')
    },
    doOK () {
      this.visible = false
      this.$emit('input'.this.visible)
      this.$emit('ok')
    },
    doCancel () {
      this.visible = false
      this.$emit('input'.this.visible)
      this.$emit('cancel')}}}</script>
<style lang="scss" scoped px2rem="false">$content-padding: 24px; $bottom-height: 54px; $bottom-height: 54px; .confirm-popup { .buttons{ padding: (($bottom-height - 32px) / 2) $content-padding; .cancel-btn { background-color: #FFF; border-color: $border-color-light; } ::v-deep .btn:not(:last-of-type) { margin-right: 10px; } } ::v-deep .popup-box { .popup-pane { .content-wrap { bottom: $bottom-height; } .bottom { border-top: solid 1px $border-color-light; }}}}</style>
Copy the code

popup/index.js

/** * Popup component *@author qinglianshizhe* /
import Vue from 'vue'
import Popup from './Popup.vue'
import Alert from './Alert.vue'
import Confirm from './Confirm.vue'

// Popup constructor
const PopupConstructor = Vue.extend({
  extends: Popup
})

// Alert constructor
const AlertConstructor = Vue.extend({
  extends: Alert
})

// Confirm constructor
const ConfirmConstructor = Vue.extend({
  extends: Confirm
})

// Get the parent node of the TAB popup
function getTabPopupParentElement () {
  let tabContentElement = window.document.getElementById('tabsViewContent')
  if (tabContentElement) {
    let tabArray = tabContentElement.childNodes
    if (tabArray.length > 0) {
      return tabArray[0]}}return document.body
}

function initInstance (instance, options) {
  // Display the content
  instance.message = typeof options === 'string' ? options : options.message
  / / HTML content
  instance.html = typeof options === 'object' ? options.html : null
  // Popover content component
  instance.content = typeof options === 'object' && options._isVue ? options : options.content
  // Popover content component parameters
  instance.contentProps = typeof options.contentProps === 'object' ? options.contentProps : {}
  // Popover content component events
  instance.contentEvents = typeof options.contentEvents === 'object' ? options.contentEvents : {}
  // Content wrapper style
  instance.contentWrapperStyle = options.contentWrapperStyle
  // Window width
  instance.width = typeof options.width === 'number' ? options.width : 300
  // Window height
  instance.height = typeof options.height === 'number' ? options.height : 220
  // Customize the style name
  instance.className = options.className || ' '
  // Whether to display a scroll bar
  instance.scroll = options.scroll
  // Mask layer coverage (full: covers the entire page, TAB: covers the current TAB page function area, available when only TAB pages are displayed)
  instance.cover = options.cover || 'full'
  / / the parent node
  let parentElement = options.parentElement || (options.cover === 'tab' ? getTabPopupParentElement() : document.body)

  // Remove when closed
  instance.$on('input'.visible= > {
    if(! visible) {setTimeout(() = > {
        parentElement.removeChild(instance.$el)
        instance.$destroy()
      }, 2000)
      /* / get the popBox element, if the Popop component is obtained from refs, if the Alert or Confirm component, get the Popop element first, Get in from Popop component refs let popBox = instance. $refs. PopBox | | (instance. $refs. BasePop && instance. $refs. BasePop. $refs. PopBox) popBox.addEventListener('transitionend', Event = > {/ / animation removed after the completion of the DOM node / / parentElement. RemoveChild (instance. $el) if (event. Target. ParentNode && . The event target. ParentNode. ParentNode) {. The event target. ParentNode. ParentNode. RemoveChild (event. Target. ParentNode)} / / destruction of components instance.$destroy() }) */}})// console.log('instance.$el=', instance.$el)
  // Add nodes to the document
  parentElement.appendChild(instance.$el)

  instance.visible = true
  instance.closed = false
}

// Displays a pop-up window
export function popup (options = {}) {
  let instance = new PopupConstructor({
    el: document.createElement('div'),
    store: options.store || (this && this.$store),
    router: options.router || (this && this.$router)
  })
  initInstance(instance, options)
  // Popover title
  instance.title = options.title || 'tip'
  // Whether to display the close button
  instance.showClose = typeof options.showClose === 'boolean' ? options.showClose : true
  return instance
}

// Display prompt box (with ok button at the bottom)
export function popupAlert (options = {}) {
  let instance = new AlertConstructor({
    el: document.createElement('div'),
    store: options.store || (this && this.$store),
    router: options.router || (this && this.$router)
  })
  initInstance(instance, options)
  // Popover title
  instance.title = options.title || ' '
  // Whether to display the close button
  instance.showClose = typeof options.showClose === 'boolean' ? options.showClose : false
  // Button text
  instance.btnText = options.btnText || 'sure'
  Options. onOK is called when the OK button is clicked
  instance.$on('ok'.() = > {
    options.onOK && options.onOK()
  })
  instance.$on('input'.visible= > {})
  return instance
}

export function popupConfirm (options = {}) {
  let instance = new ConfirmConstructor({
    el: document.createElement('div'),
    store: options.store || (this && this.$store),
    router: options.router || (this && this.$router)
  })
  initInstance(instance, options)
  // Popover title
  instance.title = options.title || ' '
  // Whether to display the close button
  instance.showClose = typeof options.showClose === 'boolean' ? options.showClose : false
  // Determine the button text
  instance.okBtnText = options.okBtnText || 'sure'
  // Cancel button text
  instance.cancelBtnText = options.cancelBtnText || 'cancel'
  Options. onOK is called when the OK button is clicked
  instance.$on('ok'.visible= > {
    options.onOK && options.onOK()
  })
  Options. onOK is called when the OK button is clicked
  instance.$on('cancel'.visible= > {
    options.onCancel && options.onCancel()
  })
  return instance
}

export default popup

Copy the code

Thanks for the comment section.

Hope to finish watching friends can give a thumbs-up, encourage once