前言

在日常工作中弹窗组件是很常用的组件,但用得多还是别人的,空闲时间就自己来简单实现一个弹窗组件

涉及知识点:extend、$mount、$el

使用方式:

this.$Confirm({
title:'自定义标题'
}).then(res=>{
console.log(res)
})

目录结构

index.vue:组件布局、样式、交互逻辑

index.js:挂载组件、暴露方法

知识点

在此之前,了解下涉及的知识点

1. extend

使用这个api,可以将引入的vue组件变成vue构造函数,实例化后方便进行扩展

2. $mount

我们希望弹窗组件是在使用时才显示出来,那么就需要动态的向body中添加元素。使用$mount方法可以手动挂载一个vue实例,和 extend 刚好搭配使用,这个也是弹窗组件命令式的关键。

3. $el

既然要添加dom元素,通过实例的$el属性,正好可以取到dom元素,之后就是使用原生方法进行添加节点啦~

代码实现

index.vue

<template>
<div class="wrap">
<div class="main">
<div class="content">
{{title}}
</div>
<div class="btn-grounp">
<div class="btn cancel" @click="cancel">{{cancelText}}</div>
<div class="btn confirm" @click="confirm">{{confirmText}}</div>
</div>
</div>
</div>
</template> <script>
export default {
name:'',
data () {
return {
title:'这是一个弹窗',
confirmText:'确定',
cancelText:'取消'
};
},
methods: {
show(cb){
typeof cb === 'function' && cb.call(this,this)
return new Promise(resolve=>{
this.resolve = resolve
})
},
confirm(){
this.resolve('confirm')
this.hide()
},
cancel(){
this.resolve('cancel')
this.hide()
},
hide(){
document.body.removeChild(this.$el)
this.$destroy()
}
},
} </script> <style scoped>
.wrap{
position: fixed;
top: 0;
bottom:0;
left:0;
right:0;
display:flex;
justify-content: center;
align-items: center;
background: rgba(0,0,0,.3);
}
.main{
width: 30%;
padding: 10px;
background: #fff;
box-shadow: 0 0 10px 1px #ddd;
border-radius: 5px;
}
.content{
color:#424242;
font-size: 20px;
}
.btn-grounp{
margin-top: 15px;
display:flex;
justify-content: flex-end;
}
.btn{
margin-left: 15px;
padding: 5px 20px;
border-radius: 5px;
font-size: 16px;
color:#fff;
}
.confirm{
background: lightblue;
}
.cancel{
background: lightcoral;
}
</style>

index.js

import Vue from 'vue'
import comfirm from './index.vue' let newInstance = null //将vue组件变为构造函数
let ConfirmConstructor = Vue.extend(comfirm) let init = (options)=>{
//实例化组件
newInstance = new ConfirmConstructor()
//合并配置选项
Object.assign(newInstance,options)
//使用$mount()后 可以理解为创建虚拟的dom
document.body.appendChild(newInstance.$mount().$el)
}
let caller = (options)=>{
//options 为调用组件方法时传入的配置选项
if(!newInstance){
init(options)
}
return newInstance.show(vm =>{newInstance = null})
}
export default {
install(vue){
vue.prototype.$Confirm = caller
}
}

main.js

上面我对外暴露的对象中含有install方法,这里可以使用Vue.use注册组件(使用Vue.use后,会查找install方法进行调用),将组件调用方法挂载到Vue原型上。

import Confirm from './components/confirm'
Vue.use(Confirm)

写在最后

这个弹窗组件比较简陋,还有很多地方可以完善

最新文章

  1. HTTP 错误 404.3 – Not Found 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。
  2. table合并单元格colspan和rowspan .
  3. 【SQL Server】系统学习之二:索引优化
  4. mvc+entity framework database first,生成的model每次更新一个表会更新所有的model
  5. Where is Vasya?
  6. ASP.NET入门(class0612)
  7. php eval函数用法总结
  8. 常用命令su ls cp cd mv cat touch mkdir rm head less more pwd tac 等
  9. Uva_11722 Joining with Friend
  10. Python之父Guido在最近一次采访的最后说了啥
  11. hdu_5690_All X(找循环节)
  12. openwrt通过libcurl上传图片,服务器端通过PHP接收文件
  13. js对象详解(JavaScript对象深度剖析,深度理解js对象)
  14. python官方推荐的各阶段学习书籍
  15. hdu1051 Wooden Sticks---贪心
  16. jquery中关键字写错导致的错误——dataType写成dateType(data写成date)
  17. hdu2586How far away ?-(LCA)
  18. AD7729_双通道Sigma-Delta ADC
  19. 以太坊: ETH 发送交易 sendRawTransaction 方法数据的签名 和 验证过程
  20. Golang go get第三方库的坑

热门文章

  1. on duplicate key update 的使用(数据库有就修改,没有就添加数据)
  2. Deepin 下 使用 Rider 开发 .NET Core
  3. 2、Linux基础练习题
  4. thinkphp volist标签中加if判断的写法
  5. ubuntu 18 怎样对Windows进行远程桌面控制
  6. 使用POI导出EXCEL工具类并解决导出数据量大的问题
  7. Spring Boot2 系列教程(二十六)Spring Boot 整合 Redis
  8. 简单的 smartpointer
  9. 什么是TCP, UDP, HTTP, HTTPS协议?
  10. iOS核心动画高级技巧 - 3