五、组合模式
组合模式作用于将多个部分通过组合变成一个整体。就如同我们去麦当劳点了一个汉堡、两个薯条和一杯可乐。我们可以将这些东西看成一个个部分或者说组件,通过组合就可以将整个套餐产出给顾客。这个就是组合模式
1、组合模式例子
比如我们在工作中经常会制作一些表单,比如登录、注册,或者一些信息填写等等,这些表单其实都是类似的,如果你今天制作一个注册的表单,明天做个调查问卷的表单,是不是你会觉得麻烦,有些重复劳动的感觉。学会组合模式就会好很多了
注:组合模式属于那种,代码量越大,重复需求越大(就是那种两个页面之间只有小部分代码不一致,但是又不能用组件化的代码的那种需求),效率就越高。如果只是小容量的系统,基本不需要使用组合模式来创建表单。
代码语言:javascript复制<!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>
<script>
window.onload = function() {
// 组合寄生继承
function inheritPrototype(subClass, superClass) {
function F() {};
F.prototype = superClass.prototype
subClass.prototype = new F()
subClass.prototype.constructor = subClass
}
// 容器基类
function Container() {
this.children = []
this.element = null
}
Container.prototype = {
init: () => {
throw new Error('请重写init方法')
},
add: function(child){
this.children.push(child);
this.element.appendChild(child.element)
return this // 方便链式调用
}
}
// 基于容器基类创建表单容器
function CreateForm(id, method, action, parent) {
Container.call(this)
this.id = id || ''
this.method = method || ''
this.action = action || ''
this.parent = parent || ''
this.init()
}
inheritPrototype(CreateForm, Container);
CreateForm.prototype.init = function() {
this.element = document.createElement('form')
this.element.id = this.id
this.element.method = this.method
this.element.action = this.action
}
CreateForm.prototype.show = function() {
this.parent.appendChild(this.element)
}
// 行容器组件
function CreateLine(className) {
Container.call(this)
this.className = className === undefined ? 'form-line' : 'form-line' className
this.init()
}
inheritPrototype(CreateLine, Container);
CreateLine.prototype.init = function() {
this.element = document.createElement('div')
this.element.className = this.className
}
// label // 最下层叶子节点不需要继承容器基类的方法
function CreateLabel(text, forName) {
this.text = text || ''
this.forName = forName || ''
this.init()
}
CreateLabel.prototype.init = function() {
this.element = document.createElement('label')
this.element.setAttribute('for', this.forName)
this.element.innerHTML = this.text
}
// input
function CreateInput(type, id, name, defaultValue) {
this.type = type || ''
this.id = id || '';
this.name = name || '';
this.defaultValue = defaultValue || '';
this.init()
}
CreateInput.prototype.init = function() {
this.element = document.createElement('input')
this.element.type = this.type
this.element.id = this.id
this.element.name = this.name
this.element.value = this.defaultValue
}
var form = new CreateForm('owner-form', 'GET', '/aaa.html', document.body);
var userLine = new CreateLine()
.add( new CreateLabel('用户名', 'user') )
.add( new CreateInput('text', 'user', 'user'))
var passwordLine = new CreateLine()
.add( new CreateLabel('密码', 'pwd') )
.add( new CreateInput('password', 'pwd', 'pwd'))
var submitLine = new CreateLine()
.add( new CreateLabel('submit', '', '', '登录') )
form.add(userLine).add(passwordLine).add(submitLine).show()
}
// var aa = new Container()
</script>
</head>
<body>
<!-- 普通方式实现表单 -->
<!-- <form action="xxx" method="GET">
<div class = 'form-line'>
<label for="user">用户名</label>
<input type="text" id = "user" name ="user"/>
</div>
<div class = 'form-line'>
<label for="pwd">用户名</label>
<input type="password" id = "pwd" name ="pwd"/>
</div>
<div class = 'form-line'>
<input type="submit" value="登录"/>
</div>
</form>
-->
</body>
</html>