一起来做一下Vue全局提示组件

 更新时间:2022年06月07日 11:58:08   作者:阿远Carry  
前端开发的时候,在项目中引入组件以及使用是非常常见操作,下面这篇文章主要给大家介绍了关于Vue全局提示组件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

全局提示组件在前端中算是比较重要的,在开发业务时候肯定能用的上,毕竟任何报错只要提示“服务器异常”就可以完美把锅扔给后台(手动滑稽)

全局提示组件在人气比较🔥的 UI 组件库必有他身影,可能叫法不太相同,有叫 message、toast、alert 等,但就是这么一玩意。

拿 ant-design-vue 组件库为例

其核心代码

message.info('This is a normal message')

他是API的方式进行调用组件,以平常使用components注册组件,之后在template中使用的方式不太相同

想要实现这个,其实并不困难

但在之前我想声明一下:ant-design-vue 的 message 做个type分类,有info、success、error等。但为了读者方便理解,我们统一就用message来进行调用,读者可以根据本文提供的demo源码自行进行调整(贴一下 ant-design-vue 源码)

首先,我们在 components 目录下创建 message 目录,同时创建 Message.vue 和 index.js 文件

然后在 Message.vue 中写

<!-- Message.vue -->
<template>
  <div>{{ content }}</div>
</template>

<script>
export default {
  name: 'Message',
  props: {
    content: {
      type: String,
      default: ''
    }
  }
}
</script>

再者在 index.js 中写

// index.js
import { render, createVNode } from 'vue'
import Message from './Message.vue'

export default function message (content) {
  const div = document.createElement('div')
  const vm = createVNode(Message, {
    content
  })
  render(vm, div)
  document.body.appendChild(div)
}

最后在 app.vue 引入使用

<!-- app.vue -->
<template>
</template>
<script>
import message from './components/message'
export default{
  setup() {
    message('消息组件1')
    message('消息组件2')
  }
}
</script>

效果:

ok,这样就实现了以API的方式进行调用组件

其核心代码其实只有以下

const div = document.createElement('div')
const vm = createVNode(Message, {
  content
})
render(vm, div)
document.body.appendChild(div)

createVNode 可以认为就是h函数,支持直接转成虚拟dom对象

再去调用 render,渲染至div下,再将div插入body中

由于我们做的是全局组件,应该不被任何因素干扰,比如 vue-router

但是上面例子我们会发现,我们只要调用一个 message 方法,就要创建一个div插入至body,这显然不是符合vue数据驱动视图的理念

那,接下里进行改造

先从 Message.vue 文件开始

我们先定义一个消息列表messages,之后提供添加 add 和删除delete消息列两方法,再暴露add方法出去

当然,删除消息是需要根据id进行删除,可不能瞎删

<!-- Message.vue -->
<script>
import { ref, unref } from 'vue'
export default {
  name: 'Message',
  setup (props, { expose }) {
    // 消息列表
    const messages = ref([])
    
    let id = 0
    // 生成id
    const uuid = () => `message_${id++}`
    
    // 添加消息对象
    const add = (message) => {
      const id = uuid()
      const _message = {
        ...message,
        id
      }
      unref(messages).push(_message)
      const { duration = 3 } =  message
      // 设置定时器
      const timer = setTimeout(() => {
        clearTimeout(timer)
        remove(id)
      }, duration * 1000)
    }
    
    // 根据 id 删除消息对象
    const remove = (id) => {
      messages.value = unref(messages).filter(message => message.id !== id)
    }
    
    // 暴露出add 和 remove
    expose({
      add
    })
    
    return {
      messages
    }
  }
}
</script>

用v-for把消息列表渲染出来,同时使用transition-group做一些列表过渡动画

<!-- Message.vue -->
<template>
  <transition-group
    class="message"
    tag="div"
  >
    <div
      class="message-content"
      v-for="message in messages"
      :key="message.id"
    >
      {{ message.content }}
    </div>
  </transition-group>
</template>

再编写一点消息列表样式和其弹出动画样式

<!-- Message.vue -->
<style scoped>
.message {
  position: fixed;
  z-index: 999;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
}

.message-content {
  padding: 8px 16px;
  border-radius: 3px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
  background: #fff;
  margin-bottom: 20px;
}

.v-enter-active,
.-leave-active {
  transition: all 200ms ease-in;
}
.v-enter-from,
.v-leave-to {
  opacity: 0;
  transform: translateY(-30px);
}
</style>

再改造一下入口文件

之前我们发现在 app.vue 中调用一次 message方法,就会一次 dom 操作,那我们使用闭包写一个单例模式进行改造

再者我们在 Message.vue 暴露出add的方法可以直接进行操作消息列表

// index.js
import { render, createVNode } from 'vue'
import Message from './Message.vue'

let vm
// 使用单例模式,不再重新插入body
function getMessageInstance () {
  if (vm) return
  const div = document.createElement('div')
  vm = createVNode(Message)
  render(vm, div)
  document.body.appendChild(div)
}

export default function message (content = '', duration) {
  getMessageInstance()
  vm.component.exposed.add({
    content,
    duration
  })
}

最后在 app.vue 文件中随便编写一些测试代码

<!-- app.vue -->
<template>
  <button @click="onClick">测试</button>
</template>
<script>
import message from './components/message'
export default{
  setup() {
    message('消息组件1', 4)
    message('消息组件2', 2)
    let index = 3
    const onClick = () => {
      message(`消息组件${index++}`)
    }
    return {
      onClick
    }
  }
}
</script>

看看最终效果

好,这就是全局提示组件设计大致思路。

回顾一下会发现,其实Vue的组件开发依旧绕不开 JavaScript,可见 JavaScript 在前端的份量。

总结

到此这篇关于Vue全局提示组件的文章就介绍到这了,更多相关Vue全局提示组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue中transition动画使用(移动端页面切换左右滑动效果)

    vue中transition动画使用(移动端页面切换左右滑动效果)

    这篇文章主要介绍了vue中transition动画使用(移动端页面切换左右滑动效果),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Vue动态绑定Class的几种常用方式

    Vue动态绑定Class的几种常用方式

    在vue框架开发中,有时候我们需要对元素的样式进行动态控制,比如tab按钮的切换,下面这篇文章主要给大家介绍了关于Vue动态绑定Class的几种常用方式,需要的朋友可以参考下
    2023-03-03
  • 使用elementUI的表格table给列添加样式

    使用elementUI的表格table给列添加样式

    这篇文章主要介绍了使用elementUI的表格table给列添加样式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • Vue.js状态管理之Pinia与Vuex详解

    Vue.js状态管理之Pinia与Vuex详解

    Pinia和Vuex一样都是是vue的全局状态管理器,其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了名字Pinia,下面这篇文章主要给大家介绍了关于Vue.js状态管理之Pinia与Vuex的相关资料,需要的朋友可以参考下
    2023-02-02
  • 关于vue中使用three.js报错的解决方法

    关于vue中使用three.js报错的解决方法

    最近因为three.js的项目要用Vue.js,下面这篇文章主要给大家介绍了关于vue中使用three.js报错的解决方法,文中通过图文以及示例代码介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • vue中render函数的使用详解

    vue中render函数的使用详解

    这篇文章主要介绍了vue中render函数的使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • vue.js语法及常用指令

    vue.js语法及常用指令

    vue.js相比于Angular.js,Vue.js提供了更加简洁、更易于理解的API,使得我们能够快速地上手并使用Vue.js。下面通过本文给大家分享vue.js语法及常用指令,希望对大家有所帮助
    2017-10-10
  • vue单页面应用打开新窗口显示跳转页面的实例

    vue单页面应用打开新窗口显示跳转页面的实例

    今天小编就为大家分享一篇vue单页面应用打开新窗口显示跳转页面的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • keep-Alive搭配vue-router实现缓存页面效果的示例代码

    keep-Alive搭配vue-router实现缓存页面效果的示例代码

    这篇文章主要介绍了keep-Alive搭配vue-router实现缓存页面效果,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • uniApp h5项目如何通过命令行打包并生成指定路径及文件名称

    uniApp h5项目如何通过命令行打包并生成指定路径及文件名称

    用uni-app来写安卓端,近日需要将程序打包为H5放到web服务器上,经过一番折腾,这里给大家分享下,这篇文章主要给大家介绍了关于uniApp h5项目如何通过命令行打包并生成指定路径及文件名称的相关资料,需要的朋友可以参考下
    2024-02-02

最新评论