在我们日常中肯呢个会将一个表单用这种模式来创建
- const Car = function () { }
- Car.prototype.getName = function () {
- throw new Error("需要重写该方法")
- }
- Car.prototype.getPrice = function () {
- throw new Error("需要重写该方法")
- }
- const Benz = function () { }
- // 继承Car
- Benz.prototype = new Car()
- // 重写getName方法
- Benz.prototype.getName = function () {
- return 'Benz'
- }
- const b = new Benz()
- console.log(b.getName()) // Benz
- console.log(b.getPrice()) // 需要重写该方法
先写一个基类,再继承该基类
- const Benz = function (name, price) {
- Car.call(this)
- this.name = name
- this.price = price
- }
- Benz.prototype = new Car
- Benz.prototype.getPrice = function () {
- return this.price
- }
- Benz.prototype.getName = function () {
- return this.name
- }
- const benz = new Benz('奔驰', 50)
- console.log(benz.getName()) // 输出:奔驰
- console.log(benz.getPrice()) // 输出:50
- const bmw = new Benz('宝马', 100)
- console.log(bmw.getPrice()) // 输出:100
首先我们创建一个基类
-
- const Base = function () {
- this.children = []
- this.element = null
- }
- Base.prototype = {
- init: function () {
- throw new Error('必须重写该方法')
- },
- add: function () {
- throw new Error('必须重写该方法')
- },
- remove: function () {
- throw new Error('必须重写该方法')
- },
- get: function () {
- throw new Error('必须重写该方法')
- }
- }
接下来创建一个容器
-
- const FormItem = function (id,parent) {
- Base.call(this)
- this.id = id
- this.parent = parent
- this.init()
- }
- FormItem.prototype = new Base()
- FormItem.prototype.init = function () {
- this.element = document.querySelector('#form')
- this.element.id = this.id
- }
- FormItem.prototype.add = function (child) {
- this.children.push(child)
- this.element.appendChild(child.getDom())
- return this
- }
- FormItem.prototype.getDom = function () {
- return this.element
- }
- FormItem.prototype.show = function () {
- this.parent.appendChild(this. Element)
- }
注意,这里的 show 方法就是用来将所有的 dom 追加到页面上
下面创建一系列的 form 相关 item 及一些dom
-
- const FieldsetItem = function (selector, label) {
- Base.call(this)
- this.selector = selector
- this.label = label
- this.init()
- }
- FieldsetItem.prototype = new Base()
- FieldsetItem.prototype.init = function () {
- this.element = document.createElement('fieldset')
- const legend = document.createElement('legend')
- legend.innerHTML = this.label
- this.element.appendChild(legend)
- }
- FieldsetItem.prototype.add = function (child) {
- this.children.push(child)
- this.element.appendChild(child.getDom())
- return this
- }
- FieldsetItem.prototype.getDom = function () {
- return this. Element
- }
-
-
- const Group = function () {
- Base.call(this)
- this.init()
- }
- Group.prototype = new Base()
- Group.prototype.init = function () {
- this.element = document.createElement('div')
- this.element.className = 'group'
- }
- Group.prototype.add = function (child) {
- this.children.push(child)
- this.element.appendChild(child.getDom())
- return this
- }
- Group.prototype.getDom = function () {
- return this.element
- }
-
- const LabelItem = function (name, label) {
- Base.call(this)
- this.name = name
- this.label = label
- this.init()
- }
- LabelItem.prototype = new Base()
- LabelItem.prototype.init = function () {
- this.element = document.createElement('label')
- this.element.innerHTML = this.label
- this.element.htmlFor = this.name
- }
- LabelItem.prototype.add = function (child) {
- // 这里不需要添加,因为label后面直接跟输入框
- return this
- }
- LabelItem.prototype.getDom = function () {
- return this.element
- }
-
- const InputItem = function (name) {
- Base.call(this)
- this.name = name
- this.init()
- }
- InputItem.prototype = new Base()
- InputItem.prototype.init = function () {
- this.element = document.createElement('input')
- this.element.name = this.name
- this.element.style.marginLeft = '5px'
- }
- InputItem.prototype.add = function (child) {
- // 这里不需要添加,因为输入框后面直接跟标签
- return this
- }
- InputItem.prototype.getDom = function () {
- return this.element
- }
-
- const CheckboxItem = function (name, value, label) {
- Base.call(this)
- this.name = name
- this.value = value
- this.label = label
- this.init()
- }
- CheckboxItem.prototype = new Base()
- CheckboxItem.prototype.init = function () {
- const span = document.createElement('span')
- this.element = document.createElement('label')
- const input = document.createElement('input')
- input.type = 'checkbox'
- span.innerHTML = this.label
- input.value = this.value
- input.style.marginRight = '5px'
- this.element.appendChild(input)
- this.element.appendChild(span)
- }
- CheckboxItem.prototype.add = function (child) {
- }
- CheckboxItem.prototype.getDom = function () {
- return this.element
- }
-
- const SpanItem = function (name) {
- Base.call(this)
- this.name = name
- this.init()
- }
- SpanItem.prototype = new Base()
- SpanItem.prototype.init = function () {
- this.element = document.createElement('span')
- this.element.innerHTML = this.name
- this.element.style.marginLeft = '5px'
- }
- SpanItem.prototype.add = function (child) {
- // 这里不需要添加,因为span前面直接跟输入框
- return this
- }
- SpanItem.prototype.getDom = function () {
- return this. Element
- }
假使页面中存在 dom
- <form id="form">form>
- <div id="content">div>
js
- var form = new FormItem('form', document.querySelector('#content'))
- form.add(new FieldsetItem('account', '账号').add(
- new Group().add(
- new LabelItem('user_name', '用户名:')
- ).add(
- new InputItem('user_name')
- ).add(new SpanItem('4 到 6 位数字或字母'))
- ).add(
- new Group().add(
- new LabelItem('user_pwd', '密 码:')
- ).add(
- new InputItem('user_pwd')
- ).add(new SpanItem('6 到 12 位数字或字母'))
- ).add(
- new Group().add(
- new CheckboxItem('remember', true, '是否记住')
- )
- ))
- .show()
效果
组合模式能够给我们提供一个清晰的组成结构。组合对象类通过继承同一个父类使其具有统一的方法,这样也方便了我们统一管理与使用,当然此时单体成员与组合体成员行为表现就比较一致了,这也模糊了简单对象与组合对象的区别