Skip to content

React实现双向数据绑定 #20

@Wscats

Description

@Wscats

利用Proxy对数据进行劫持,自动触发this.setState

import { define, WeElement, html, h, extend, get, set } from "omi"; export interface appOptions { name: string; view(props?: any, state?: any, ref?: any); state?: any; propTypes?: any; props?: any; defaultProps?: any; css?: string; install?(props?: any, state?: any, ref?: any); installed?(props?: any, state?: any, ref?: any); uninstall?(props?: any, state?: any, ref?: any); beforeUpdate?(props?: any, state?: any, ref?: any); updated?(props?: any, state?: any, ref?: any); beforeRender?(props?: any, state?: any, ref?: any); receiveProps?(props?: any, state?: any, ref?: any); } // Added code const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]'; // Added code const observify = (obj, that) => { if (!isObject(obj)) { return obj; } Object.keys(obj).forEach(key => { obj[key] = observify(obj[key], that); }); return Observer(obj, that); } // Added code const Observer = (obj, that) => { return new Proxy(obj, { set(obj, prop, value) { const res = Reflect.set(obj, prop, value); that.update(); return res; } }); } const app = ({ name, view, state, propTypes, props, defaultProps, css, install, installed, uninstall, beforeUpdate, updated, beforeRender, receiveProps }: appOptions) => { define(name, class extends WeElement { state = Object.assign({}, state); static props = props; static propTypes = propTypes; static defaultProps = defaultProps; static css = css; private ref; constructor() { super(); (that => { // Added code that.state = observify(that.state, that) })(this); } install() { install && install( this.props ? this.props : {}, this.state ? this.state : {}, this ); } installed() { installed && installed( this.props ? this.props : {}, this.state ? this.state : {}, this ); } uninstall() { uninstall && uninstall( this.props ? this.props : {}, this.state ? this.state : {}, this ); } render(oProps, oState) { return view( this.props ? this.props : oProps, this.state ? this.state : oState, this ); } }); }; extend("model", (el: any, path, scope) => { el.value = get(scope, path); el.addEventListener("input", () => { set(scope, path, el.value); scope.update(); }); }); export { html, h, app };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions