android6 全局对话框,vue3.0自定义组件|vue3仿android/ios弹框|Vue3.x全局对话框

介绍

前几天有给大家分享一个vue2弹框组件,今天主要分享的是Vue3.0实现轻量级移动端自定义弹出框组件V3Popup。

AAffA0nNPuCLAAAAAElFTkSuQmCC

V3Popup 一款基于vue3.0开发的移动端自定义弹出层组件。

内置20+种参数配置、7+弹窗类型、6+弹窗动画

支持 msg、dialog、modal、actionSheet、toast、android/ios 等弹窗类型。

并且在功能效果及UI上和之前的vue2保持一致。

AAffA0nNPuCLAAAAAElFTkSuQmCC

快速引入

在main.js中引入v3popup组件。

import { createApp } from 'vue'

import App from './App.vue'

// 引入弹窗组件v3popup

import V3Popup from './components/v3popup'

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

支持组件式和函数式两种灵活调用方式。

content="

确认框(这里是确认框提示信息,这里确认框提示信息,这里是确认框提示信息)
"

:btns="[

{text: '取消', click: () => showConfirm=false},

{text: '确定', style: 'color:#f90;', click: handleInfo},

]"

/>

函数式写法如下:

let $el = this.$v3popup({

title: '标题',

content: '

这里是内容信息!
',

type: 'android',

shadeClose: false,

xclose: true,

btns: [

{text: '取消', click: () => { $el.close(); }},

{text: '确认', style: 'color:#f90;', click: () => handleOK},

],

onSuccess: () => {},

onEnd: () => {}

})

在vue3.0中提供了两种可供全局调用的方法。app.config.globalProperties 和 app.provide

1、通过 app.config.globalProperties.$v3popup = V3Popup 这种方式挂载

// vue2.x中调用

methods: {

showDialog() {

this.$v3popup({...})

}

}

// vue3.x中调用

setup() {

// 获取上下文

const { ctx } = getCurrentInstance()

ctx.$v3popup({...})

}

2、通过 app.provide('v3popup', V3Popup)这种方式

// vue2.x中调用

methods: {

showDialog() {

this.v3popup({...})

}

}

// vue3.x中调用

setup() {

const v3popup = inject('v3popup')

const showDialog = () => {

v3popup({...})

}

return {

v3popup,

showDialog

}

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

编码实现

在vue3中既可以通过vue2的optionAPI写法来实现,也可以通过setup来写。既然是vue3,就通过vue3语法写了。

/**

* @Desc Vue3.0自定义弹层V3Popup

* @Time andy by 2020-12

* @About Q:282310962 wx:xy190310

*/

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(() => {

...

})

// 监听弹层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,

}

}

}

上面就是vue3实现弹窗的模板及核心逻辑处理部分。

AAffA0nNPuCLAAAAAElFTkSuQmCC

在vue3.0中可以通过 createApp 或 createVNode render 来实现函数式写法。将弹框实例挂载到body上面。

import { createApp } from 'vue'

import PopupConstructor from './popup.vue'

let $inst

// 创建挂载实例

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)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

okey,基于vue3.x开发自定义弹框组件就介绍这么多。感谢大家的阅读。

结语

如果你觉得这篇内容对你有启发或帮助,那么可以帮我三个小忙:

转发/点赞,让更多的人也能看到这篇分享。

加关注、不迷路,不定期分享原创技术知识。

也看看其它历史文章。

AAffA0nNPuCLAAAAAElFTkSuQmCC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UniApp是一个基于Vue.js的跨平台开发框架,可以同时开发iOSAndroid、H5等多个平台的应用。Vue3是Vue.js的最新版本,带来了许多新特性和改进。 自定义指令是Vue.js中一种强大的扩展机制,可以用于在DOM元素上添加自定义行为。在UniApp中,自定义指令的使用方式与Vue.js保持一致。 节流是一种常用的优化技术,用于限制函数的执行频率。在UniApp中,可以通过自定义指令来实现节流功能。 以下是使用UniApp和Vue3实现自定义指令节流的步骤: 1. 在UniApp项目中创建一个自定义指令文件,例如`throttle.js`。 2. 在`throttle.js`中定义一个全局定义指令,例如`v-throttle`。 3. 在指令的`bind`钩子函数中,初始化节流函数,并将其绑定到DOM元素上。 4. 在指令的`update`钩子函数中,更新节流函数的参数。 5. 在指令的`unbind`钩子函数中,解绑节流函数。 下面是一个示例代码,演示如何在UniApp中使用Vue3实现自定义指令节流: ```javascript // throttle.js import { throttle } from 'lodash' // 使用lodash库提供的节流函数 export default { mounted(el, binding) { const { value, arg } = binding const callback = value const delay = arg || 300 // 默认延迟时间为300ms const throttledCallback = throttle(callback, delay) el.addEventListener('click', throttledCallback) }, unmounted(el) { el.removeEventListener('click', throttledCallback) } } ``` 在使用自定义指令的组件中,可以通过`v-throttle`指令来实现节流功能: ```html <template> <button v-throttle="handleClick">点击按钮</button> </template> <script> export default { methods: { handleClick() { // 处理点击事件 } } } </script> ``` 这样,当按钮被点击时,`handleClick`方法将被节流执行,限制了函数的执行频率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值