Hanks
7 years ago
committed by
Evan You
13 changed files with 430 additions and 10 deletions
@ -1,6 +1,90 @@ |
|||
// import {
|
|||
// // id, 'lifecycle', hookname, fn
|
|||
// // https://github.com/Hanks10100/weex-native-directive/tree/master/component
|
|||
// registerComponentHook,
|
|||
// updateComponentData
|
|||
// } from '../util/index'
|
|||
/* @flow */ |
|||
|
|||
// https://github.com/Hanks10100/weex-native-directive/tree/master/component
|
|||
|
|||
import { mergeOptions } from 'core/util/index' |
|||
import { initProxy } from 'core/instance/proxy' |
|||
import { initState } from 'core/instance/state' |
|||
import { initRender } from 'core/instance/render' |
|||
import { initEvents } from 'core/instance/events' |
|||
import { initProvide, initInjections } from 'core/instance/inject' |
|||
import { initLifecycle, mountComponent, callHook } from 'core/instance/lifecycle' |
|||
import { initInternalComponent, resolveConstructorOptions } from 'core/instance/init' |
|||
import { registerComponentHook, updateComponentData } from '../../util/index' |
|||
|
|||
let uid = 0 |
|||
|
|||
// override Vue.prototype._init
|
|||
function initVirtualComponent (options: Object = {}) { |
|||
const vm: Component = this |
|||
const componentId = options.componentId |
|||
|
|||
// virtual component uid
|
|||
vm._uid = `virtual-component-${uid++}` |
|||
|
|||
// a flag to avoid this being observed
|
|||
vm._isVue = true |
|||
// merge options
|
|||
if (options && options._isComponent) { |
|||
// optimize internal component instantiation
|
|||
// since dynamic options merging is pretty slow, and none of the
|
|||
// internal component options needs special treatment.
|
|||
initInternalComponent(vm, options) |
|||
} else { |
|||
vm.$options = mergeOptions( |
|||
resolveConstructorOptions(vm.constructor), |
|||
options || {}, |
|||
vm |
|||
) |
|||
} |
|||
|
|||
/* istanbul ignore else */ |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
initProxy(vm) |
|||
} else { |
|||
vm._renderProxy = vm |
|||
} |
|||
|
|||
vm._self = vm |
|||
initLifecycle(vm) |
|||
initEvents(vm) |
|||
initRender(vm) |
|||
callHook(vm, 'beforeCreate') |
|||
initInjections(vm) // resolve injections before data/props
|
|||
initState(vm) |
|||
initProvide(vm) // resolve provide after data/props
|
|||
callHook(vm, 'created') |
|||
|
|||
registerComponentHook(componentId, 'lifecycle', 'attach', () => { |
|||
mountComponent(vm) |
|||
}) |
|||
|
|||
registerComponentHook(componentId, 'lifecycle', 'detach', () => { |
|||
vm.$destroy() |
|||
}) |
|||
} |
|||
|
|||
// override Vue.prototype._update
|
|||
function updateVirtualComponent (vnode: VNode, hydrating?: boolean) { |
|||
// TODO
|
|||
updateComponentData(this.$options.componentId, {}) |
|||
} |
|||
|
|||
// listening on native callback
|
|||
export function resolveVirtualComponent (vnode: MountedComponentVNode): VNode { |
|||
const BaseCtor = vnode.componentOptions.Ctor |
|||
const VirtualComponent = BaseCtor.extend({}) |
|||
VirtualComponent.prototype._init = initVirtualComponent |
|||
VirtualComponent.prototype._update = updateVirtualComponent |
|||
|
|||
vnode.componentOptions.Ctor = BaseCtor.extend({ |
|||
beforeCreate () { |
|||
registerComponentHook(VirtualComponent.cid, 'lifecycle', 'create', componentId => { |
|||
// create virtual component
|
|||
const options = { componentId } |
|||
return new VirtualComponent(options) |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
|
@ -0,0 +1,31 @@ |
|||
<template recyclable="true"> |
|||
<div> |
|||
<text class="output">{{output}}</text> |
|||
<input class="input" type="text" v-model="output" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
module.exports = { |
|||
props: ['message'], |
|||
data () { |
|||
return { |
|||
output: this.message | '' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.output { |
|||
height: 80px; |
|||
font-size: 60px; |
|||
color: #41B883; |
|||
} |
|||
.input { |
|||
font-size: 50px; |
|||
color: #666666; |
|||
border-width: 2px; |
|||
border-color: #41B883; |
|||
} |
|||
</style> |
@ -0,0 +1,18 @@ |
|||
<template recyclable="true"> |
|||
<div class="footer"> |
|||
<text class="copyright">All rights reserved.</text> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.footer { |
|||
height: 80px; |
|||
justify-content: center; |
|||
background-color: #EEEEEE; |
|||
} |
|||
.copyright { |
|||
color: #AAAAAA; |
|||
font-size: 32px; |
|||
text-align: center; |
|||
} |
|||
</style> |
@ -0,0 +1,48 @@ |
|||
({ |
|||
type: 'recycle-list', |
|||
attr: { |
|||
listData: [ |
|||
{ type: 'A' }, |
|||
{ type: 'A' } |
|||
], |
|||
templateKey: 'type', |
|||
alias: 'item' |
|||
}, |
|||
children: [{ |
|||
type: 'cell-slot', |
|||
attr: { templateType: 'A' }, |
|||
children: [{ |
|||
type: 'div', |
|||
attr: { |
|||
'@isComponentRoot': true, |
|||
'@componentProps': { |
|||
message: 'No binding' |
|||
} |
|||
}, |
|||
children: [{ |
|||
type: 'text', |
|||
style: { |
|||
height: '80px', |
|||
fontSize: '60px', |
|||
color: '#41B883' |
|||
}, |
|||
attr: { |
|||
value: { '@binding': 'output' } |
|||
} |
|||
}, { |
|||
type: 'input', |
|||
event: ['input'], |
|||
style: { |
|||
fontSize: '50px', |
|||
color: '#666666', |
|||
borderWidth: '2px', |
|||
borderColor: '#41B883' |
|||
}, |
|||
attr: { |
|||
type: 'text', |
|||
value: 0 |
|||
} |
|||
}] |
|||
}] |
|||
}] |
|||
}) |
@ -0,0 +1,21 @@ |
|||
<template> |
|||
<recycle-list :list-data="longList" template-key="type" alias="item"> |
|||
<cell-slot template-type="A"> |
|||
<editor message="No binding"></editor> |
|||
</cell-slot> |
|||
</recycle-list> |
|||
</template> |
|||
|
|||
<script> |
|||
// require('./editor.vue') |
|||
module.exports = { |
|||
data () { |
|||
return { |
|||
longList: [ |
|||
{ type: 'A' }, |
|||
{ type: 'A' } |
|||
] |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,100 @@ |
|||
({ |
|||
type: 'recycle-list', |
|||
attr: { |
|||
listData: [ |
|||
{ type: 'A' }, |
|||
{ type: 'B', poster: 'yy', title: 'y' }, |
|||
{ type: 'A' } |
|||
], |
|||
templateKey: 'type', |
|||
alias: 'item' |
|||
}, |
|||
children: [{ |
|||
type: 'cell-slot', |
|||
attr: { templateType: 'A' }, |
|||
children: [{ |
|||
type: 'div', |
|||
attr: { |
|||
'@isComponentRoot': true, |
|||
'@componentProps': {} |
|||
}, |
|||
// style: {
|
|||
// height: '120px',
|
|||
// justifyContent: 'center',
|
|||
// alignItems: 'center',
|
|||
// backgroundColor: 'rgb(162, 217, 192)'
|
|||
// },
|
|||
children: [{ |
|||
type: 'text', |
|||
// style: {
|
|||
// fontWeight: 'bold',
|
|||
// color: '#41B883',
|
|||
// fontSize: '60px'
|
|||
// },
|
|||
attr: { value: 'BANNER' } |
|||
}] |
|||
}, { |
|||
type: 'text', |
|||
attr: { value: '----' } |
|||
}, { |
|||
type: 'div', |
|||
attr: { |
|||
'@isComponentRoot': true, |
|||
'@componentProps': {} |
|||
}, |
|||
style: { height: '80px', justifyContent: 'center', backgroundColor: '#EEEEEE' }, |
|||
children: [{ |
|||
type: 'text', |
|||
style: { color: '#AAAAAA', fontSize: '32px', textAlign: 'center' }, |
|||
attr: { value: 'All rights reserved.' } |
|||
}] |
|||
}] |
|||
}, { |
|||
type: 'cell-slot', |
|||
attr: { templateType: 'B' }, |
|||
children: [{ |
|||
type: 'div', |
|||
attr: { |
|||
'@isComponentRoot': true, |
|||
'@componentProps': {} |
|||
}, |
|||
// style: {
|
|||
// height: '120px',
|
|||
// justifyContent: 'center',
|
|||
// alignItems: 'center',
|
|||
// backgroundColor: 'rgb(162, 217, 192)'
|
|||
// },
|
|||
children: [{ |
|||
type: 'text', |
|||
// style: {
|
|||
// fontWeight: 'bold',
|
|||
// color: '#41B883',
|
|||
// fontSize: '60px'
|
|||
// },
|
|||
attr: { value: 'BANNER' } |
|||
}] |
|||
}, { |
|||
type: 'div', |
|||
attr: { |
|||
'@isComponentRoot': true, |
|||
'@componentProps': { |
|||
imageUrl: { '@binding': 'item.poster' }, |
|||
title: { '@binding': 'item.title' } |
|||
} |
|||
}, |
|||
children: [{ |
|||
type: 'image', |
|||
style: { width: '750px', height: '1000px' }, |
|||
attr: { |
|||
src: { '@binding': 'imageUrl' } |
|||
} |
|||
}, { |
|||
type: 'text', |
|||
style: { fontSize: '80px', textAlign: 'center', color: '#E95659' }, |
|||
attr: { |
|||
value: { '@binding': 'title' } |
|||
} |
|||
}] |
|||
}] |
|||
}] |
|||
}) |
@ -0,0 +1,30 @@ |
|||
<template> |
|||
<recycle-list :list-data="longList" template-key="type" alias="item"> |
|||
<cell-slot template-type="A"> |
|||
<banner></banner> |
|||
<text>----</text> |
|||
<footer></footer> |
|||
</cell-slot> |
|||
<cell-slot template-type="B"> |
|||
<banner></banner> |
|||
<poster :image-url="item.poster" :title="item.title"></poster> |
|||
</cell-slot> |
|||
</recycle-list> |
|||
</template> |
|||
|
|||
<script> |
|||
// require('./banner.vue') |
|||
// require('./footer.vue') |
|||
// require('./poster.vue') |
|||
module.exports = { |
|||
data () { |
|||
return { |
|||
longList: [ |
|||
{ type: 'A' }, |
|||
{ type: 'B', poster: 'yy', title: 'y' }, |
|||
{ type: 'A' } |
|||
] |
|||
} |
|||
} |
|||
} |
|||
</script> |
Loading…
Reference in new issue