从零开始构建自己的vue组件库之message篇

8次阅读

共计 3085 个字符,预计需要花费 8 分钟才能阅读完成。

第二篇:从零开始构建自己的 vue 组件库之————message 组件


组件需求

  • message 这种组件应该是按需加载的没差了,用的时候就不要写在页面里了,必须得是 this.$message(config) 这样子用的,姿势很优美 [滑稽];
  • 顶部居中吧,既然人家各种框架也是顶部居中,咱也随大流啦,重在理解实现方式啦 [再次滑稽];
  • 好了,具体需求是,用不同图标表示不同类型的 message(有默认);时长自定义或默认;内容自定义;可关闭或不可关闭(或点击文字关闭);

PS:组件结构参考上一篇 button 组件

message.vue

<template lang="html">
  <transition name="message-fade">
    <div class="wui__message" :class="[prefixCls +'--'+ type]" v-if="visible">
      <i  :class="[prefixCls +'__icon'+'--'+ type,iconType]"></i>  
      <div :class="[prefixCls +'__content']">
        <span :class="[prefixCls +'__content'+'__body']" v-html="content"></span>
        <span v-if="closeTxt" @click="close()" :class="[prefixCls +'__closeTxt']">
          {{closeTxt}}
        </span>
        <span v-if="closable" :class="[prefixCls +'__iconbox']">
          <i class="icon-close" :class="[prefixCls +'__icon']"  @click="close()"></i>
        </span>
      </div>
    </div>
  </transition>
</template>

<script>
const prefixCls = 'wui__message';
export default {
  name:'Message',
  data(){
    return {prefixCls:prefixCls,}
  },
  mounted() {
    //do something after mounting vue instance
    if(this.closeTxt){this.closable = false}
  },
  methods: {close() {this.visible = false}
  }
}
</script>

<style lang="scss" scoped>
</style>

message 目录下的 index.js

import Vue from 'vue';
import Message from './src/message.vue';
const defaults = {
    visible:false,
    content:undefined,
    duration:'3',
    type:'info',
    closable:false,
    closeTxt:null,
    top:20,
    iconType:''
};
const typeMap = {
  "info":'icon-info',
  "error":'icon-heart-broken',
  "warning":'icon-stopwatch',
  "success":'icon-checkmark-outline'
}
const MessageVueConstructor = Vue.extend(Message);

MessageVueConstructor.prototype.close = function() {
  var vm=this;
  this.$on('after-leave', _ => {if (vm.$el && vm.$el.parentNode) {vm.$el.parentNode.removeChild(vm.$el);
    }
    this.$destroy();});
    vm.visible = false;

};
const messageBox = (options = {}) => {if (Vue.prototype.$isServer) return;
    options = Object.assign({}, defaults, options);
    let instance = new MessageVueConstructor({el: document.createElement('div'),
      data: options
    });
    if(!instance.type||!instance.content){return false}
    document.body.appendChild(instance.$el);
    Vue.nextTick(() => {
      instance.visible = true;
      instance.iconType = typeMap[instance.type]
      // if duration is 0 means can't close
      if(instance.duration!=0){setTimeout(function(){instance.close();
        },options.duration*1000)
      }
    });
    return instance;
  };

export default messageBox;

package 下的 index.js(继上篇增加)

import WButton from './button/index.js';
import WMessage from './message/index';
const components = [
  WButton,
  WMessage
]

const install = function(Vue) {if (install.installed) return
  components.map(component => Vue.component(component.name, component))
  Vue.prototype.$Message = WMessage;  //important
}

if (typeof window !== 'undefined' && window.Vue) {install(window.Vue)
}

export default {
  install,
  WButton,
  WMessage,
}

接下来就可以愉快的使用了,具体的使用姿势如下

this.$Message({content:'this is info'})  
// 不指定 type 默认为 info
this.$Message({type:'info',content:'This is a closed message',closable:true})  
// 这种情况就会有关闭的叉叉
this.$Message({type:'info',content:'this is 10-second message',duration:10})  
// 时长 10 秒让 message 多待会
this.$Message({type:'info',content:'This is a message that can not be closed',duration:0}) 
// 时长为 0 表示不想让消失
this.$Message({type:'info',content:'This is a custom closed text message',closeTxt:'朕知道了',duration:10})  
// 自定义关闭文字也可以皮一下

至此一个 message 组件就愉快的实现了,可以满足大多数场景的需求,扩展性也是比较 OK 的,可是总觉得还缺点功能,路过的看官伸出无敌的小手指正一下可好?

正文完
 0