溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

V3Popup彈框組件怎么在Vue3.0中使用

發(fā)布時間:2020-12-31 15:39:53 來源:億速云 閱讀:490 作者:Leah 欄目:開發(fā)技術(shù)

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)V3Popup彈框組件怎么在Vue3.0中使用,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

V3Popup 基于vue3.x實現(xiàn)的移動端彈出框組件,集合msg、alert、dialog、modal、actionSheet、toast等多種效果。支持20+種自定義參數(shù)配置,旨在通過極簡的布局、精簡的調(diào)用方式解決多樣化的彈框場景。

v3popup 在開發(fā)之初參考借鑒了Vant3、ElementPlus等組件化思想。并且功能效果和之前vue2.0保持一致。

◆ 快速引入

在main.js中全局引入v3popup組件。

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// 引入彈窗組件v3popup
import V3Popup from './components/v3popup'

app.use(V3Popup)
app.mount('#app')

v3popup同樣支持標(biāo)簽式+函數(shù)式兩種調(diào)用方式。

標(biāo)簽寫法
<v3-popup 
  v-model="showDialog"
  title="標(biāo)題"
  content="<p style='color:#df6a16;padding:10px;'>這里是內(nèi)容信息!</p>"
  type="android"
  shadeClose="false"
  xclose
  :btns="[
    {text: '取消', click: () => showDialog=false},
    {text: '確認', style: 'color:#f90;', click: handleOK},
  ]"
  @success="handleOpen"
  @end="handleClose"
/>
  <template #content>這里是自定義插槽內(nèi)容信息!</template>
</v3-popup>
函數(shù)寫法
let $el = this.$v3popup({
  title: '標(biāo)題',
  content: '<p style='color:#df6a16;padding:10px;'>這里是內(nèi)容信息!</p>',
  type: 'android',
  shadeClose: false,
  xclose: true,
  btns: [
    {text: '取消', click: () => { $el.close(); }},
    {text: '確認', style: 'color:#f90;', click: () => handleOK},
  ],
  onSuccess: () => {},
  onEnd: () => {}
})

Vue3.0中掛載全局函數(shù)有2種方式app.config.globalPropertiesapp.provide

通過 app.config.globalProperties.$v3popup = V3Popup 方式掛載。

// vue2.x中調(diào)用
methods: {
  showDialog() {
    this.$v3popup({...})
  }
}

// vue3.x中調(diào)用
setup() {
  // 獲取上下文
  const { ctx } = getCurrentInstance()
  ctx.$v3popup({...})
}

通過 app.provide('v3popup', V3Popup) 方式掛載。

// vue2.x中調(diào)用
methods: {
  showDialog() {
    this.v3popup({...})
  }
}

// vue3.x中調(diào)用
setup() {
  const v3popup = inject('v3popup')
  
  const showDialog = () => {
    v3popup({...})
  }

  return {
    v3popup,
    showDialog
  }
}

不過vue.js作者是推薦使用 provide inject 方式來掛載原型鏈函數(shù)。

◆ 效果預(yù)覽

V3Popup彈框組件怎么在Vue3.0中使用

V3Popup彈框組件怎么在Vue3.0中使用

V3Popup彈框組件怎么在Vue3.0中使用

V3Popup彈框組件怎么在Vue3.0中使用

V3Popup彈框組件怎么在Vue3.0中使用

V3Popup彈框組件怎么在Vue3.0中使用

◆ 參數(shù)配置

v3popup支持如下參數(shù)配置。

|props參數(shù)|
v-model     是否顯示彈框
title      標(biāo)題
content     內(nèi)容(支持String、帶標(biāo)簽內(nèi)容、自定義插槽內(nèi)容)***如果content內(nèi)容比較復(fù)雜,推薦使用標(biāo)簽式寫法
type      彈窗類型(toast | footer | actionsheet | actionsheetPicker | android | ios)
popupStyle   自定義彈窗樣式
icon      toast圖標(biāo)(loading | success | fail)
shade      是否顯示遮罩層
shadeClose   是否點擊遮罩時關(guān)閉彈窗
opacity     遮罩層透明度
round      是否顯示圓角
xclose     是否顯示關(guān)閉圖標(biāo)
xposition    關(guān)閉圖標(biāo)位置(left | right | top | bottom)
xcolor     關(guān)閉圖標(biāo)顏色
anim      彈窗動畫(scaleIn | fadeIn | footer | fadeInUp | fadeInDown)
position    彈出位置(top | right | bottom | left)
follow     長按/右鍵彈窗(坐標(biāo)點)
time      彈窗自動關(guān)閉秒數(shù)(1、2、3)
zIndex     彈窗層疊(默認8080)
teleport    指定掛載節(jié)點(默認是掛載組件標(biāo)簽位置,可通過teleport自定義掛載位置) teleport="body | #xxx | .xxx"
btns      彈窗按鈕(參數(shù):text|style|disabled|click)
++++++++++++++++++++++++++++++++++++++++++++++
|emit事件觸發(fā)|
success     層彈出后回調(diào)(@success="xxx")
end       層銷毀后回調(diào)(@end="xxx")
++++++++++++++++++++++++++++++++++++++++++++++
|event事件|
onSuccess    層打開回調(diào)事件
onEnd      層關(guān)閉回調(diào)事件

v3popup.vue模板

<template>
  <div ref="elRef" v-show="opened" class="vui__popup" :class="{'vui__popup-closed': closeCls}" :id="id">
    <!-- //蒙層 -->
    <div v-if="JSON.parse(shade)" class="vui__overlay" @click="shadeClicked" :></div>
    <div class="vui__wrap">
      <div class="vui__wrap-section">
        <div class="vui__wrap-child" :class="['anim-'+anim, type&&'popupui__'+type, round&&'round', position]" :>
          <div v-if="title" class="vui__wrap-tit" v-html="title"></div>
          <div v-if="type=='toast'&&icon" class="vui__toast-icon" :class="['vui__toast-'+icon]" v-html="toastIcon[icon]"></div>
          <!-- 判斷插槽是否存在 -->
          <template v-if="$slots.content">
            <div class="vui__wrap-cnt"><slot name="content" /></div>
          </template>
          <template v-else>
            <div v-if="content" class="vui__wrap-cnt" v-html="content"></div>
          </template>
          <slot />
          <div v-if="btns" class="vui__wrap-btns">
            <span v-for="(btn, index) in btns" :key="index" class="btn" : @click="btnClicked($event, index)" v-html="btn.text"></span>
          </div>
          <span v-if="xclose" class="vui__xclose" :class="xposition" : @click="close"></span>
        </div>
      </div>
    </div>
  </div>
</template>
/**
 * @Desc   Vue3.0自定義彈框組件V3Popup
 * @Time   andy by 2020-12
 * @About  Q:282310962 wx:xy190310
 */
<script>
  import { onMounted, ref, reactive, watch, toRefs, nextTick } from 'vue'
  let $index = 0, $locknum = 0, $timer = {}
  export default {
    props: {
      // 接收父組件v-model值,如果v-model:open,則這里需寫open: {...}
      modelValue: { type: Boolean, default: false },
      // 標(biāo)識符,相同ID共享一個實例
      id: {
        type: String, default: ''
      },
      title: String,
      content: String,
      type: String,
      popupStyle: String,
      icon: String,
      shade: { type: [Boolean, String], default: true },
      shadeClose: { type: [Boolean, String], default: true },
      opacity: { type: [Number, String], default: '' },
      round: Boolean,
      xclose: Boolean,
      xposition: { type: String, default: 'right' },
      xcolor: { type: String, default: '#333' },
      anim: { type: String, default: 'scaleIn' },
      position: String,
      follow: { type: Array, default: null },
      time: { type: [Number, String], default: 0 },
      zIndex: { type: [Number, String], default: '8080' },
      teleport: [String, Object],
      btns: {
        type: Array, default: null
      },
      onSuccess: { type: Function, default: null },
      onEnd: { type: Function, default: null },
    },
    emits: [
      'update:modelValue'
    ],
    setup(props, context) {
      const elRef = ref(null)

      const data = reactive({
        opened: false,
        closeCls: '',
        toastIcon: {
          ...
        }
      })

      onMounted(() => {
        ...
      })

      // 監(jiān)聽彈層v-model
      watch(() => props.modelValue, (val) => {
        if(val) {
          open()
        }else {
          close()
        }
      })

      // 打開彈層
      const open = () => {
        if(data.opened) return
        data.opened = true
        typeof props.onSuccess === 'function' && props.onSuccess()

        const dom = elRef.value
        dom.style.zIndex = getZIndex() + 1

        ...

        // 倒計時
        if(props.time) {
          $index++
          // 避免重復(fù)操作
          if($timer[$index] !== null) clearTimeout($timer[$index])
          $timer[$index] = setTimeout(() => {
            close()
          }, parseInt(props.time) * 1000)
        }

        // 長按|右鍵菜單
        if(props.follow) {
          ...
        }
      }

      // 關(guān)閉彈層
      const close = () => {
        if(!data.opened) return

        data.closeCls = true
        setTimeout(() => {
          ...

          context.emit('update:modelValue', false)
          typeof props.onEnd === 'function' && props.onEnd()
        }, 200)
      }

      // 點擊遮罩層
      const shadeClicked = () => {
        if(JSON.parse(props.shadeClose)) {
          close()
        }
      }
      // 按鈕事件
      const btnClicked = (e, index) => {
        let btn = props.btns[index];
        if(!btn.disabled) {
          typeof btn.click === 'function' && btn.click(e)
        }
      }
      
      ...

      return {
        ...toRefs(data),
        elRef,
        close,
        shadeClicked,
        btnClicked,
      }
    }
  }
</script>

Vue3中可通過createApp或createVNode | render 來掛載實例到body來實現(xiàn)函數(shù)式調(diào)用。

import { createApp } from 'vue'
import PopupConstructor from './popup.vue'

let $inst
// 創(chuàng)建掛載實例
let createMount = (opts) => {
  const mountNode = document.createElement('div')
  document.body.appendChild(mountNode)

  const app = createApp(PopupConstructor, {
    ...opts, modelValue: true,
    remove() {
      app.unmount(mountNode)
      document.body.removeChild(mountNode)
    }
  })
  return app.mount(mountNode)
}

function V3Popup(options = {}) {
  options.id = options.id || 'v3popup_' + generateId()
  $inst = createMount(options)
  
  return $inst
}

V3Popup.install = app => {
  app.component('v3-popup', PopupConstructor)
  // app.config.globalProperties.$v3popup = V3Popup
  app.provide('v3popup', V3Popup)
}

這樣就實現(xiàn)了在vue3中注冊原型鏈函數(shù)和v3-popup組件,就可以使用函數(shù)式調(diào)用了。

上述就是小編為大家分享的V3Popup彈框組件怎么在Vue3.0中使用了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)
推薦閱讀:
  1. js選擇彈框
  2. layer彈框

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI