前言

由于业务需求,需要使用一个消息的全局通知组件,项目原来是使用Element上的通知组件,但是到了后面发现Element的通知组件无法满足消息通知的时间性以及可条跳转性准则所以需要自己开发一个消息通知组件,话不多说,先上干货吧。

下面为消息通知组件的使用情况,这个组件设置为可跳转不可跳转两种。

可跳转通知(在查看详情中可定义相关方法通过点击去触发,比如说放路由,或者相关URL)

不可跳转通知(纯通知)

这个是通知组件设计时的vue上的目录结构

通知组件的调用方法

组件调用代码

this.$myMsg.notify({title:"通知标题",content: "通知内容",type: 'jumpNotification',time: 0,timeNow:new Date().getTime()});

界面组件代码

<!--* @Descripttion: 通知组件的绘制界面* @version: * @Author: 刘延强* @Date: 2021-07-26 09:51:32* @LastEditors: 刘延强* @LastEditTime: 2021-07-28 15:52:07
--><template><transition name="slide-fade"><div class="my-notify" v-if="notifyFlag"><!-- 可跳转通知 --><div class="notify" v-if="type=='jumpNotification'"><div class="notice"><div><div class="iconmessage"><div class="el-icon-bell icon-xiaoxi"></div></div></div><div class="subject-content"><div class="h3">{{title}}<!-- 消息标题 --></div><div class="content"><div class="left-part"><span class="right">{{ content }}</span><!-- 消息内容 --></div></div></div><div class="close" @click="close()"><i class="el-icon-circle-close"/></div></div><div class="tableTitle"></div><div class="more" @click="clickSet()" ><div class="txt" v-time="timeNow"></div><div class="toinfo"><span class="txt">查看详情</span><span class="el-icon-arrow-right el-icon--right"/></div></div></div><!-- 不跳转的通知 --><div class="notify" v-if="type=='noJumpNotification'"><div class="notice"><div><div class="iconmessage1"><div class="el-icon-bell icon-xiaoxi"></div></div></div><div class="subject-content"><div class="h3">{{title}}<!-- 消息标题 --></div><div class="content"><div class="left-part"><span class="right">{{ content }}</span><!-- 消息内容 --></div></div></div><div class="close" @click="close()"><i class="el-icon-circle-close"/></div></div></div></div></transition>
</template><style scoped>.subject-content{margin: 0 0 15px 10px;
}.left-part {width: 260px;overflow: hidden;display: flex;flex-flow: row wrap;justify-content: start;align-items: center;
}.iconmessage {width: 44px;height: 44px;background: rgba(125, 191, 243, 1);border-radius: 100%;margin-top: 7px;
}.iconmessage1 {width: 44px;height: 44px;background: rgba(125, 191, 243, 1);border-radius: 100%;margin-top: -17px;
}.icon-xiaoxi {text-align: center;line-height: 45px;font-size: 26px;color: white;margin-left: 9px;
}.notice {display: flex;flex-flow: row nowrap;align-items: center;width: calc(100% - 30px);padding: 0 15px;background: white;padding-bottom: 10px;border-radius: 5px;padding-top: 25px;z-index:99999;
}.close {position: absolute;right: 5px;top: 1px;color: #409eff;cursor: pointer;font-size: 22px;font-weight: bold;
}
.tableTitle {position: relative;margin: 0 auto;width: 100%;height: 1px;background-color: #d4d4d4;text-align: center;font-size: 16px;color: rgba(101, 101, 101, 1);
}.more {display: flex;flex-flow: row nowrap;justify-content: space-between;align-items: center;width: calc(100% - 30px);padding: 0 15px;background: white;border-radius: 5px;
}.txt{cursor:pointer;font-size: 12px;font-family: MicrosoftYaHei;color: rgba(169, 169, 169, 1);line-height: 16px;padding: 20px 0;
}.info {display: flex;flex-flow: column nowrap;justify-content: center;align-items: flex-start;position: relative;top: 0.66667vw;width: calc(100% - 24vw);
}.toinfo {display: flex;justify-content: center;align-items: center;
}.slide-fade-leave-active {transition: all .2s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to{transform: translateX(10px);opacity: 0;
}.my-notify{margin: 10px;width: 350px;z-index: 99999;
}
.notify{position: relative;width: 350px;border-radius: 5px;background-color:white;box-shadow: -5px 5px 12px 0 rgba(204, 204, 204, .8);animation: show cubic-bezier(.18,.89,.32,1.28) .4s;/* 图文不可复制CSS */-webkit-user-select: none;-ms-user-select: none;-moz-user-select: none;-khtml-user-select: none;user-select: none;
}.notify .tip{height: 30px;margin-bottom: 5px;line-height: 30px;
}.h3 {width: 260px;font-family: MicrosoftYaHei;color: rgba(169, 169, 169, 1);color: #232323;font-size: 17px;font-weight: 600;padding: 0;
}.notify .tip span{line-height: 30px;font-size: 17px;font-weight: 600;
}
@keyframes show{0%{right: -350px;}100%{right: 10px;}
}
</style>

界面逻辑JS

/** @Descripttion: 通知组件的相关逻辑* @version: * @Author: 刘延强* @Date: 2021-07-26 09:52:22* @LastEditors: 刘延强* @LastEditTime: 2021-07-28 16:16:00*/import vue from 'vue'
import myNotify from './myNotify'
import './timeDifference.js'
import Utils from './util';// 创建vue组件实例
const notify = vue.extend(myNotify);//添加通知节点(用来存放通知的元素)
let notifyWrap = document.createElement('div');
notifyWrap.className = "notify-wrap"
// notifyWrap.style = "position: fixed; right: 0px; top: 90px; transition-duration: .5s;"
notifyWrap.style = "position: fixed;right: 0px; bottom: 0px; transition-duration: .5s;"
document.body.appendChild(notifyWrap);let myMsg = {/*** 通知框* @title 提示标题* @content 提示内容;* @type 提示框类型,parameter: jumpNotification,noJumpNotification* @time 显示时长* @timeNow 弹窗出现的时间*/notify: ({title,timeNow,content, type, time = 2000,}) => {//创建一个存放通知的divconst notifyDom = new notify({el: document.createElement('div'),data () {return {title:title, //文本标题timeNow:timeNow,//弹窗出现的时间notifyFlag: true, // 是否显示time: time,//取消按钮是否显示content: content, // 文本内容type: type, // 类型timer: '',timeFlag: false,}},watch:{timeFlag(){if(this.timeFlag){this.notifyFlag = false;window.clearTimeout(this.timer); }}},created(){this.timer = setTimeout(() => { if(this.time!=0){this.timeFlag = true;}}, this.time);},//销毁一个通知实例beforeDestroy(){window.clearTimeout(this.timer); },methods: {//关闭通知消息close() {window.clearTimeout(this.timer); this.notifyFlag = false;},//点击查看详情的方法clickSet() {Utils.$emit('Brainstorm','msg')this.close();}}})//往notifyWrap里面添加通知// notifyWrap.appendChild(notifyDom.$el);  //这个的意思是把div元素节点添加到body元素节点中成为其子节点,但是其后面添加的新节点放在body的现有子节点的最后notifyWrap.insertBefore(notifyDom.$el, document.body.lastElementChild.firstChild);//这个的意思是把div元素节点添加到body元素节点中成为其子节点,但是放在body的现有子节点的最前面}
}//注册
function register(){vue.prototype.$myMsg = myMsg
}export default {myMsg,register
}

通知时间JS

/** @Descripttion: 消息推送的时间变化组件* @version: * @Author: 刘延强* @Date: 2021-07-23 18:29:19* @LastEditors: 刘延强* @LastEditTime: 2021-07-23 19:29:52*/import Vue from 'vue'/*** 实时时间转换指令,大于一个月则返回具体的年月日* @param { string } timeStamp - 时间 格式:年-月-日 时:分:秒 或 时间戳* @returns { string }*/function getFormatTime(timeStamp){var dateTime = new Date(timeStamp) // 将传进来的字符串或者毫秒转为标准时间var year = dateTime.getFullYear()var month = dateTime.getMonth() + 1var day = dateTime.getDate()var hour = dateTime.getHours()var minute = dateTime.getMinutes()// var second = dateTime.getSeconds()var millisecond = dateTime.getTime() // 将当前编辑的时间转换为毫秒var now = new Date() // 获取本机当前的时间var nowNew = now.getTime() // 将本机的时间转换为毫秒var milliseconds = 0var timeSpanStrmilliseconds = nowNew - millisecondif (milliseconds <= 1000 * 60 * 1) { // 小于一分钟展示为刚刚timeSpanStr = '刚刚'} else if (1000 * 60 * 1 < milliseconds && milliseconds <= 1000 * 60 * 60) { // 大于一分钟小于一小时展示为分钟timeSpanStr = Math.round((milliseconds / (1000 * 60))) + '分钟前'} else if (1000 * 60 * 60 * 1 < milliseconds && milliseconds <= 1000 * 60 * 60 * 24) { // 大于一小时小于一天展示为小时timeSpanStr = Math.round(milliseconds / (1000 * 60 * 60)) + '小时前'} else if (1000 * 60 * 60 * 24 < milliseconds && milliseconds <= 1000 * 60 * 60 * 24 * 15) { // 大于一天小于十五天展示位天timeSpanStr = Math.round(milliseconds / (1000 * 60 * 60 * 24)) + '天前'} else if (milliseconds > 1000 * 60 * 60 * 24 * 15 && year === now.getFullYear()) {timeSpanStr = month + '-' + day + ' ' + hour + ':' + minute} else {timeSpanStr = year + '-' + month + '-' + day + ' ' + hour + ':' + minute}return timeSpanStr}Vue.directive('time', {bind: function(el, binding){el.innerHTML = getFormatTime(binding.value);//每隔一分钟更新一次el.__timeout__ = setInterval(function(){el.innerHTML = getFormatTime(binding.value);}, 60000);},unbind: function(el){clearInterval(el.__timeout__);delete el.__timeout__;}
});

查看详情的调用方法的公共文件

/** @Descripttion: 跨页面方法调用方法的公共文件* @version: * @Author: 刘延强* @Date: 2021-07-26 17:55:56* @LastEditors: 刘延强* @LastEditTime: 2021-07-26 20:01:49*/import Vue from 'vue'
export default new Vue

被远程跨界面调用的方法

//被远程跨界面调用的方法//@Brainstorm 头脑风暴跳转调用  var that = this;Utils.$on('Brainstorm', function (msg) {that.jumpPage();})

最后需要去main.js注册才可以全局使用这个组件

//通知消息
import message from "@/components/myMsg/index"
Vue.use(message.register);

写的不是很好,望大佬们指正!

Vue 自定义消息通知组件相关推荐

  1. 理解vue中的组件(二)

    上节说到组件https://segmentfault.com/a/1190000009236700,这一节继续来学习组件: 原文博客地址,欢迎学习交流:点击预览 从github上获取本文代码:示例代码 ...

  2. vxe-input vue 日期选择组件带农历节日、小圆点提醒

    vxe-table vxe-input vue 日期选择组件带农历节日.小圆点提醒 默认的日期选择是没有节日信息的 可以通过 festival-method 方法自定义节日信息,接收一个对象,用于渲染 ...

  3. VUE常用UI组件插件及框架-vue前端UI框架收集

    UI组件及框架 element - 饿了么出品的Vue2的web UI工具套件 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开源 UI 组件库 Keen-UI - ...

  4. 基于Vue结合Vant组件库的仿电影APP

    Vue综合案例 Vue综合案例 一.项目概要 1.效果前瞻 2.开发流程 3.开发环境 二.初始化及必要知识点 1.初始化远程仓库 2.创建项目 3.路由规划 4.反向代理配置 5.网络请求封装 6. ...

  5. Vue单文件组件的使用

    项目搭建完成后需要分别对 main.js , index.html , App.vue 文件进行编写代码 index.html <!DOCTYPE html> <html lang= ...

  6. vue 文字上下循环滚动_基于 Vue 无缝滚动组件Vue-Seamless-Scroll

    今天给小伙伴们推荐一款超棒的Vue无缝滚动组件VueSeamlessScroll. vue-seamless-scroll 基于 vue.js 构建的简单实用的无缝滚动组件.满足丰富的配置需求,支持上 ...

  7. Vue.js子组件向父组件通信

    一.场景描述: 曾经有个电商项目,其中有个"老带新"模块,而且该模块新增的入口很多,但是新增后展示效果还不一样,当时就考虑将新增的组件单独拿出来,其实就是一个子组件向父组同步数据的 ...

  8. Vue.Draggable 实现组件拖拽

    Vue.Draggable 实现组件拖拽 特性 支持触摸设备 支持拖拽和选择文本 支持智能滚动 支持不同列表之间的拖拽 不以jQuery为基础 和视图模型同步刷新 和vue2的国度动画兼容 支持撤销操 ...

  9. vue与react组件的思考

    前言 我最一开始是先学的react,然后也就前段时间开始学习vue,一开始给我的感受是两者很相似,react给我的感觉是灵活,vue是一种死板的感觉.为什么有这种感觉呢,react有一种很强烈的欲望, ...

最新文章

  1. 基于StringTemplate的视图
  2. VTK:vtkCompassWidget用法实战
  3. 想成为阿里160万年薪的P8架构师?你必须掌握如下6大技能体系!
  4. 2017.3.25 SJY摆石子 思考记录
  5. 华为云的“大招”——Euler开源 Gauss开放 旨在建立云生态
  6. Linux离线同步时间
  7. 如果人工智能最终将毁灭人类,挽救人类你能做什么?
  8. leetcode Candy
  9. MySql事务及ACID实现的原理
  10. Thinkpad常见问题大全(转载联想工程师博客)
  11. matlab中polyfit与polyval的功能
  12. ssh “Missing privilege separation directory: /run/sshd“
  13. 使用 React Testing Library 和 Jest 完成单元测试
  14. 原来 Elasticsearch 还可以这么理解
  15. 群晖NAS虚拟机安装软路由LEDE,把K3C做AP
  16. Markdowm常用公式及相关符号笔记
  17. Jenkins Git Changelog Plugin
  18. 液晶监控屏:大屏领域已占据主导地位
  19. MATLAB基础——设置符号变量sym,syms,symfun,symvar
  20. 【社招和校招】格灵深瞳合肥研发中心计算机视觉算法岗招聘

热门文章

  1. 分金问题 返回分割的最小代价 (贪心算法)
  2. KDD2016论文精品解读(二)
  3. netstat,ss,nc ,wget,dig
  4. win7下java用jdbc驱动来连接sql server的方法 (转载)
  5. Python学习之路:通过分片的方式修改列表的技巧(拓展知识)
  6. 宽带连接时用电脑开热点的方法
  7. P1972 [SDOI2009] HH的项链
  8. 微信「看一看」多模型内容策略与召回
  9. 性能测试中的二八原则
  10. OkHttp请求json数据