1. 首页
  2. 前端

关于vue中全局组件通用组件的封装及使用方法介绍

使用vue开发项目,有些UI组件库难免满足不了工作需求,这时,自己封装一些组件是必不可少的,接下来接介绍下vue中公共组件的封装步骤和实例分析。

vue使用install定义安装全局组件需要install和use这两个api来配合才能完成,组件通过export暴露出install方法 。

但如果直接将指定组件赋值到vue的prototype上,组件不需要vue.use安装直接就能用。

1.全局组件单例模式

这里通过实现一个 Notify移动端消息提示组件和加载组件,来对组件的封装过程进行详述。

实例一: Notify组件的封装

Notify.vue

<template>
  <div class="Notify" v-show="visible" :class="className">
    <div class="msg" :class="type">{{ message }}</div>
  </div>
</template>

<script>
export default {
  name: "Notify",
  data() {
    return {
      show1: false,
      $_timer: null,
      className: "fadein",
      time: 2000
    };
  },
  props: {
    message: {
      type: String,
      required:true,
      default: "提示信息"
    },
    visible: {
      type: Boolean,
      default: false
    },
    duration: {
      type: Number,
      default: 2000
    },
    type: {
      type: String,
      default: "default"
    }
  },
  mounted() {},
  methods: {
    fire() {
      const _this = this;
      if (_this.$_timer) {
        clearTimeout(_this.$_timer);
      }
      if (_this.visible) {
        if (_this.duration) {
          _this.time = _this.duration;
        }
        _this.$_timer = setTimeout(() => {
          _this.hide();
        }, _this.time);
      }
    },
    show() {
      this.className = "fadein";
      this.visible = true;

      this.fire();
    },
    hide() {
      this.className = "fadeout";
      setTimeout(() => (this.visible = false), 300);
    }
  },
  watch: {
    visible: {
      handler: function(data) {
        this.show1 = data;
      },
      immediate: true
    }
  }
};
</script>
<style lang="less">
.Notify {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 9999;
  padding: 10px 10px 0;
  box-sizing: border-box;
  .msg {
    font-size: @font;
    height: 66px;
    line-height: 66px;
    text-align: center;
    border-radius: 5px;
  }
}
.default {
  background-color: @color;
  color: #fff;
}
.success {
  background-color: #00d712;
  color: #dfffe8;
}
.warning {
  background-color: @color;
  color: #fff;
}
.error {
  background-color: red;
  color: #fff;
}
/* 淡入代码 */
@keyframes fade-in {
  0% {
    opacity: 0;
  } /*初始状态 透明度为0*/
  100% {
    opacity: 1;
  } /*结束状态 透明度为1*/
}
@keyframes fade-out {
  0% {
    opacity: 1;
  } /*初始状态 透明度为0*/
  100% {
    opacity: 0;
  } /*结束状态 透明度为1*/
}
.fadein {
  animation: fade-in; /*动画名称*/
  animation-duration: 0.3s; /*动画持续时间*/
}
.fadeout {
  animation: fade-out; /*动画名称*/
  animation-duration: 0.3s; /*动画持续时间*/
}
</style>

index.js

import NotifyComponent from "./Notify";

const Notify = {};
// 注册Notify
Notify.install = function(Vue) {
  // 生成一个Vue的子类
  // 同时这个子类也就是组件
  const NotifyConstructor = Vue.extend(NotifyComponent);
  // 生成一个该子类的实例
  const instance = new NotifyConstructor();
  // 将这个实例挂载在我创建的div上
  // 并将此div加入全局挂载点内部
  instance.$mount(document.createElement("div"));
  document.body.appendChild(instance.$el);
  // 通过Vue的原型注册一个方法
  // 让所有实例共享这个方法
  Vue.prototype.$notify = (config, duration, type) => {
    console.log(config);
    if (typeof config === "string" || typeof config === "number") {
      console.log(type);
      instance.message = config;
      instance.duration = duration;
      instance.type = type;
      instance.visible = true;
      instance.show();
      return;
    }
    instance.message = config.content;
    instance.duration = config.duration;
    instance.visible = true;
    instance.type = config.type;
    instance.show();
  };
};

export default Notify;

main.js中注册:

import Notify from "./components/Notify";
Vue.use(Notify);

这时候,Notify全局组件就已经封装好了,在项目的任意组件中都可以直接使用了。该组件是单例模式,我们可以按照下面方式使用:

this.$notify('系统异常')
this.$notify({
    content: '系统异常',
    duration: 2000,
    type: "success"
})

实例二: Loading加载组件的封装

Loading.vue

<template>
  <div v-if="visible" class="loading">
    <div class="loading-block">
      <img :src="src" />
    </div>
    <div class="text">{{text}}</div>
  </div>
</template>
<script>
export default {
  name: "Loading",
  data() {
    return {
      src: require("./../../assets/images/loading.gif"),
      visible: false
    };
  },
  props: {
    text: {
      type: String,
      default: "加载中..."
    }
  }
};
</script>
<style lang="less" scoped>
.loading {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 9999;
  transform: translate(-50%, -50%);
  width: 100%;
  .loading-block {
    text-align: center;
    img {
      width: 50%;
    }
  }
  .text {
    text-align: center;
    font-size: 36px;
    color: #666;
  }
}
</style>

index.js

import LoadingComponent from "./Loading";
const Loading = {};
// 注册Loading
Loading.install = function(Vue) {
  // 生成一个Vue的子类
  // 同时这个子类也就是组件
  Vue.prototype.$loading = {};
  const LoadingConstructor = Vue.extend(LoadingComponent);
  // 生成一个该子类的实例
  const instance = new LoadingConstructor();
  Vue.prototype.$loading.show = config => {
    // 并将此div加入全局挂载点内部
    Vue.nextTick(() => {
      instance.visible = true;
    });
    document.body.appendChild(instance.$mount().$el);
    if (config) {
      instance.text = config.text;
    }
  };
  Vue.prototype.$loading.hide = () => {
    instance.visible = false;
    document.body.removeChild(document.getElementById("loading"));
  };
};
export default Loading;

至此,关于Loading的加载组件就已经封装好了,可以在需要的地方注册就可以了,这里就以注册到main.js为例:

import Loading from "@/components/loading";
Vue.use(Loading);

对于自定义的全局组件在组件中使用和在导航守卫beforeEach中的使用有所不同,如果是在组件中使用,使用方式如下:

this.$loading.show();
this.$loading.hide();
this.$loading.show({
      text: '加载中'
});

由于$loading是挂在在Vue实例原型中的对象,如果是在导航守卫中使用,直接是拿不到$loading对象的,所以我们使用Vue.prototype来获取Vue原型中的$loading对象就可以拿到该对象,方式如下:

Vue.prototype.$loading.show();
Vue.prototype.$loading.hide();
Vue.prototype.$loading.show({
  text: '加载中'
});

对于简单的全局组件封装的实例介绍就到此,接下来介绍下通用的组件封装方式

2.通用组件封装

未完待续…………

原创文章,作者:Ferrycoln,如若转载,请注明出处:https://ms200.cn/archives/1521

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

在线咨询:点击这里给我发消息

邮件:499661635@qq.com.com

工作时间:周一至周五,9:30-18:30

QR code