Browse Source

[weex] wip: experimenting with transition-group

dev
Evan You 8 years ago
parent
commit
b88d3ca82c
  1. 6
      src/platforms/weex/runtime/components/index.js
  2. 151
      src/platforms/weex/runtime/components/transition-group.js
  3. 2
      src/platforms/weex/runtime/components/transition.js
  4. 4
      src/platforms/weex/runtime/modules/transition.js

6
src/platforms/weex/runtime/components/index.js

@ -1,5 +1,7 @@
import Transition from 'web/runtime/components/transition'
import Transition from './transition'
import TransitionGroup from './transition-group'
export default {
Transition
Transition,
TransitionGroup
}

151
src/platforms/weex/runtime/components/transition-group.js

@ -0,0 +1,151 @@
import { warn, extend } from 'core/util/index'
import { transitionProps, extractTransitionData } from './transition'
const props = extend({
tag: String,
moveClass: String
}, transitionProps)
delete props.mode
export default {
props,
created () {
const dom = this._requireWeexModule('dom')
this.getPosition = el => new Promise((resolve, reject) => {
dom.getComponentRect(el.ref, res => {
if (!res.result) {
reject(new Error(`failed to get rect for element: ${el.tag}`))
} else {
resolve(res.size)
}
})
})
const animation = this._requireWeexModule('animation')
this.animate = (el, options) => new Promise(resolve => {
animation.transition(el.ref, options, resolve)
})
},
render (h) {
const tag = this.tag || this.$vnode.data.tag || 'span'
const map = Object.create(null)
const prevChildren = this.prevChildren = this.children
const rawChildren = this.$slots.default || []
const children = this.children = []
const transitionData = extractTransitionData(this)
for (let i = 0; i < rawChildren.length; i++) {
const c = rawChildren[i]
if (c.tag) {
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
children.push(c)
map[c.key] = c
;(c.data || (c.data = {})).transition = transitionData
} else if (process.env.NODE_ENV !== 'production') {
const opts = c.componentOptions
const name = opts
? (opts.Ctor.options.name || opts.tag)
: c.tag
warn(`<transition-group> children must be keyed: <${name}>`)
}
}
}
if (prevChildren) {
const kept = []
const removed = []
const positionPromises = []
prevChildren.forEach(c => {
c.data.transition = transitionData
positionPromises.push(this.getPosition(c.elm).then(pos => {
c.data.pos = pos
}))
if (map[c.key]) {
kept.push(c)
} else {
removed.push(c)
}
})
this.kept = h(tag, null, kept)
this.removed = removed
this.pendingPositions = Promise.all(positionPromises)
}
return h(tag, null, children)
},
beforeUpdate () {
// force removing pass
this.__patch__(
this._vnode,
this.kept,
false, // hydrating
true // removeOnly (!important, avoids unnecessary moves)
)
this._vnode = this.kept
},
updated () {
const children = this.prevChildren
const moveClass = this.moveClass || ((this.name || 'v') + '-move')
const moveData = children.length && this.getMoveData(children[0].context, moveClass)
if (!moveData) {
return
}
children.forEach(callPendingCbs)
this.pendingPositions.then(() => Promise.all(children.map(c => {
// record new position
return this.getPosition(c.elm).then(pos => {
c.data.newPos = pos
})
}))).then(() => Promise.all(children.map(c => {
const oldPos = c.data.pos
const newPos = c.data.newPos
const dx = oldPos.left - newPos.left
const dy = oldPos.top - newPos.top
if (dx || dy) {
c.data.moved = true
return this.animate(c.elm, {
styles: {
transform: `translate(${dx}px,${dy}px)`
}
})
}
}))).then(() => {
children.forEach(c => {
if (c.data.moved) {
this.animate(c.elm, {
styles: {
transform: ''
},
duration: moveData.duration || 0,
delay: moveData.delay || 0,
timingFunction: moveData.timingFunction || 'linear'
})
}
})
})
},
methods: {
getMoveData (context, moveClass) {
const stylesheet = context.$options.style || {}
return stylesheet['@TRANSITION'] && stylesheet['@TRANSITION'][moveClass]
}
}
}
function callPendingCbs (c) {
/* istanbul ignore if */
if (c.elm._moveCb) {
c.elm._moveCb()
}
/* istanbul ignore if */
if (c.elm._enterCb) {
c.elm._enterCb()
}
}

2
src/platforms/weex/runtime/components/transition.js

@ -0,0 +1,2 @@
// reuse same transition component logic from web
export * from 'web/runtime/components/transition'

4
src/platforms/weex/runtime/modules/transition.js

@ -1,3 +1,4 @@
import { warn } from 'core/util/debug'
import { extend, once, noop } from 'shared/util'
import { activeInstance } from 'core/instance/lifecycle'
import { resolveTransition } from 'web/runtime/transition-util'
@ -233,11 +234,12 @@ function getEnterTargetState (el, stylesheet, startClass, endClass, activeClass,
for (const key in startState) {
targetState[key] = el.style[key]
if (
process.env.NODE_ENV !== 'production' &&
targetState[key] == null &&
(!activeState || activeState[key] == null) &&
(!endState || endState[key] == null)
) {
console.log(
warn(
`transition property "${key}" is declared in enter starting class (.${startClass}), ` +
`but not declared anywhere in enter ending class (.${endClass}), ` +
`enter active cass (.${activeClass}) or the element's default styling. ` +

Loading…
Cancel
Save