一起来做一下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全局提示组件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue全局loading及错误提示的思路与实现

    前言 近期项目马上上线,前两天产品提个需求,加个全局loading,我这半路出家的vue选手,有点懵逼,这玩意还是第一次,但是作为一个初级的前端切图仔,这个东西是必须会的,花了五分钟思考了一下,然后动键盘码出来 ,今天总结一下,与各位分享交流,有错误还请各位指出. 思路 我们项目请求使用的是axios,那么我们就在请求前后进行拦截,添加我们需要的东西,然后通信控制loading,通信方式我就不写了,有个老哥写的不错,可以去看看传送门 代码实现 首先对axios进行封装 如果你想进行全局错误提醒

  • vue的全局提示框组件实例代码

    这篇文章给大家介绍一个vue全局提示框组件,具体代码如下所示: <template> <!-- 全局提示框 --> <div v-show="visible" class="dialog-tips dialog-center"> <div>{{message}}</div> </div> </template> <script> export default { data

  • 最简单的vue消息提示全局组件的方法

    简介 实现功能 自定义文本 自定义类型(默认,消息,成功,警告,危险) 自定义过渡时间 使用vue-cli3.0生成项目 toast全局组件编写 /src/toast/toast.vue <template> <div class="app-toast" v-if="isShow" :class="{'info': type=== 'info','success': type=== 'success','wraning': type===

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

    全局提示组件在前端中算是比较重要的,在开发业务时候肯定能用的上,毕竟任何报错只要提示“服务器异常”就可以完美把锅扔给后台(手动滑稽) 全局提示组件在人气比较的 UI 组件库必有他身影,可能叫法不太相同,有叫 message.toast.alert 等,但就是这么一玩意. 拿 ant-design-vue 组件库为例 其核心代码 message.info('This is a normal message') 他是API的方式进行调用组件,以平常使用components注册组件,之后在templa

  • Vue 全局loading组件实例详解

    上图不上种,菊花万人捅: loading.js: import './loading.css' let Loading = {} // 避免重复install,设立flag Loading.installed = false Loading.install = function (Vue) { if (Loading.installed) return Vue.prototype.$loading = {} Vue.prototype.$loading.show = () => { // 如果页

  • Vue全局分页组件的实现代码

    需求 一个监控控制台界面,有成千上万条表格数据,需要做一个全局分页组件,支持调整每页显示数目.总页数.当前页数.前进后退.自由跳转页数. 字段 参数名 数据类型 说明 total Number 总条数 pageNo Number 总页数 limit Number 每页展示条数 原型 预期长酱紫(不要嫌丑!毕竟是后台控制台!) 代码 html <template> <div class="paging-content clearfix"> <div clas

  • 用Vue.extend构建消息提示组件的方法实例

    前提 前段时间自己做的vue练手项目,需要一个通用的消息提示组件,但是消息提示这种组件我更想用方法来调用,而不是在各个页面上都添加个组件(那样感觉很麻烦,重度懒癌患者),于是就上网差查了查,并研究了ElementUI的message源码.自己弄出来一个简陋的消息提示组件 Vue.extend是什么 按照官方文档说法,他是一个类构造器,用来创建一个子类vue并返回构造函数,而Vue.component它的任务是将给定的构造函数与字符串ID相关联,以便Vue.js可以在模板中接收它. 了解了这点之后

  • vue全局组件和局部组件的写法介绍

    目录 全局组件和局部组件写法 全局组件引入写法 局部组件引入写法 vue全局/局部组件 全局组件和局部组件写法 vue组件有两种,一种是全局组件,一种是局部组件.整个项目经常用到的用全局写法,用到比较少的专供特定页面用的使用局部组件. 全局组件引入写法 在项目的main.js中: import Vue from 'vue'; import MyComponent from '@/components/MyComponent.vue'; // 导入自己写的组件文件   Vue.use(MyComp

  • vue中使用svg封装全局消息提示组件

    本文实例为大家分享了vue中使用svg封装全局消息提示组件的具体代码,供大家参考,具体内容如下 先看效果图 一.首先安装下载需要用到的svg相关依赖 npm install svg-sprite-loader --save-dev 二.针对没有vue.config.js文件的vue项目,直接在webpack.base.conf.js中进行如下两个配置 1.找到图片相关配置位置,添加款选出的代码 2.在图片配置后添加如下代码 三.根据添加的代码我们去src下创建一个icons文件夹,icons下面

  • vue实现过渡动画Message消息提示组件示例详解

    目录 概述 目录结构 总结 概述 在我自己平时做项目的时候,必不可少的会用到message组件,用来对用户友好反馈,总之使用频率还是挺高的,刚开始工作的时候,经常用的就是组件库的现成的,想想也不能总是用别人现成的,最近模拟组件库调用方式自己写了一个消息提示组件,支持过渡效果,支持自己进行扩展. 目录结构 .src/component/MessageBox/MessageBox.vue代码: <template> //css实现过渡 <transition name="fade-

  • 自定义vue全局组件use使用、vuex的使用详解

    自定义vue全局组件use使用(解释vue.use()的原理) 我们在前面学习到是用别人的组件:Vue.use(VueRouter).Vue.use(Mint)等等. 其实使用的这些都是全局组件,这里我们就来讲解一下怎么样定义一个全局组件,并解释vue.use()的原理 而我们再用Axios做交互,则不能使用Vue.use(Axios),因为Axios没有install自定义一个全局Loading组件,并使用: 总结目录: |-components |-loading |-index.js 导出

  • Vue.js实现一个漂亮、灵活、可复用的提示组件示例

    这次的教程里,我们要把组件化进行到底!最近半年的几个项目中,都遇到了需要使用Toast或者Notification组件的情况.在目前已有的一些基于Vue.js开发的组件库,都没有找到太合适的,所以自己重头实现了一个.历经几个项目的磨练,这个提示组件的功能已经越来越完善,这次就分享一下组件以及其实现思路吧. 深入组件化,组件的拆分.整合与复用 Vue.js的组件化可以说是其招牌特性之一,而在实际应用时,并非一味地追求组件颗粒越小越好,而是需要根据项目的实际需求,来分析自己需要什么级别的组件. 例如

随机推荐