Vue2下判断有新消息来时以站内信方式在页面右下角弹出

以下是完整的Vue2全局通知组件实现方案,包含自动挂载和全局调用方法:

第一步:创建通知组件

<!-- src/components/Notification/index.vue -->
<template>
  <div class="notification-container">
    <transition-group name="notification-slide">
      <div 
        v-for="(msg, index) in activeNotifications"
        :key="msg.id"
        class="notification"
        :class="[`type-${msg.type}`]"
      >
        <div class="notification-header">
          <span class="title">{{ msg.title }}</span>
          <button class="close-btn" @click="close(msg.id)">×</button>
        </div>
        <div class="content">{{ msg.content }}</div>
      </div>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: 'GlobalNotification',
  data() {
    return {
      notifications: [],
      nextId: 1
    }
  },
  computed: {
    activeNotifications() {
      return this.notifications.slice(-3)
    }
  },
  methods: {
    add(config) {
      const newMsg = {
        id: this.nextId++,
        type: 'info',
        duration: 5000,
        ...config,
        timer: null
      }

      newMsg.timer = setTimeout(() => {
        this.close(newMsg.id)
      }, newMsg.duration)

      this.notifications.push(newMsg)
    },
    close(id) {
      const index = this.notifications.findIndex(msg => msg.id === id)
      if (index > -1) {
        clearTimeout(this.notifications[index].timer)
        this.notifications.splice(index, 1)
      }
    }
  }
}
</script>

<!-- 保持之前提供的样式不变 -->

<style scoped>
.notification-container {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 9999;
  max-width: 350px;
  display: flex;
  flex-direction: column-reverse;
  gap: 15px;
}

.notification {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  padding: 15px;
  border-left: 4px solid #409eff;
  transition: all 0.3s ease;
}

.notification.type-success {
  border-color: #67c23a;
}
.notification.type-warning {
  border-color: #e6a23c;
}
.notification.type-error {
  border-color: #f56c6c;
}

.notification-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.title {
  font-weight: 600;
  font-size: 14px;
  color: #303133;
}

.close-btn {
  border: none;
  background: transparent;
  font-size: 18px;
  cursor: pointer;
  color: #909399;
  padding: 0 5px;
}

.content {
  font-size: 13px;
  color: #606266;
  line-height: 1.5;
}

.notification-slide-enter-active,
.notification-slide-leave-active {
  transition: all 0.3s ease;
}
.notification-slide-enter,
.notification-slide-leave-to {
  opacity: 0;
  transform: translateX(100%);
}
</style>

第二步:创建插件文件

// src/components/Notification/index.js
import Vue from 'vue'
import Notification from './index.vue'

const NotificationConstructor = Vue.extend(Notification)

let notificationInstance = null

const initInstance = () => {
  notificationInstance = new NotificationConstructor({
    el: document.createElement('div')
  })
  document.body.appendChild(notificationInstance.$el)
}

const NotificationPlugin = {
  install(vue) {
    vue.prototype.$notify = (config) => {
      if (!notificationInstance) {
        initInstance()
      }
      notificationInstance.add(config)
    }
  }
}

export default NotificationPlugin

第三步:全局注册(main.js)

// src/main.js
import Vue from 'vue'
import App from './App.vue'
import NotificationPlugin from '@/components/Notification/index'

Vue.use(NotificationPlugin)

new Vue({
  render: h => h(App)
}).$mount('#app')

第四步:全局使用示例

在任何Vue组件中直接调用:

// 显示基础通知
this.$notify({
  title: '系统消息',
  content: '您有新的站内信',
  type: 'success',
  duration: 3000
})

// 显示警告通知
this.$notify({
  title: '操作警告',
  content: '删除操作不可恢复',
  type: 'warning'
})

// 显示错误通知
this.$notify({
  title: '发生错误',
  content: '网络连接超时',
  type: 'error',
  duration: 8000
})

功能增强说明:

  1. 自动挂载:首次调用时自动创建DOM节点,无需手动放置组件
  2. 内存管理:使用单例模式保证全局只有一个通知实例
  3. 类型校验(可选增强):
// 在NotificationPlugin中添加
import { validateType } from './validators'

Vue.prototype.$notify = (config) => {
  if (!validateType(config.type)) {
    console.error('Invalid notification type')
    return
  }
  // ...原有逻辑
}
  1. 全局配置(可选):
// 初始化配置
Vue.use(NotificationPlugin, {
  maxDisplay: 5,      // 最大显示数量
  defaultDuration: 5000, // 默认持续时间
  position: {        // 显示位置
    bottom: '20px',
    right: '20px'
  }
})

注意事项:

  1. 样式文件需要全局引入或在组件内使用scoped以外的样式声明
  2. 建议在组件销毁时自动清理定时器(已在原组件实现)
  3. 可以通过扩展config参数添加更多功能(如点击回调、自定义模板等)

这种实现方式具有以下优势:

  • 真正的全局单例模式
  • 完全解耦的调用方式
  • 支持Vue2的完整生命周期管理
  • 可扩展性强,方便后续功能升级

第五步:header组件判断新消息

mounted() {
  this.startTimer(); // 组件挂载时启动定时器
},
beforeDestroy() {
  this.stopTimer(); // 组件销毁时清除定时器
},
methods: {
  // 启动定时器
  startTimer() {
    if (!this.timer) {
      this.timer = setInterval(this.checkForNewMessages, 10000); // 每 10 秒执行一次
    }
  },

  // 清除定时器
  stopTimer() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null;
    }
  },
  // 检查是否有新消息
  checkForNewMessages() {
    this.$http.post('/message/list',{'pageSize':3,"userId":this.userId}).then(res => {
        console.log('定时器判断是否有新消息 : ',res);
        if (res.code === '0000'&&res.data.rows.length>0) {
          res.data.rows.forEach(item => {
            // 显示基础通知
            this.$notify({
              title: '新消息提醒',
              content: item.content,
              type: 'success',
              duration: 3000
            })
          })

        }
      })
      .catch(error => {
        console.error('检查新消息失败:', error);
      });
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值