js原生模仿Polymer2.0属性监测

13 篇文章 0 订阅
/* 
    调用示例

class Polymer extends Base {
 
    static get properties() {
        return {
            age: {
                type: Number,
                value: 18
            },
            test: {
                type: Object,
                value: { N: 1 }
            }
        }
    }

    static get observers() {
        return [
            'nameChanged(name)',
            'ageChanged(age)'
        ]
    }

    nameChanged(name) {
        console.log(this.proxy.nameChanged)
    }

}
let p = new Polymer();
p.proxy.name = 2;


*/

class Base {
	constructor() {
		this.observers = this.getObservers(this.constructor.observers);
		this.proxy = this.proxy();
	}

	isArray(it) {
		return Object.prototype.toString.call(it) === '[object Array]';
	}

	isObject(it) {
		return Object.prototype.toString.call(it) === '[object Object]';
	}

	looseEqual(a, b) {
		if (a === b) { return true }
		var isObjectA = isObject(a);
		var isObjectB = isObject(b);
		if (isObjectA && isObjectB) {
			try {
				var isArrayA = Array.isArray(a);
				var isArrayB = Array.isArray(b);
				if (isArrayA && isArrayB) {
					return a.length === b.length && a.every(function (e, i) {
						return looseEqual(e, b[i])
					})
				} else if (a instanceof Date && b instanceof Date) {
					return a.getTime() === b.getTime()
				} else if (!isArrayA && !isArrayB) {
					var keysA = Object.keys(a);
					var keysB = Object.keys(b);
					return keysA.length === keysB.length && keysA.every(function (key) {
						return looseEqual(a[key], b[key])
					})
				} else {
					/* istanbul ignore next */
					return false
				}
			} catch (e) {
				/* istanbul ignore next */
				return false
			}
		} else if (!isObjectA && !isObjectB) {
			return String(a) === String(b)
		} else {
			return false
		}
	}
	getProperties() {
		return this.constructor.properties;
	}
	getObservers(observers) {
		let props = this.getProperties;
		let observersList1 = [];
		let observersList2 = [];
		if (observers) {
			for (let i of observers) {
				let fn = i.split('(')[0];
				let prop = i.split('(')[1].split(')')[0];
				observersList1.push({ prop, fn });
			}
			for (let prop in props) {
				if ('observer' in props[prop]) {
					observersList2.push({ prop, fn: props[prop].observer });
				}
			}
		}
		return observersList1.concat(observersList2);
	}


	proxy() {
		Object.assign(this, this.constructor.properties)
		let handler = {
			get(target, key) {
				let v = target[key]
				return (v ? (v.value ? v.value : v) : undefined);
			},
			set(target, key, value, reciever) {
				let o = target.observers;
				for (let i = 0; i < o.length; i++) {
					if (o[i].prop === key) {
						if (Reflect.has(target, o[i].fn)) {
							target[o[i].fn](value);
						} else {
							console.log(target[o[i].fn] + 'is not defined!\n"refresh" function is called')
						}
						break;
					}
				}

				return Reflect.set(target, key, value, reciever);
			}

		}

		return new Proxy(this, handler);
	}

}

export { Base }
<!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>
</head>

<body>

    <my-div></my-div>
</body>
<script type="module">
    import { Base } from './ES6/Base.js'

    class Polymer extends Base {
        constructor(){
            super()
            setInterval(() => { this.proxy.age++ }, 1000)

        }
        static get properties() {
            return {
                age: {
                    type: Number,
                    value: 18
                }
            }
        }

        static get observers() {
            return [
                'nameChanged(name)',
                'ageChanged(age)'
            ]
        }
        nameChanged(name) {
            console.log(this.proxy.nameChanged)
        }
        ageChanged(age) {
            this.div.innerText = age;
        }

    }
    let p = new Polymer();

    

    class MyDiv extends Base.copyProperties(HTMLElement, p) {
        constructor() {
            super();

            p.div = document.createElement('div');
            p.div.innerText = 20;

            this.attachShadow({ mode: 'open' }).appendChild(p.div);
        }
        static get is() {
            return 'my-div'
        }


    }

    customElements.define(MyDiv.is, MyDiv)


</script>

</html>

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值