1. 组件编写原则
2. 封装JS
class Dialog {
constructor ( options) {
this . opts = {
width: "30%" ,
height: "200px" ,
title: "测试标题" ,
content: "测试内容" ,
dragable: true ,
maskable: true ,
isCancel: false ,
}
}
}
3. 合并配置Object.assign(a,b)
class Dialog {
constructor ( options) {
this . opts = Object. assign ( {
width: "30%" ,
height: "200px" ,
title: "默认标题" ,
content: "默认内容" ,
dragable: true ,
maskable: true ,
isCancel: false ,
} , options) ;
console. log ( this . opts) ;
}
}
let dialog1 = new Dialog ( {
width: "40%" ,
title: "dialog1测试标题" ,
content: "dialog2测试内容" ,
} ) ;
> { width: "40%" , height: "200px" , title: "dialog1测试标题" , content: "dialog2测试内容" , dragable: true , …}
4. 页面渲染
renderView ( ) {
this . dialogHTML = document. createElement ( "div" ) ;
this . dialogHTML. innerHTML =
`
<div class="k-wrapper"></div>
<div class="k-dialog" style="width: ${ this . opts. width} ;height: ${ this . opts. height} ">
<div class="k-header">
<span class="k-title"> ${ this . opts. title} </span><span class="k-close">X</span>
</div>
<div class="k-body">
<span> ${ this . opts. content} </span>
</div>
<div class="k-footer">
${ this . opts. isCancel? '<span class="k-cancel">取消</span>' : '' }
<span class="k-primary">确定</span>
</div>
</div>
`
document. querySelector ( "body" ) . appendChild ( this . dialogHTML) ;
}
5. 功能实现-显示弹窗
open ( ) {
if ( this . opts. maskable) {
this . dialogHTML. querySelector ( ".k-wrapper" ) . style. display = "block" ;
}
this . dialogHTML. querySelector ( ".k-dialog" ) . style. display = "block" ;
}
6. 功能实现-关闭弹窗extends EventTarget类
close ( ) {
if ( this . opts. maskable) {
this . dialogHTML. querySelector ( ".k-wrapper" ) . style. display = "none" ;
}
this . dialogHTML. querySelector ( ".k-dialog" ) . style. display = "none" ;
}
class Dialog extends EventTarget {
constructor ( options) {
super ( ) ;
this . opts = Object. assign ( {
width: "30%" ,
height: "200px" ,
title: "默认标题" ,
content: "默认内容" ,
dragable: true ,
maskable: true ,
isCancel: false ,
success ( ) {
console. log ( "默认点击确定了!" ) ;
} ,
cancel ( ) {
console. log ( "默认点击取消了" ) ;
} ,
} , options) ;
}
}
let cancel = new Event ( "cancel" ) ;
this . addEventListener ( "cancel" , this . opts. cancel) ;
let success = new Event ( "success" ) ;
this . addEventListener ( "success" , this . opts. success) ;
this . dialogHTML. onclick = e => {
switch ( e. target. className) {
case 'k-close' :
this . close ( ) ;
this . dispatchEvent ( cancel) ;
break ;
case 'k-cancel' :
this . close ( ) ;
this . dispatchEvent ( cancel) ;
break ;
case 'k-primary' :
this . close ( ) ;
this . dispatchEvent ( success) ;
}
}
7. 继承—弹窗增加对话框功能
class ExtendsDialog extends Dialog {
constructor ( options) {
super ( options) ;
this . renderInput ( ) ;
}
renderInput ( ) {
let myInput = document. createElement ( "input" ) ;
myInput. type = "text" ;
myInput. classList. add ( "input-inner" ) ;
this . dialogHTML. querySelector ( ".k-body" ) . appendChild ( myInput) ;
}
}
8. 子类将值传给父类—传递对话框中的内容confirm()
class ExtendsDialog extends Dialog {
constructor ( options) {
super ( options) ;
this . renderInput ( ) ;
}
renderInput ( ) {
let myInput = document. createElement ( "input" ) ;
myInput. type = "text" ;
myInput. classList. add ( "input-inner" ) ;
this . dialogHTML. querySelector ( ".k-body" ) . appendChild ( myInput) ;
}
confirm ( ) {
let value = this . dialogHTML. querySelector ( ".input-inner" ) . value;
super . confirm ( value) ;
}
}
class Dialog extends EventTarget {
constructor ( options) {
super ( ) ;
this . opts = Object. assign ( {
...
success ( ) {
console. log ( "默认点击确定了!" ) ;
} ,
cancel ( ) {
console. log ( "默认点击取消了" ) ;
} ,
} , options) ;
this . init ( ) ;
}
init ( ) {
this . renderView ( ) ;
let cancel = new Event ( "cancel" ) ;
this . addEventListener ( "cancel" , this . opts. cancel) ;
this . addEventListener ( "success" , this . opts. success) ;
this . dialogHTML. onclick = e => {
switch ( e. target. className) {
case 'k-close' :
this . close ( ) ;
this . dispatchEvent ( cancel) ;
break ;
case 'k-cancel' :
this . close ( ) ;
this . dispatchEvent ( cancel) ;
break ;
case 'k-primary' :
this . close ( ) ;
this . confirm ( ) ;
break ;
}
}
}
...
confirm ( value) {
let success = new CustomEvent ( "success" , {
detail: value
} ) ;
this . dispatchEvent ( success) ;
}
}
9. 完整代码
< ! DOCTYPE html>
< html lang= "en" >
< head>
< meta charset= "UTF-8" >
< meta name= "viewport" content= "width=device-width, initial-scale=1.0" >
< meta http- equiv= "X-UA-Compatible" content= "ie=edge" >
< title> Document< / title>
< style>
. k- dialog {
width: 30 % ;
z- index: 2001 ;
display: block;
position: absolute;
background: #fff;
border- radius: 2 px;
box- shadow: 0 1 px 3 px rgba ( 0 , 0 , 0 , .3 ) ;
margin: 0 auto;
top: 15 vh;
left: 30 % ;
display: none;
}
. k- wrapper {
position: fixed;
left: 0 px;
top: 0 px;
bottom: 0 px;
right: 0 px;
background: black;
opacity: 0.4 ;
z- index: 2000 ;
display: none;
}
. k- header {
padding: 20 px 20 px 10 px;
}
. k- header . k- title {
line- height: 24 px;
font- size: 18 px;
color: #303133 ;
float: left;
}
. k- body {
padding: 30 px 20 px;
color: #606266 ;
font- size: 14 px;
}
. k- footer {
padding: 10 px 20 px 30 px;
text- align: right;
}
. k- close {
color: #909399 ;
font- weight: 400 ;
float: right;
cursor: pointer;
}
. k- cancel {
color: #606266 ;
border: 1 px solid #dcdfe6;
text- align: center;
cursor: pointer;
padding: 12 px 20 px;
font- size: 14 px;
border- radius: 4 px;
font- weight: 500 ;
margin- right: 10 px;
}
. k- cancel: hover {
color: #409 eff;
background: #ecf5ff;
border- color: #c6e2ff;
}
. k- primary {
border: 1 px solid #dcdfe6;
text- align: center;
cursor: pointer;
padding: 12 px 20 px;
font- size: 14 px;
border- radius: 4 px;
font- weight: 500 ;
background: #409 eff;
color: #fff;
margin- left: 10 px;
}
. k- primary: hover {
background: #66 b1ff;
}
. k- input {
width: 100 % ;
margin- left: 20 px;
margin- bottom: 20 px;
}
. input- inner {
- webkit- appearance: none;
background- color: #fff;
background- image: none;
border- radius: 4 px;
border: 1 px solid #dcdfe6;
box- sizing: border- box;
color: #606266 ;
display: inline- block;
font- size: inherit;
height: 40 px;
line- height: 40 px;
outline: none;
padding: 0 15 px;
transition: border- color .2 s cubic- bezier ( .645 , .045 , .355 , 1 ) ;
width: 100 % ;
margin- top: 20 px;
}
< / style>
< / head>
< body>
< ! -- < div class = "k-wrapper" > < / div>
< div class = "k-dialog" >
< div class = "k-header" >
< span class = "k-title" > 提示< / span> < span class = "k-close" > X < / span>
< / div>
< div class = "k-body" >
< span> 这是一段文本< / span>
< input class = "input-inner" type= "text" / >
< / div>
< div class = "k-footer" >
< span class = "k-cancel" > 取消< / span>
< span class = "k-primary" > 确定< / span>
< / div>
< / div> -- >
< button class = "dialog1" > 点击< / button>
< button class = "dialog2" > 点击2 < / button>
< / body>
< script>
class Dialog extends EventTarget {
constructor ( options) {
super ( ) ;
this . opts = Object. assign ( {
width: "30%" ,
height: "200px" ,
title: "默认标题" ,
content: "默认内容" ,
dragable: true ,
maskable: true ,
isCancel: false ,
success ( ) {
console. log ( "默认点击确定了!" ) ;
} ,
cancel ( ) {
console. log ( "默认点击取消了" ) ;
} ,
} , options) ;
this . init ( ) ;
}
init ( ) {
this . renderView ( ) ;
let cancel = new Event ( "cancel" ) ;
this . addEventListener ( "cancel" , this . opts. cancel) ;
this . addEventListener ( "success" , this . opts. success) ;
this . dialogHTML. onclick = e => {
switch ( e. target. className) {
case 'k-close' :
this . close ( ) ;
this . dispatchEvent ( cancel) ;
break ;
case 'k-cancel' :
this . close ( ) ;
this . dispatchEvent ( cancel) ;
break ;
case 'k-primary' :
this . close ( ) ;
this . confirm ( ) ;
break ;
}
}
}
renderView ( ) {
this . dialogHTML = document. createElement ( "div" ) ;
this . dialogHTML. innerHTML =
`
<div class="k-wrapper"></div>
<div class="k-dialog" style="width: ${ this . opts. width} ;height: ${ this . opts. height} ">
<div class="k-header">
<span class="k-title"> ${ this . opts. title} </span><span class="k-close">X</span>
</div>
<div class="k-body">
<span> ${ this . opts. content} </span>
</div>
<div class="k-footer">
${ this . opts. isCancel? '<span class="k-cancel">取消</span>' : '' }
<span class="k-primary">确定</span>
</div>
</div>
`
document. querySelector ( "body" ) . appendChild ( this . dialogHTML) ;
}
open ( ) {
if ( this . opts. maskable) {
this . dialogHTML. querySelector ( ".k-wrapper" ) . style. display = "block" ;
}
this . dialogHTML. querySelector ( ".k-dialog" ) . style. display = "block" ;
}
close ( ) {
if ( this . opts. maskable) {
this . dialogHTML. querySelector ( ".k-wrapper" ) . style. display = "none" ;
}
this . dialogHTML. querySelector ( ".k-dialog" ) . style. display = "none" ;
}
confirm ( value) {
let success = new CustomEvent ( "success" , {
detail: value
} ) ;
this . dispatchEvent ( success) ;
}
}
class ExtendsDialog extends Dialog {
constructor ( options) {
super ( options) ;
this . renderInput ( ) ;
}
renderInput ( ) {
let myInput = document. createElement ( "input" ) ;
myInput. type = "text" ;
myInput. classList. add ( "input-inner" ) ;
this . dialogHTML. querySelector ( ".k-body" ) . appendChild ( myInput) ;
}
confirm ( ) {
let value = this . dialogHTML. querySelector ( ".input-inner" ) . value;
super . confirm ( value) ;
}
}
let dialog1 = new Dialog ( {
width: "40%" ,
title: "dialog1测试标题" ,
content: "dialog1测试内容" ,
isCancel: true ,
maskable: false ,
} ) ;
document. querySelector ( ".dialog1" ) . onclick = function ( ) {
dialog1. open ( ) ;
}
let dialog2 = new ExtendsDialog ( {
width: "40%" ,
height: "250px" ,
title: "dialog2测试标题" ,
content: "dialog2测试内容" ,
isCancel: true ,
maskable: false ,
success ( e) {
console. log ( '内容是:' , e. detail) ;
}
} ) ;
document. querySelector ( ".dialog2" ) . onclick = function ( ) {
dialog2. open ( ) ;
}
< / script>
< / html>