使用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>
content: “系统异常”, //消息提示内容,必填项
duration: 2000, //消息持续时间,不指定,默认为2000
type: “success” //消息类型,成功( success ),失败( error ),警告( warning ),如果不指定type,择默认是 default
show() //显示方法
hide() //消失方法
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