vue How to write a message notification component $ notify, simple and easy to understand, you can do it when you go!

Without further ado, on the renderings

Foreword

    When I used elementui to write the page when I finished the design, I found this notification to be very interesting. It can be called with a command (this. $ Notify), which is amazing. So I plan to encapsulate one myself and call it later.

Step 1: Create a template for this notification

First, you find a suitable location in the vue project to create a folder, create a vue file and a js file

code show as below

myNotify.vue

 I implement the transition through transition  , v-if to determine the display type, the other is some styles (personally feel that this is quite redundant, can be improved)

<template>
  <transition name="slide-fade">
    <div class="my-notify" v-if="notifyFlag">
      <div class="notify success" v-if="type=='success'">
        <div class="tip">
          <span>成功</span>
        </div>
        <div class="content"> {{content}}</div>
      </div>
      <div class="notify error" v-else-if="type=='error'">
        <div class="tip">
          <span>错误</span>
        </div>
        <div class="content">{{content}}</div>
      </div>
      <div class="notify warning" v-else-if="type=='warning'">
        <div class="tip">
          <span>警告</span>
        </div>
        <div class="content">{{content}}</div>
      </div>
    </div>
  </transition>
</template>

<style scoped>
.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;
}
.notify-wrap{
  
  background-color: #1AFA29;
}
.my-notify{
  margin: 10px;
  width: 350px;
}
.notify{
  position: relative;
  right: 10px;
  padding-left: 10px;
  width: 320px;
  height: 70px;
  border-radius: 4px;
  background-color:rgb(255, 244, 224);
  box-shadow: -5px 5px 12px 0 rgba(204, 204, 204, .8);
  animation: show cubic-bezier(.18,.89,.32,1.28) .4s;
}
.success{
  border-left: 10px solid #1AFA29;
}
.error{
  border-left: 10px solid #D81E06;
}
.warning{
  border-left: 10px solid #F4EA2A;
}
.notify .tip{
  height: 30px;
  margin-bottom: 5px;
  line-height: 30px;
}
.notify .tip span{
  line-height: 30px;
  font-size: 17px;
  font-weight: 600;
}
.notify .content{
  width: 320px;
  height: 30px;
  font-size: 15px;
}
@keyframes show{
  0%{
    right: -350px;
  }
  100%{
    right: 10px;
  }
}
</style>

index.js

When using element notifications, I found that he realized it by inserting elements in the body, but I felt that each one was a bit scattered, so I wrapped them with a div, so that I could not use js Calculating height to achieve queuing has become simpler. Time out by timeout to achieve the effect of staying, monitoring the change of timeFlag to decide whether to disappear the notification. The role of the registration method is described in detail below.

import vue from 'vue'
import myNotify from './myNotify'

// 创建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;"
document.body.appendChild(notifyWrap);

let myMsg = {
  /**
   * 通知框
   * @content 提示内容;
   * @type 提示框类型,parameter: success,error,warning
   * @time 显示时长
   */
  notify: ({
    content, 
    type, 
    time = 1500,
  }) => {
    //创建一个存放通知的div
    const notifyDom = new notify({
      el: document.createElement('div'),
      data () {
        return {
          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(() => { 
          this.timeFlag = true;
        }, this.time);
         
      },
      beforeDestroy(){
        window.clearTimeout(this.timer); 
      }
    })
    
    //往notifyWrap里面添加通知
    notifyWrap.appendChild(notifyDom.$el);
  }
}

//注册
function register(){
  vue.prototype.$myMsg = myMsg
}

export default {
  myMsg,
  register
}

You may find that this format is a bit strange. If you have visited the vue official website, this format is more familiar, creating a vue object, and so on.

Okay, here comes the question. With the theme function, how do we use this. $ Xxx to call it?

Step 2: Register

 Enter main.js to add it.

import Vue from 'vue';
import App from './App';
import router from './router';
import store from "./store/store";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import api from "@/server/api.js";

//这行
import message from "@/components/myMsg/index"


Vue.config.productionTip = false;
Vue.prototype.$http = api;
Vue.use(ElementUI);

//和这行
Vue.use(message.register);

new Vue({
  el: '#app',
  store,
  router,
  components: { App },
  template: '<App/>'
})

As long as the two lines noted above are sufficient. In fact, you can be lazy here, because it is named index, so you don't need to add index when introducing the path. Here, you can see the registration. Yes, the registration method above is made here. Of course, you can also write it separately.

Step 3: Call

Okay, after so long, how to call it?

this.$myMsg.notify({
   content: "啦啦啦",
   type: 'success',
 //time: 5500
});

Is it almost the same, hurry and try!

End

 I am still an intern, there may be a lot of unreasonable places on it, please also enlighten me!

Published 3 original articles · Liked5 · Visitors1072

Guess you like

Origin blog.csdn.net/weixin_39394140/article/details/103768034