/*
调用示例
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>