vue 自定义 notice 组件、多notice 展示样式、自定义渲染内容

notices.vue

<template>
  <div ref='noticeSelfs' :class="['noticeSelf' , classStyle]"  flex>
    <div class='imgs'>
      <img class="imgs1" src="../../../../assets/index/welcome.png" alt="">
      <img class="imgs2" src="../../../../assets/index/headBg.png" alt="">
    </div>
    <div class='contents'>
      <div v-if='showDeletes' @click='deletes'> 删除</div>
      <div v-if='title' class='title'>{{title}}</div>
      <div v-if='message' class='message'>{{message}}</div>
      <render-cell v-if='renders' :render="renders"></render-cell>
    </div>
  </div>
</template>
<script>
  import RenderCell from '@/libs/render';

  export default {
    components: {
      RenderCell
    },
    props: {
      classStyle: {
        type: String,
      },
      showDeletes: { //是否显示删除按钮
        type: Boolean,
        default: true
      },
      title: { //标题
        type: String,
      },
      message: { //message
        type: String,
      },
      duration: { //延迟自动关闭时间 0 默认不自动关闭
        type: Number,
        default: 3000,
      },
      renders: {
        type: Function
      },
      onclose: { //关闭是回调方法
        type: Function
      },
    },
    data() {
      return {
        timer: ''
      };
    },
    mounted() {
      //主动触发
      this.show()
    },
    methods: {
      //自定义关闭事件
      close() {
        this.onclose ? this.onclose() : '';
        this.hide()
      },
      //主动删除
      deletes() {
        this.close()
      },
      //被动触发
      show() {
        if (this.duration != 0) {
          this.timer = setTimeout(() => {
            this.hide();
          }, this.duration);
        }
      },
      //关闭
      hide() {
        let dom = this.$refs.noticeSelfs
        dom.setAttribute("class",dom.getAttribute('class')+" notice1-leave")
        clearTimeout(this.timer)
        let times = setTimeout(()=>{
          clearTimeout(times)
          this.remove();
        },500)
      },
    },
  };

</script>
<style lang="less" scoped>
  .contents{
    border: 1px solid #ccc;
    border-radius: 10px 0px 10px 0px;
    padding: 10px;
    width: 189px;
  }
  .imgs{
    width: 72px;
    position: relative;
  }
  .imgs1{
    position: absolute;
    width: 40px; 
    /* top: 20px;  */
  }
  .imgs2{
    position: absolute;
    width: 85px;
    /* top: 20px; */
    left: -23px;
  }
  .noticeSelf {
    width: 300px;
    height: auto;
    padding: 20px;
    border-radius: 10px;
    background-color: lightblue;
    margin: 10px;
  }

  .notice1-info {
    background-color: white;
  }

  .notice1-warning {
    background-color: rgb(219, 194, 125);
  }
  @keyframes fade-in {  
    0% {opacity: 0;
      transform: translateX(-300px);
    }
    40% {opacity: 0;}
    100% {opacity: 1;
      transform: translateX(0px);}
  }   
  .notice1-info {    
      animation: fade-in;/*动画名称*/  
      animation-duration: 1.5s;/*动画持续时间*/  
  } 

  .notice1-leave{
    animation: fade-out;/*动画名称*/  
    animation-duration: 1.5s;/*动画持续时间*/  
  }
  @keyframes fade-out {  
    100% {opacity: 1;
      transform: translateX(0px);
    }
    40% {opacity: 0;}
    100% {opacity: 0;
      transform: translateX(-300px);}
  } 
</style>



render.js

export default {
  name: 'RenderCell',
  functional: true,
  props: {
    render: Function
  },
  render: (h, ctx) => {
      return ctx.props.render(h);
  }
};

create.js

//  create.js
import Vue from "vue";
import Notice from "@/view/visitorSystem/components/notices";
function create(type, props) {

  if( type == "info"){
    props.classStyle='notice1-info'
  }else if(type == "warning"){
    props.classStyle='notice1-warning'
  }

  //  先创建实例
  let vm = new Vue({
  render(h) {
    return h(Notice, {
        props
      });
    }
  }).$mount();

  if (!document.querySelector(".notece-container")) {
    let div = document.createElement("div");
    div.setAttribute("class", "notece-container");
    div.style.position = "absolute";
    div.style.top = "20px";
    div.style.left = "20px";
    div.style.maxHeight = "calc(100% - 50px)";
    div.style.overflow = "auto";
    div.style.zIndex = "10000000";
    document.body.appendChild(div);
    document.querySelector(".notece-container").addEventListener("scroll",function(e){
      // console.log("scrollscrollscrollscrollscrollTop>>>>>>>>>>>>",e.target.scrollTop)
      // console.log("e.target.scrollHeighte.target.scrollHeight",e.target.scrollHeight)
      // console.log("dom.clientHeight",e.target.clientHeight)
    })
  }

  //手动挂载到div.notece-container上
  document.querySelector(".notece-container").appendChild(vm.$el);

  //多消息通知自动滚动到底部
  vm.$nextTick(()=>{
    let dom = document.querySelector(".notece-container")
      let scrollHeight= dom.scrollHeight
      let clientHeight= dom.clientHeight
      if(scrollHeight>clientHeight){
        dom.scrollTop=scrollHeight
      }
  })

  const comp = vm.$children[0];
  //销毁
  comp.remove = function() {
    document.querySelector(".notece-container").removeChild(vm.$el);
    vm.$destroy();
  };
  return comp;
}
export default {
  info(props) {
    return create("info", props);
  },
  success(props) {
    return create("success", props);
  },
  fail(props) {
    return create("fail", props);
  },
  warning(props) {
    return create("warning", props);
  }
};


注册

//  main.js
import create from '@/libs/create'
Vue.prototype.$create = create

调用

<script>

 export default {
 	mounted(){
		this.$create.info({
        title:'法萨芬三发发发发生发啊1',
        message:'发丰东股份回过家干活2',
        duration:0,
        onclose(){
          console.log('>>>>>>>>>>>>',111111111111111111111111111111111);
        },
        renders: h => {
              return h('div', {
                class: "hoverNotice",
                style: {
                  'line-height': '1.3',
                  // color:"#FFB300",
                  // display: 'inline-block',
                  cursor: 'pointer',
                },
                domProps: {
                  innerHTML: '这里是要渲染的数据这里是要渲染的数据这里是要渲染的数据这里是要渲染的数据这里是要渲染的数据'// 这里是要渲染的数据
                },

              }, [
                h('span', {}, `${1?'查看':''}`),

              ])
            }
      })
      this.$create.warning({
        title:'法萨芬三发发发发生发啊12324',
        message:'发丰东股份回过家干活4234234234232',
        duration:5000,
        showDeletes:false
      })
 	}
 }
</script>

你可能感兴趣的:(vue)