Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromvuejs/vue

Commit661bfe5

Browse files
Hanks10100yyx990803
authored andcommitted
feat(weex): partially support lifecycles of virtual component (vuejs#7242)
Update the `_init` and `_update` logic to partially support lifecycles.Add test cases for testing the lifecycle hooks and data update.
1 parentd544d05 commit661bfe5

File tree

13 files changed

+229
-37
lines changed

13 files changed

+229
-37
lines changed

‎flow/component.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ declare interface Component {
7070
_hasHookEvent: boolean;
7171
_provided: ?Object;
7272
_inlineComputed: ?{[key:string]:Watcher}; // inline computed watchers for literal props
73+
// _virtualComponents?:{[key:string]:Component};
7374

7475
// private methods
7576

‎flow/options.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ declare type InternalComponentOptions = {
1111
typeInjectKey=string|Symbol;
1212

1313
declaretypeComponentOptions={
14+
componentId?:string;
15+
1416
// data
1517
data:Object|Function|void;
1618
props?:{[key:string]:PropOptions};

‎package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
"typescript":"^2.6.1",
126126
"uglify-js":"^3.0.15",
127127
"webpack":"^3.10.0",
128-
"weex-js-runtime":"^0.23.3",
128+
"weex-js-runtime":"^0.23.5",
129129
"weex-styler":"^0.3.0"
130130
},
131131
"config": {

‎src/core/instance/state.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ function initData (vm: Component) {
150150
observe(data,true/* asRootData */)
151151
}
152152

153-
functiongetData(data:Function,vm:Component):any{
153+
exportfunctiongetData(data:Function,vm:Component):any{
154154
try{
155155
returndata.call(vm,vm)
156156
}catch(e){

‎src/platforms/weex/runtime/recycle-list/virtual-component.js

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
// https://github.com/Hanks10100/weex-native-directive/tree/master/component
44

5-
import{mergeOptions}from'core/util/index'
5+
import{mergeOptions,isPlainObject,noop}from'core/util/index'
6+
importWatcherfrom'core/observer/watcher'
67
import{initProxy}from'core/instance/proxy'
7-
import{initState}from'core/instance/state'
8+
import{initState,getData}from'core/instance/state'
89
import{initRender}from'core/instance/render'
910
import{initEvents}from'core/instance/events'
1011
import{initProvide,initInjections}from'core/instance/inject'
11-
import{initLifecycle,mountComponent,callHook}from'core/instance/lifecycle'
12+
import{initLifecycle,callHook}from'core/instance/lifecycle'
1213
import{initInternalComponent,resolveConstructorOptions}from'core/instance/init'
1314
import{registerComponentHook,updateComponentData}from'../../util/index'
1415

@@ -55,8 +56,25 @@ function initVirtualComponent (options: Object = {}) {
5556
initProvide(vm)// resolve provide after data/props
5657
callHook(vm,'created')
5758

59+
// send initial data to native
60+
constdata=vm.$options.data
61+
constparams=typeofdata==='function'
62+
?getData(data,vm)
63+
:data||{}
64+
if(isPlainObject(params)){
65+
updateComponentData(componentId,params)
66+
}
67+
5868
registerComponentHook(componentId,'lifecycle','attach',()=>{
59-
mountComponent(vm)
69+
callHook(vm,'beforeMount')
70+
71+
constupdateComponent=()=>{
72+
vm._update(vm._vnode,false)
73+
}
74+
newWatcher(vm,updateComponent,noop,null,true)
75+
76+
vm._isMounted=true
77+
callHook(vm,'mounted')
6078
})
6179

6280
registerComponentHook(componentId,'lifecycle','detach',()=>{
@@ -65,25 +83,53 @@ function initVirtualComponent (options: Object = {}) {
6583
}
6684

6785
// override Vue.prototype._update
68-
functionupdateVirtualComponent(vnode:VNode,hydrating?:boolean){
69-
// TODO
70-
updateComponentData(this.$options.componentId,{})
86+
functionupdateVirtualComponent(vnode?:VNode){
87+
constvm:Component=this
88+
constcomponentId=vm.$options.componentId
89+
if(vm._isMounted){
90+
callHook(vm,'beforeUpdate')
91+
}
92+
vm._vnode=vnode
93+
if(vm._isMounted&&componentId){
94+
// TODO: data should be filtered and without bindings
95+
constdata=Object.assign({},vm._data)
96+
updateComponentData(componentId,data,()=>{
97+
callHook(vm,'updated')
98+
})
99+
}
71100
}
72101

73102
// listening on native callback
74103
exportfunctionresolveVirtualComponent(vnode:MountedComponentVNode):VNode{
75104
constBaseCtor=vnode.componentOptions.Ctor
76105
constVirtualComponent=BaseCtor.extend({})
106+
constcid=VirtualComponent.cid
77107
VirtualComponent.prototype._init=initVirtualComponent
78108
VirtualComponent.prototype._update=updateVirtualComponent
79109

80110
vnode.componentOptions.Ctor=BaseCtor.extend({
81111
beforeCreate(){
82-
registerComponentHook(VirtualComponent.cid,'lifecycle','create',componentId=>{
112+
// const vm: Component = this
113+
114+
// TODO: listen on all events and dispatch them to the
115+
// corresponding virtual components according to the componentId.
116+
// vm._virtualComponents = {}
117+
constcreateVirtualComponent=(componentId,propsData)=>{
83118
// create virtual component
84-
constoptions={ componentId}
85-
returnnewVirtualComponent(options)
86-
})
119+
// const subVm =
120+
newVirtualComponent({
121+
componentId,
122+
propsData
123+
})
124+
// if (vm._virtualComponents) {
125+
// vm._virtualComponents[componentId] = subVm
126+
// }
127+
}
128+
129+
registerComponentHook(cid,'lifecycle','create',createVirtualComponent)
130+
},
131+
beforeDestroy(){
132+
deletethis._virtualComponents
87133
}
88134
})
89135
}

‎src/platforms/weex/util/index.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,17 @@ export function registerComponentHook (
7070
}
7171

7272
// Updates the state of the component to weex native render engine.
73-
exportfunctionupdateComponentData(componentId:string,newData:Object){
73+
exportfunctionupdateComponentData(
74+
componentId:string,
75+
newData:Object|void,
76+
callback?:Function
77+
){
7478
if(!document||!document.taskCenter){
7579
warn(`Can't find available "document" or "taskCenter".`)
7680
return
7781
}
7882
if(typeofdocument.taskCenter.updateData==='function'){
79-
returndocument.taskCenter.updateData(componentId,newData)
83+
returndocument.taskCenter.updateData(componentId,newData,callback)
8084
}
8185
warn(`Failed to update component data (${componentId}).`)
8286
}

‎test/weex/cases/cases.spec.js

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -137,29 +137,45 @@ describe('Usage', () => {
137137
constid=String(Date.now()*Math.random())
138138
constinstance=createInstance(id,code)
139139
expect(tasks.length).toEqual(3)
140-
tasks.length=0
141-
instance.$triggerHook(2,'create',['component-1'])
142-
instance.$triggerHook(2,'create',['component-2'])
143-
instance.$triggerHook('component-1','attach')
144-
instance.$triggerHook('component-2','attach')
145-
expect(tasks.length).toEqual(2)
146-
expect(tasks[0].method).toEqual('updateComponentData')
147-
// expect(tasks[0].args).toEqual([{ count: 42 }])
148-
expect(tasks[1].method).toEqual('updateComponentData')
149-
// expect(tasks[1].args).toEqual([{ count: 42 }])
150140
setTimeout(()=>{
141+
// check the render results
151142
consttarget=readObject('recycle-list/components/stateful.vdom.js')
152143
expect(getRoot(instance)).toEqual(target)
153-
constevent=getEvents(instance)[0]
154144
tasks.length=0
155-
fireEvent(instance,event.ref,event.type,{})
145+
146+
// trigger component hooks
147+
instance.$triggerHook(
148+
2,// cid of the virtual component template
149+
'create',// lifecycle hook name
150+
151+
// arguments for the callback
152+
[
153+
'x-1',// componentId of the virtual component
154+
{start:3}// propsData of the virtual component
155+
]
156+
)
157+
instance.$triggerHook(2,'create',['x-2',{start:11}])
158+
159+
// the state (_data) of the virtual component should be sent to native
160+
expect(tasks.length).toEqual(2)
161+
expect(tasks[0].method).toEqual('updateComponentData')
162+
expect(tasks[0].args).toEqual(['x-1',{count:6},''])
163+
expect(tasks[1].method).toEqual('updateComponentData')
164+
expect(tasks[1].args).toEqual(['x-2',{count:22},''])
165+
166+
instance.$triggerHook('x-1','attach')
167+
instance.$triggerHook('x-2','attach')
168+
tasks.length=0
169+
170+
// simulate a click event
171+
// the event will be caught by the virtual component template and
172+
// should be dispatched to virtual component according to the componentId
173+
constevent=getEvents(instance)[0]
174+
fireEvent(instance,event.ref,'click',{componentId:'x-1'})
156175
setTimeout(()=>{
157176
// expect(tasks.length).toEqual(1)
158-
// expect(tasks[0]).toEqual({
159-
// module: 'dom',
160-
// method: 'updateComponentData',
161-
// args: [{ count: 43 }]
162-
// })
177+
// expect(tasks[0].method).toEqual('updateComponentData')
178+
// expect(tasks[0].args).toEqual([{ count: 7 }])
163179
instance.$destroy()
164180
resetTaskHook()
165181
done()
@@ -168,6 +184,39 @@ describe('Usage', () => {
168184
}).catch(done.fail)
169185
})
170186

187+
// it('component lifecycle', done => {
188+
// global.__lifecycles = []
189+
// compileWithDeps('recycle-list/components/stateful-lifecycle.vue', [{
190+
// name: 'lifecycle',
191+
// path: 'recycle-list/components/lifecycle.vue'
192+
// }]).then(code => {
193+
// const id = String(Date.now() * Math.random())
194+
// const instance = createInstance(id, code)
195+
// setTimeout(() => {
196+
// const target = readObject('recycle-list/components/stateful-lifecycle.vdom.js')
197+
// expect(getRoot(instance)).toEqual(target)
198+
199+
// instance.$triggerHook(2, 'create', ['y-1'])
200+
// instance.$triggerHook('y-1', 'attach')
201+
// instance.$triggerHook('y-1', 'detach')
202+
// expect(global.__lifecycles).toEqual([
203+
// 'beforeCreate undefined',
204+
// 'created 0',
205+
// 'beforeMount 1',
206+
// 'mounted 1',
207+
// 'beforeUpdate 2',
208+
// 'updated 2',
209+
// 'beforeDestroy 2',
210+
// 'destroyed 2'
211+
// ])
212+
213+
// delete global.__lifecycles
214+
// instance.$destroy()
215+
// done()
216+
// }, 50)
217+
// }).catch(done.fail)
218+
// })
219+
171220
it('stateful component with v-model',done=>{
172221
compileWithDeps('recycle-list/components/stateful-v-model.vue',[{
173222
name:'editor',

‎test/weex/cases/recycle-list/components/counter.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
props: ['start'],
1111
data () {
1212
return {
13-
count:parseInt(this.start,10)||42
13+
count:parseInt(this.start,10)*2||42
1414
}
1515
},
1616
methods: {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<template recyclable="true">
2+
<div>
3+
<text>{{number}}</text>
4+
</div>
5+
</template>
6+
7+
<script>
8+
module.exports= {
9+
data () {
10+
return { number:0 }
11+
},
12+
beforeCreate () {
13+
try {__lifecycles.push('beforeCreate'+this.number) }catch (e) {}
14+
},
15+
created () {
16+
try {__lifecycles.push('created'+this.number) }catch (e) {}
17+
this.number++
18+
},
19+
beforeMount () {
20+
try {__lifecycles.push('beforeMount'+this.number) }catch (e) {}
21+
},
22+
mounted () {
23+
try {__lifecycles.push('mounted'+this.number) }catch (e) {}
24+
this.number++
25+
},
26+
beforeUpdate () {
27+
try {__lifecycles.push('beforeUpdate'+this.number) }catch (e) {}
28+
},
29+
updated () {
30+
try {__lifecycles.push('updated'+this.number) }catch (e) {}
31+
},
32+
beforeDestroy () {
33+
try {__lifecycles.push('beforeDestroy'+this.number) }catch (e) {}
34+
},
35+
destroyed () {
36+
try {__lifecycles.push('destroyed'+this.number) }catch (e) {}
37+
}
38+
}
39+
</script>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
({
2+
type:'recycle-list',
3+
attr:{
4+
append:'tree',
5+
listData:[
6+
{type:'X'},
7+
{type:'X'}
8+
],
9+
templateKey:'type',
10+
alias:'item'
11+
},
12+
children:[{
13+
type:'cell-slot',
14+
attr:{append:'tree',templateType:'X'},
15+
children:[{
16+
type:'div',
17+
attr:{
18+
'@isComponentRoot':true,
19+
'@componentProps':{}
20+
},
21+
children:[{
22+
type:'text',
23+
attr:{
24+
value:{'@binding':'number'}
25+
}
26+
}]
27+
}]
28+
}]
29+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<template>
2+
<recycle-list:list-data="longList"template-key="type"alias="item">
3+
<cell-slottemplate-type="X">
4+
<lifecycle></lifecycle>
5+
</cell-slot>
6+
</recycle-list>
7+
</template>
8+
9+
<script>
10+
// require('./lifecycle.vue')
11+
module.exports= {
12+
data () {
13+
return {
14+
longList: [
15+
{ type:'X' },
16+
{ type:'X' }
17+
]
18+
}
19+
}
20+
}
21+
</script>

‎test/weex/runtime/framework.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('framework APIs', () => {
3636
type:'div',
3737
children:[{
3838
type:'text',
39-
attr:{value:'{"bundleUrl":"http://example.com/","a":1,"b":2,"env":{}}'}
39+
attr:{value:'{"bundleUrl":"http://example.com/","a":1,"b":2,"env":{},"bundleType":"Vue"}'}
4040
}]
4141
})
4242
})
@@ -170,6 +170,7 @@ describe('framework APIs', () => {
170170
`,{bundleUrl:'http://whatever.com/x.js'})
171171
expect(JSON.parse(getRoot(instance).children[0].attr.value)).toEqual({
172172
bundleUrl:'http://whatever.com/x.js',
173+
bundleType:'Vue',
173174
env:{
174175
weexVersion:'0.10.0',
175176
platform:'Node.js'

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp