前言
VUE中有标签式组件和API式组件,我们在开发过程中很多时候都是在写标签式组件,API式组件写的比较少,但如果我们使用了一些VUE的UI框架的话,那一定会使用过API式组件。API式组件一般用于弹窗、消息提醒等方面,也就是暂时显示类型的组件,比如ElementUI的$message、$alert等。那么接下来我们就来开发一个API式组件吧。
一、原理分析
由于API式组件需要在调用API的时候才渲染,因此,我们需要在调用方法的时候,才能让组件实例挂载。当用完了这个组件,我们需要让它自动挂载,比如一个弹窗组件,在弹窗结束之后,我们要让它自动卸载。因此我们需要用到两个VUE的API:$mount、$destroy。
二、开发组件
下面我们以一个Alert组件为例,我们要写一个弹窗组件,在调用API时弹出,点击确定时隐藏并销毁。
1.编写组件模板
在components文件夹下新建一个文件夹 myAlert ,在 myAlert 文件夹中新建 index.js 和 template.vue 两个文件。
接下来编辑 template.vue文件
<template>
<div class="mark">
<div class="alert">
<div class="alert-title">{{ title }}</div>
<div class="alert-content">{{ content }}</div>
<div class="alert-btn">确定</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
title:'标题',
content:'您的余额不足'
}
}
}
</script>
<style lang="scss" scoped>
.mark{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,.3);
display: flex;
align-items: center;
justify-content: center;
.alert{
width: calc(100% - 100px);
max-width: 300px;
background: #fff;
box-sizing: border-box;
border-radius: 10px;
.alert-title{
line-height: 48px;
text-align: center;
color: #333;
font-size: 18px;
}
.alert-content{
line-height: 1.6em;
text-align: center;
color: #999;
font-size: 14px;
padding: 5px 15px 15px;
}
.alert-btn{
line-height: 48px;
text-align: center;
color: #0073ff;
font-size: 16px;
border-top: 1px solid #eee;
cursor: pointer;
}
}
}
</style>
这时候我们可以先通过标签方式直接引入这个组件,看看样式效果
<template>
<div>
<myAlert/>
</div>
</template>
<script>
import myAlert from '@/components/myAlert/template'
export default {
components:{
myAlert
}
}
</script>
显示如下说明正常
我们可以通过这个方式查看自己组件模板的样式
当模板样式确定好之后,我们需要把 template.vue 文件里的 data 数据清空了,或者需要默认值的话可以留个默认值。清空后代码如下:
export default {
data(){
return {
title:'',
content:''
}
}
}
此时我们的模板已编写完成,接下来我们来实现它的API式组件调用吧
2.实现API式组件
我们来编辑一下 components/myAlert/index.js 文件
import Vue from 'vue'//引入VUE
import template from "@/components/myAlert/template";//引入模板
const Component = Vue.extend(template)//拿到继承模板后的类
export const myAlert = (data)=>{
//初始化组件实例对象
let node = new Component({
data:data || {}//将调用API传入的参数赋值给组件的data
})
//挂载组件
node.$mount()
//将节点插入到页面中
document.body.appendChild(node.$el)
}
接下来我们试着通过API的方式调用一下这个组件,把刚才的标签式组件都删掉,改为如下方式:
<template>
<div>
</div>
</template>
<script>
import {myAlert} from '@/components/myAlert'
export default {
mounted(){
myAlert({
title:'API调用',
content:'恭喜您,成功了'
})
}
}
不出意外的话,页面显示应该是这样的
那说明我们已经成功了, 但现在点击确定并没有任何反应,因为我们还没有做卸载处理
接下来我们来做卸载处理
修改 components/myAlert/template.vue 文件如下:
<template>
<div class="mark">
<div class="alert">
<div class="alert-title">{{ title }}</div>
<div class="alert-content">{{ content }}</div>
<div class="alert-btn" @click="close">确定</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
title: '',
content: ''
}
},
methods: {
close() {
if (this.$el.parentNode)//先判断是否有父节点
this.$el.parentNode.removeChild(this.$el)//把该节点从父节点中删除
this.$destroy()//卸载组件
}
}
}
</script>
修改之后,我们再点击确定按钮,弹窗组件就会消失并且被卸载啦,那么这个API式组件我们就制作完成了。