如何优雅地写一个Vue全局组件
如何优雅地写一个Vue全局组件
在Vue开发过程中,为了实现高内聚,低耦合的代码,组件复用是一件稀松平常的事情。
你可能看到过在多个组件中频繁import,并且添加到components里,最后,还要在template模板中引用。
引入
import childCom from '@/components/childCom.vue';
注册
components:{
childCom
}
引用
<childCom/>
以上只是最普通的用法,当你需要父子组件进行数据传递的时候,各种props,$emit,业务越多,就越有一种剪不断理还乱的感慨。It's so messy
高级一点的,你可能会想,与其频繁地import,我干嘛不使用全局组件呢?恭喜你,已经很接近真相了!Vue为我们提供了注册全局组件的方法:
Vue.component('my-component', { /* ... */ })
这样是省去了组件引入和注册的步骤,但是还不够,我们还需要在父组件模板中引用,父子组件之间数据交互依然很麻烦
我依稀记得,那是一个雨后的下午,空气中充斥着泥土的芳香,我百无聊赖地躺在椅子上,鼠标在网页上游曳,突然一个东西闯入我的眼帘,它好像长着倒钩,勾起了我无限的好奇心。那天月挂星稀的时候,我依然在文档里陶醉。
前戏那么多,该到正题了。。。。
官网的介绍很简单:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。也就是说他可以接收的对象里面可以包括data,methods等组件属性。那么我们是不是可以利用这一点做一个定制度高的全局组件呢?
那么我们就来搞一个全局model框~~
在index.vue中敲出model的基本样式布局,默认属性配置:
<template>
<div class="model" v-show="showModel">
<div class="content">
<div class="title">{{ title }}</div>
<div class="operate">
<div class="cancel" @click="cancelModel" :style="{color: cancelTextColor}">{{ cancelText }}</div>
<div class="confirm" @click="confirmModel" :style="{color: confirmTextColor,background: confirmBgColor}">{{ confirmText }}</div>
</div>
</div>
</div>
</template>
data () {
return {
title: '标题',
cancelText: '取消',
confirmText: '确定',
showModel:true,
cancelTextColor: '#424141',
confirmTextColor: '#fff',
confirmBgColor:'cornflowerblue'
}
},
.model {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0,0,0,.5);
}
.content {
width: 300px;
height: 150px;
background: #FFFFFF;
border-radius: 10px;
overflow: hidden;
text-align: center;
}
.title {
font-size: 20px;
line-height: 100px;
}
.operate {
height: 50px;
display: flex;
font-size: 20px;
line-height: 50px;
}
.cancel {
box-sizing: border-box;
flex: 1;
border-top: 1px solid #ddd;
}
.confirm {
flex: 1;
background: cornflowerblue;
color: #FFFFFF;
}
下来我们再来搞如何将这个组件注册成全局,在index.js中:
引入index.vue组件,vue依赖
import vue from 'vue'
import model from './index.vue'
使用extend方法创建vue的子类
const modelConstructor = vue.extend(model);
new出子类实例,混入配置对象,并且将该实例挂载到DOM中去。
function showModel (options,callback) {
const modelDom = new modelConstructor({
data () {
return options
},
methods:{
cancelModel () {
this.remove()
},
confirmModel () {
callback && callback()
this.remove()
},
remove(){
this.showModel = false
document.body.removeChild(modelDom.vm.$el)
}
}
})
modelDom.vm = modelDom.$mount()
console.log(modelDom.vm)
document.body.appendChild(modelDom.vm.$el)
}
将初始化函数挂载到Vue原型链上。
function initModel () {
vue.prototype.$showModel = showModel
}
最后,抛出初始化函数
export default initModel
在main.js中进行插件注册:
import initModel from './model/index.js'
Vue.use(initModel)
以上,全局组件就已经写好了,下来我们全局任何地方使用了,比如,在home.vue中:
默认调用:
<div @click='showModel'>显示model框</div>
showModel () {
this.$showModel()
}
自定义调用(自定义样式,配置回调函数):
this.$showModel({
showModel:true,
title:'model标题',
cancelTextColor:'#96063d',
confirmTextColor:'#68f609',
confirmBgColor:'#f9a6a6'
},()=>{
console.log(123)
})
OK,that's all,Are you get it?~Bye~
镇楼图有点东西~
听君一席话胜读十年书!
大佬牛逼!!!
我是因为第一张图片来的