最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue3.0開發(fā)輕量級手機端彈框組件V3Popup的場景分析

 更新時間:2020年12月30日 14:56:13   作者:xiaoyan2017  
這篇文章主要介紹了基于Vue3.0開發(fā)輕量級手機端彈框組件V3Popup,本文通過場景分析給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

之前有分享一個vue2.x移動端彈框組件,今天給大家?guī)淼氖荲ue3實現(xiàn)自定義彈框組件。

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

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同樣支持標簽式+函數式兩種調用方式。

標簽寫法

<v3-popup 
  v-model="showDialog"
  title="標題"
  content="<p style='color:#df6a16;padding:10px;'>這里是內容信息!</p>"
  type="android"
  shadeClose="false"
  xclose
  :btns="[
    {text: '取消', click: () => showDialog=false},
    {text: '確認', style: 'color:#f90;', click: handleOK},
  ]"
  @success="handleOpen"
  @end="handleClose"
/>
  <template #content>這里是自定義插槽內容信息!</template>
</v3-popup>

函數寫法

let $el = this.$v3popup({
  title: '標題',
  content: '<p style='color:#df6a16;padding:10px;'>這里是內容信息!</p>',
  type: 'android',
  shadeClose: false,
  xclose: true,
  btns: [
    {text: '取消', click: () => { $el.close(); }},
    {text: '確認', style: 'color:#f90;', click: () => handleOK},
  ],
  onSuccess: () => {},
  onEnd: () => {}
})

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

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

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

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

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

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

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

  return {
    v3popup,
    showDialog
  }
}

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

◆ 效果預覽

◆ 參數配置

v3popup支持如下參數配置。

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

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" :style="{opacity}"></div>
    <div class="vui__wrap">
      <div class="vui__wrap-section">
        <div class="vui__wrap-child" :class="['anim-'+anim, type&&'popupui__'+type, round&&'round', position]" :style="[popupStyle]">
          <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" :style="btn.style" @click="btnClicked($event, index)" v-html="btn.text"></span>
          </div>
          <span v-if="xclose" class="vui__xclose" :class="xposition" :style="{'color': xcolor}" @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 },
      // 標識符,相同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++
          // 避免重復操作
          if($timer[$index] !== null) clearTimeout($timer[$index])
          $timer[$index] = setTimeout(() => {
            close()
          }, parseInt(props.time) * 1000)
        }

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

      // 關閉彈層
      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)函數式調用。

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中注冊原型鏈函數和v3-popup組件,就可以使用函數式調用了。

到此這篇關于基于Vue3.0開發(fā)輕量級手機端彈框組件V3Popup的場景分析的文章就介紹到這了,更多相關Vue3自定義彈框組件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 關于vue.extend和vue.component的區(qū)別淺析

    關于vue.extend和vue.component的區(qū)別淺析

    最近工作中遇到了vue.extend,vue.component,但二者之間的區(qū)別與聯(lián)系是什么呢?下面這篇文章主要給大家介紹了關于vue.extend和vue.component區(qū)別的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • Nuxt升級2.0.0時出現(xiàn)的問題(小結)

    Nuxt升級2.0.0時出現(xiàn)的問題(小結)

    這篇文章主要介紹了Nuxt升級2.0.0時出現(xiàn)的問題(小結),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • Vue elementUI 自定義表單模板組件功能實現(xiàn)

    Vue elementUI 自定義表單模板組件功能實現(xiàn)

    在項目開發(fā)中,我們會遇到這種需求,在管理后臺添加自定義表單,在指定的頁面使用定義好的表單,這篇文章主要介紹了Vue elementUI 自定義表單模板組件,需要的朋友可以參考下
    2022-12-12
  • vue3.0 項目搭建和使用流程

    vue3.0 項目搭建和使用流程

    這篇文章主要介紹了vue3.0 項目搭建和使用流程,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下
    2021-03-03
  • vue項目引入svg圖標的完整步驟

    vue項目引入svg圖標的完整步驟

    在實際的項目開發(fā)中,使用svg圖標占用內存比圖片更小,映入圖片內存比較大,同時也適用于不同屏幕的尺寸,下面這篇文章主要給大家介紹了關于vue項目引入svg圖標的完整步驟,需要的朋友可以參考下
    2022-10-10
  • Vue的生命周期一起來看看

    Vue的生命周期一起來看看

    這篇文章主要為大家詳細介紹了Vue的生命周期,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Vue環(huán)境搭建+VSCode+Win10的詳細教程

    Vue環(huán)境搭建+VSCode+Win10的詳細教程

    這篇文章主要介紹了Vue環(huán)境搭建+VSCode+Win10,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • 基于Vue實現(xiàn)可以拖拽的樹形表格實例詳解

    基于Vue實現(xiàn)可以拖拽的樹形表格實例詳解

    因業(yè)務需求,需要一個樹形表格,并且支持拖拽排序,任意未知插入,github搜了下,真不到合適的,大部分樹形表格都沒有拖拽功能,所以決定自己實現(xiàn)一個。這里分享一下實現(xiàn)過程,需要的朋友可以參考下
    2018-10-10
  • Vue項目開發(fā)實現(xiàn)父組件與子組件數據間的雙向綁定原理及適用場景

    Vue項目開發(fā)實現(xiàn)父組件與子組件數據間的雙向綁定原理及適用場景

    在 Vue.js 中,實現(xiàn)父組件與子組件數據之間的雙向綁定,可以通過以下幾種方式,下面我將介紹幾種常見的方法,并解釋它們的實現(xiàn)原理和適用場景,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • vuex實現(xiàn)購物車的增加減少移除

    vuex實現(xiàn)購物車的增加減少移除

    這篇文章主要為大家詳細介紹了vuex實現(xiàn)購物車的增加減少移除,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論

阳春市| 阿巴嘎旗| 花莲市| 巧家县| 四平市| 东乡族自治县| 林口县| 吴川市| 水富县| 皮山县| 河北区| 昌江| 中阳县| 常州市| 阿鲁科尔沁旗| 德州市| 平和县| 句容市| 七台河市| 宁波市| 新安县| 洛宁县| 宁安市| 开江县| 报价| 隆德县| 陆丰市| 仁布县| 民勤县| 仁寿县| 乐山市| 娱乐| 通渭县| 驻马店市| 白城市| 肥乡县| 永济市| 河池市| 山西省| 兴仁县| 遂昌县|