千家信息网

怎么利用vue3仿苹果系统侧边消息提示效果

发表于:2024-09-21 作者:千家信息网编辑
千家信息网最后更新 2024年09月21日,这篇文章主要介绍怎么利用vue3仿苹果系统侧边消息提示效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!动效预览最近在做毕业设计, 想给毕设系统加上一个仿苹果系统的侧边消息提示
千家信息网最后更新 2024年09月21日怎么利用vue3仿苹果系统侧边消息提示效果

这篇文章主要介绍怎么利用vue3仿苹果系统侧边消息提示效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

动效预览

最近在做毕业设计, 想给毕设系统加上一个仿苹果系统的侧边消息提示框, 让我们先来看看效果.

其他UI库

熟悉前端开发的同学可能发现了, 在 Element UI 中这个组件叫 Notification 通知; 在Bootstrap 中这个组件叫 Toasts.

开始

当初看到这个组件就觉得很酷炫, 今天就带大家看一下我是怎么一步一步实现的, 有不对或者可以优化的地方请各位大佬点评. ???? (本次组件基于 Vue3 实现)

组件目录结构

Toasts

|

| -- index.js // 注册组件, 定义全局变量以便调用

|

| -- instance.js // 手动实例创建前后的逻辑

|

| -- toasts.vue // 消息提示 HTMl 部分

|

| -- toastsBus.js // 解决 vue3 去除 $on和$emit 的解决方案

toasts.vue

大概的DOM结构

...
...
...

index.js

注册组件 & 定义全局变量

在这里我们注册组件, 定义全局变量以便调用

import toast from './instance'import Toast from './toasts.vue'export default (app) => {    // 注册组件    app.component(Toast.name, Toast);    // 注册全局变量, 后续只需调用 $Toast({}) 即可    app.config.globalProperties.$Toast = toast;}

instance.js

手动挂载实例

???????????? 这里是全文的重点 ????????????

首先我们学习如何将组件手动挂载至页面

import { createApp } from 'vue';import Toasts from './toasts'const toasts = (options) => {    // 创建父容器    let root = document.createElement('div');    document.body.appendChild(root)    // 创建Toasts实例    let ToastsConstructor = createApp(Toasts, options)    // 挂载父亲元素    let instance = ToastsConstructor.mount(root)    // 抛出实例本身给vue    return instance}export default toasts;

给每一个创建的 toasts 正确的定位

如图所示, 每创建一个 toasts 将会排列到上一个 toasts 的下方(这里的间隙为16px). 想要做到这种效果我们需要知道 已存在 的toasts 的高度.

// instance.js// 这里我们需要定义一个数组来存放当前存活的 toastslet instances = []const toasts = (options) => {    ...    // 创建后将实例加入数组    instances.push(instance)        // 重制高度    let verticalOffset = 0    // 遍历获取当前已存活的 toasts 高度及其间隙 累加    instances.forEach(item => {        verticalOffset += item.$el.offsetHeight + 16    })    // 累加本身需要的间隙    verticalOffset += 16    // 赋值当前实例y轴方向便宜长度    instance.toastPosition.y = verticalOffset    ...}export default toasts;

加入 主动&定时 关闭功能

让我们先来分析一下这里的业务:

  • 定时关闭: 在 toast 创建时给一个自动关闭时间, 当计时器结束后自动关闭.

  • 主动关闭: 点击关闭按钮关闭 toast.

在这个基础上我们可以加上一些人性化的操作, 例如鼠标移入某个 toast 时停止它的自动关闭(其他 toast 不受影响), 当鼠标移开时重新启用它的自动关闭.

我们来分析一下 instance.js 中 toast 关闭时的逻辑

  1. 将此 toast 从存活数组中删除, 并且遍历数组将从此条开始后面的 toast 位置向上位移.

  2. 从 中删除Dom元素.

  3. 调用 unmount() 销毁实例.

// instance.jsimport { createApp } from 'vue';import Toasts from './toasts'import Bus from './toastsBus'let instances = []let seed = 1const toasts = (options) => {    // 手动挂载实例    let ToastsConstructor = createApp(Toasts, options)    let instance = ToastsConstructor.mount(root)    // 给实例加入唯一标识符    instance.id = id    // 显示实例    instance.visible = true        ...        // 监听 toasts.vue 传来关闭事件    Bus.$on('closed', (id) => {        // 因为这里会监听到所有的 'closed' 事件, 所以要匹配 id 确保        if (instance.id == id) {            // 调用删除逻辑            removeInstance(instance)            // 在  上删除dom元素            document.body.removeChild(root)            // 销毁实例            ToastsConstructor.unmount();        }    })        instances.push(instance)    return instance}export default toasts;// 删除逻辑const removeInstance = (instance) => {    if (!instance) return    let len = instances.length    // 找出当前需要销毁的下标    const index = instances.findIndex(item => {        return item.id === instance.id    })    // 从数组中删除    instances.splice(index, 1)    // 如果当前数组中还存在存活 Toasts, 需要遍历将下面的Toasts上移, 重新计算位移    if (len <= 1) return    // 获取被删除实例的高度    const h = instance.height    // 遍历被删除实例以后下标的 Toasts    for (let i = index; i < len - 1; i++) {        // 公式: 存活的实例将本身的 y 轴偏移量减去被删除高度及其间隙高度        instances[i].toastPosition.y = parseInt(instances[i].toastPosition.y - h - 16)    }}

完整代码

index.js

import toast from './instance'import Toast from './toasts.vue'export default (app) => {    app.component(Toast.name, Toast);    app.config.globalProperties.$Toast = toast;}

toastsBus.js

import emitter from 'tiny-emitter/instance'export default {    $on: (...args) => emitter.on(...args),    $once: (...args) => emitter.once(...args),    $off: (...args) => emitter.off(...args),    $emit: (...args) => emitter.emit(...args)}

instance.js

import { createApp } from 'vue';import Toasts from './toasts'import Bus from './toastsBus'let instances = []let seed = 1const toasts = (options) => {    // 创建父容器    const id = `toasts_${seed++}`    let root = document.createElement('div');    root.setAttribute('data-id', id)    document.body.appendChild(root)    let ToastsConstructor = createApp(Toasts, options)    let instance = ToastsConstructor.mount(root)    instance.id = id    instance.visible = true        // 重制高度    let verticalOffset = 0    instances.forEach(item => {        verticalOffset += item.$el.offsetHeight + 16    })    verticalOffset += 16    instance.toastPosition.y = verticalOffset    Bus.$on('closed', (id) => {        if (instance.id == id) {            removeInstance(instance)            document.body.removeChild(root)            ToastsConstructor.unmount();        }    })    instances.push(instance)    return instance}export default toasts;const removeInstance = (instance) => {    if (!instance) return    let len = instances.length    const index = instances.findIndex(item => {        return item.id === instance.id    })    instances.splice(index, 1)    if (len <= 1) return    const h = instance.height    for (let i = index; i < len - 1; i++) {        instances[i].toastPosition.y = parseInt(instances[i].toastPosition.y - h - 16)    }}

toast.vue

加入亿点点细节, 例如icon可以自定义或者是图片, 可以取消关闭按钮, 设置自动关闭时长, 或者停用自动关闭功能.

main.js

import { createApp } from 'vue'import App from './App.vue'const app = createApp(App)import '@/assets/font/UIcons/font.css'// 安装toastsimport toasts from './components/toasts'app.use(toasts).mount('#app')

使用

以上是"怎么利用vue3仿苹果系统侧边消息提示效果"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

0