SOURCE

console 命令行工具 X clear

                    
>
console
Yox.component("Size", {
    template: `
    <div>
        width: <InputNumber on-change="onWidthChange" size="small" width="60" value="{{box.prop.style.width}}" />   
        height: <InputNumber on-change="onHeightChange" size="small" width="60" value="{{box.prop.style.height}}" />
    </div>
    `,
     events: {
        onWidthChange(event, data) {
			event.stop();
			this.apply("width", data.value);
		},
		onHeightChange(event, data) {
			event.stop();
            
			this.apply("height", data.value);
		}
    },
    methods: {
		apply(prop, value) {
            var style =  {};
            style[prop] = value;
            
            this.$fire("onPropChange", style);
		}
	}
});

Yox.component("Position", {
    template: `
    <div>
        top: <InputNumber on-change="onTopChange" size="small" width="60" value="{{box.prop.style.top}}" />   
        left: <InputNumber on-change="onLeftChange" size="small" width="60" value="{{box.prop.style.left}}" />
    </div>`,
     events: {
        onLeftChange(event, data) {
			event.stop();
			this.apply("left", data.value);
		},
		onTopChange(event, data) {
			event.stop();
			this.apply("top", data.value);
		}
    },
    methods: {
		apply(prop, value) {
            var style =  {};
            style[prop] = value;
            this.$fire("onPropChange", style);
		}
	}
});

Yox.component("Lock", {
    template: `
    <div>
        lock:  <Switch checked="{{box.prop.style.lock.checked}}" on-change="onChange"></Switch>
    </div>`,
     events: {
        onChange(event, data) {
			event.stop();
			this.apply("lock", data);
		} 
    },
    methods: {
		apply(prop, value) {
            var style =  {};
            style[prop] = value;
            this.$fire("onPropChange", style);
		}
	}
});

Yox.component("SelectComp", {
    template: `
    <div>
        SelectComp:  
        <Select value="{{box.prop.style.select.value}}" on-change="onChange">
            <Option text="okay" value="1">okay</Option>
            <Option text="bad" value="2">bad</Option>
        </Select>
    </div>`,
     events: {
        onChange(event, data) {
			event.stop();
			this.apply("select", data);
		} 
    },
    methods: {
		apply(prop, value) {
            var style =  {};
            style[prop] = value;
            this.$fire("onPropChange", style);
		}
	}
});


Yox.component("InputComp", {
    template: `
    <div>
        InputComp:  
        <InputNumber on-change="onWidthChange" size="small" width="60" value="{{box.prop.style.width}}" />
    </div>`,
     events: {
        onChange(event, data) {
			event.stop();
			this.apply("select", data);
		} 
    },
    methods: {
		apply(prop, value) {
            var style =  {};
            style[prop] = value;
            this.$fire("onPropChange", style);
		}
	}
});
 
Yox.component("DynamicInputComp", {
    template: `
    <div>
        InputComp:  
        <InputNumber on-change="DynamicInputComp" size="small" width="60" value="{{value}}" />
    </div>`,
     events: {
        onChange(event, data) {
			event.stop();
			this.apply(this.get("name"), data);
		} 
    },
    methods: {
		apply(prop, value) {
            var style =  {};
            style[prop] = value;
            this.$fire("onPropChange", style);
		}
	}
});

 Yox.component("Prop", {
     template: `
        <$component box="{{box}}" /> 
     `
 });


Yox.component("Box", {
    propTypes: {
        index: {
            type: "number"
        },
        fields:  {
            type: "array"
        },
    },
    computed: {
        props1(){
            var props = [];
            _.each(this.get("fields"), function(field){
                props.push({component: field});       
            });
            return props;
        }
    },

    data(){

        return {

            componentSize: "Size",

            props: [
                {
                    component: "Size"
                }
            ] 
        }

    },

    template: `
    <Card style="  margin-top: 10px">
        <CardBody>
        
            {{index}}

            <div class="bad">
                {{JSON_stringify(props)}}
                直接$不行
                {{#each props1:key}} 
                    {{this.component}}-{{this}}-
                    <$component />
                {{/each}} 
            </div>

             <div class="ok">
                用一个组件去接component,可以
                {{#each props1:key}} 
                    <Prop component="{{component}}" box="{{box}}"  />
                {{/each}} 
            </div>

        </CardBody>
    </Card>
    `,
    events: {
         
    },
    afterMount(){

        console.log(JSON.stringify(this.get("")))

    }
});

let bus = new Yox();

Yox.prototype.$on = bus.on;
Yox.prototype.$off = bus.off;
Yox.prototype.$fire = bus.fire;

Yox.filter("JSON_stringify", JSON.stringify);

let app = new Yox({
    el: "#app",
    template: `

    <Layout vertical className="layout-demo">
   
      <Layout className="layout-demo">
        <LayoutSider width="220">
           

            <div style="padding: 10px">
                <h3 style="color: #fff">{{version}}</h3>

                {{#each list:index}}

                    <Card shadow="hover" width="200" style="margin-bottom: 10px; {{#if index === current}}background: #9de1fff7;{{/if}}">
                        <CardBody  style="padding: 0 10px 10px;">
                            <p style="word-break: break-word;">
                               {{index}}: {{JSON_stringify(this.prop.style)}}
                            </p>
                            <Button size="small" on-click="doSelectBox($event, index)">Select</Button>
                        </CardBody>
                    </Card>
                    
                {{/each}}
            </div>
        </LayoutSider>


        <LayoutContent>
          <div style="padding: 10px">
                <div>Now selected box:  {{current}}</div>
                
                <Box index="{{current}}" fields="{{list[current].fields}}" box="{{list[current]}}" />
            </div>
        </LayoutContent>
      </Layout>
 
    </Layout>
    `,
 
    data(){

        return {

            version: Yox.version,

            current: 0,

            list: [

                {
                    fields: ["Size", "Lock", "SelectComp"],
                    prop: {
                        style: {
                                width: 100,
                                height: 200,
                                lock: {
                                    checked: true
                                },
                                select: {
                                    value: "2"
                                }
                            }
                    }
                },
                {
                    fields: ["Size", "Position"],
                    prop: {
                        style: {
                                top: 50,
                                left: 80,
                                width: 100,
                                height: 200 
                            }
                    }
                },
                {
                    fields: ["Size",  "Position", "Lock"],
                    prop: {
                        style: {
                                top: 50,
                                left: 80,
                                width: 100,
                                height: 200,
                                lock: {
                                    checked: true 
                                }
                            }
                    }
                },


            ]
        }
    },

    events: {
         
    },

    methods: {

        doSelectBox(event, index){
             this.set("current", index)
         }
       
    },

    afterMount(){

        let me = this;

        var throttleSet = _.throttle(function(index, item) {
                console.log("throttle");
                me.set(`list.${index}`, item);
            }, 500, {
                leading: false,
                trailing: true
            });

        this.$on("onPropChange", (event, data)=>{

            event.stop();
           
            console.log(event, JSON.stringify(data))

            var index = me.get("current")

            var item = me.copy(me.get(`list.${index}`), true);

            console.log(`before ${JSON.stringify(item)}`)
            
       
    

            if(typeof data === "object") {
                for(let key in data){
                    item.prop.style[key] = data[key];
                }
            }
            
            console.log(`after ${JSON.stringify(item)}`)
            
            // item.a.b.c.value = data.checked;

            // 直接set 会有问题,需要节流
            throttleSet(index, item);
            

         });

    }


});
<div id="app"></div>
<link rel="stylesheet" href="//unpkg.com/bell-ui@0.12.0/dist/bell-ui.css">
<script src="//unpkg.com/yox@1.0.0-alpha.121/dist/standard/dev/yox.js"></script>
<script src="//unpkg.com/bell-ui@0.12.0/dist/bell-ui.js"></script>

<script src="//unpkg.com/lodash@4.17.15/lodash.js"></script>
 
.ok {
    background: greenyellow
}

.bad {
    background: pink
}