83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
import { MountedComponent } from './component'
|
|
|
|
const bindCache = new WeakMap()
|
|
|
|
function getBoundMethod(fn: Function, target: any, receiver: any): Function {
|
|
let boundMethodsForTarget = bindCache.get(target)
|
|
if (boundMethodsForTarget === void 0) {
|
|
bindCache.set(target, (boundMethodsForTarget = new Map()))
|
|
}
|
|
let boundFn = boundMethodsForTarget.get(fn)
|
|
if (boundFn === void 0) {
|
|
boundMethodsForTarget.set(fn, (boundFn = fn.bind(receiver)))
|
|
}
|
|
return boundFn
|
|
}
|
|
|
|
const renderProxyHandlers = {
|
|
get(target: MountedComponent, key: string, receiver: any) {
|
|
if (key === '_self') {
|
|
return target
|
|
} else if (
|
|
target._rawData !== null &&
|
|
target._rawData.hasOwnProperty(key)
|
|
) {
|
|
// data
|
|
return target.$data[key]
|
|
} else if (
|
|
target.$options.props != null &&
|
|
target.$options.props.hasOwnProperty(key)
|
|
) {
|
|
// props are only proxied if declared
|
|
return target.$props[key]
|
|
} else if (
|
|
target._computedGetters !== null &&
|
|
target._computedGetters.hasOwnProperty(key)
|
|
) {
|
|
// computed
|
|
return target._computedGetters[key]()
|
|
} else {
|
|
if (__DEV__ && !(key in target)) {
|
|
// TODO warn non-present property
|
|
}
|
|
const value = Reflect.get(target, key, receiver)
|
|
if (typeof value === 'function') {
|
|
// auto bind
|
|
return getBoundMethod(value, target, receiver)
|
|
} else {
|
|
return value
|
|
}
|
|
}
|
|
},
|
|
set(
|
|
target: MountedComponent,
|
|
key: string,
|
|
value: any,
|
|
receiver: any
|
|
): boolean {
|
|
if (__DEV__) {
|
|
if (typeof key === 'string' && key[0] === '$') {
|
|
// TODO warn setting immutable properties
|
|
return false
|
|
}
|
|
if (
|
|
target.$options.props != null &&
|
|
target.$options.props.hasOwnProperty(key)
|
|
) {
|
|
// TODO warn props are immutable
|
|
return false
|
|
}
|
|
}
|
|
if (target._rawData !== null && target._rawData.hasOwnProperty(key)) {
|
|
target.$data[key] = value
|
|
return true
|
|
} else {
|
|
return Reflect.set(target, key, value, receiver)
|
|
}
|
|
}
|
|
}
|
|
|
|
export function createRenderProxy(instance: any): MountedComponent {
|
|
return new Proxy(instance, renderProxyHandlers) as MountedComponent
|
|
}
|