Skip to content

Commit e8552e7

Browse files
committed
implement same props interface for transition-group
1 parent a7508b1 commit e8552e7

File tree

2 files changed

+55
-40
lines changed

2 files changed

+55
-40
lines changed

src/platforms/web/runtime/components/transition-group.js

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { warn } from 'core/util/index'
1+
import { warn, extend } from 'core/util/index'
2+
import { transitionProps, extractTransitionData } from './transition'
23

34
// Because the vdom's children update algorithm is "unstable" - i.e.
45
// it doesn't guarantee the relative positioning of removed elements,
@@ -9,32 +10,38 @@ import { warn } from 'core/util/index'
910
// nodes will remain where they should be.
1011

1112
export default {
12-
props: ['tag'],
13+
props: extend({ tag: String }, transitionProps),
1314

1415
beforeUpdate () {
16+
// force removing pass
1517
this.__patch__(this._vnode, this.kept)
1618
this._vnode = this.kept
1719
},
1820

1921
render (h) {
2022
const prevMap = this.prevChildrenMap
21-
const children = this.$slots.default || []
2223
const map = this.prevChildrenMap = {}
24+
const rawChildren = this.$slots.default || []
25+
const children = []
2326
const kept = []
27+
const transitionData = extractTransitionData(this)
2428

25-
for (let i = 0; i < children.length; i++) {
26-
const c = children[i]
29+
for (let i = 0; i < rawChildren.length; i++) {
30+
const c = rawChildren[i]
2731
if (c.tag) {
28-
if (c.key == null) {
29-
process.env.NODE_ENV !== 'production' && warn(
30-
'transition-group children must be keyed.'
31-
)
32-
c.key = i
33-
}
34-
map[c.key] = c
35-
;(c.data || (c.data = {})).transition = { name: 'fade' }
36-
if (prevMap && prevMap[c.key]) {
37-
kept.push(c)
32+
if (c.key != null) {
33+
children.push(c)
34+
map[c.key] = c
35+
;(c.data || (c.data = {})).transition = transitionData
36+
if (prevMap && prevMap[c.key]) {
37+
kept.push(c)
38+
}
39+
} else if (process.env.NODE_ENV !== 'production') {
40+
const opts = c.componentOptions
41+
const name = opts
42+
? (opts.Ctor.options.name || opts.tag)
43+
: c.tag
44+
warn(`<transition-group> children must be keyed: <${name}>`)
3845
}
3946
}
4047
}

src/platforms/web/runtime/components/transition.js

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,38 @@ import { warn } from 'core/util/index'
22
import { noop, camelize } from 'shared/util'
33
import { getRealChild, mergeVNodeHook } from 'core/vdom/helpers'
44

5+
export const transitionProps = {
6+
name: String,
7+
appear: Boolean,
8+
css: Boolean,
9+
mode: String,
10+
enterClass: String,
11+
leaveClass: String,
12+
enterActiveClass: String,
13+
leaveActiveClass: String,
14+
appearClass: String,
15+
appearActiveClass: String
16+
}
17+
18+
export function extractTransitionData (comp) {
19+
const data = {}
20+
const options = comp.$options
21+
// props
22+
for (const key in options.propsData) {
23+
data[key] = comp[key]
24+
}
25+
// events.
26+
// extract listeners and pass them directly to the transition methods
27+
const listeners = options._parentListeners
28+
for (const key in listeners) {
29+
data[camelize(key)] = listeners[key].fn
30+
}
31+
return data
32+
}
33+
534
export default {
635
name: 'transition',
7-
props: {
8-
name: String,
9-
appear: Boolean,
10-
css: Boolean,
11-
mode: String,
12-
enterClass: String,
13-
leaveClass: String,
14-
enterActiveClass: String,
15-
leaveActiveClass: String,
16-
appearClass: String,
17-
appearActiveClass: String
18-
},
36+
props: transitionProps,
1937
_abstract: true,
2038
render (h) {
2139
const children = this.$slots.default && this.$slots.default.filter(c => c.tag)
@@ -41,26 +59,17 @@ export default {
4159
// use getRealChild() to ignore abstract components e.g. keep-alive
4260
const child = getRealChild(rawChild)
4361
child.key = child.key || `__v${child.tag + this._uid}__`
44-
const data = (child.data || (child.data = {})).transition = {}
45-
// props
46-
for (const key in this.$options.propsData) {
47-
data[key] = this[key]
48-
}
49-
// events.
50-
// extract listeners and pass them directly to the transition methods
51-
const listeners = this.$options._parentListeners
52-
for (const key in listeners) {
53-
data[camelize(key)] = listeners[key].fn
54-
}
62+
const data = (child.data || (child.data = {})).transition = extractTransitionData(this)
5563

5664
// handle transition mode
5765
const mode = this.mode
5866
const oldRawChild = this._vnode
5967
const oldChild = getRealChild(oldRawChild)
6068
if (mode && oldChild && oldChild.data && oldChild.key !== child.key) {
69+
const oldData = oldChild.data.transition
6170
if (mode === 'out-in') {
6271
// return empty node and queue update when leave finishes
63-
mergeVNodeHook(oldChild.data.transition, 'afterLeave', () => {
72+
mergeVNodeHook(oldData, 'afterLeave', () => {
6473
this.$forceUpdate()
6574
})
6675
return /\d-keep-alive$/.test(rawChild.tag)
@@ -73,7 +82,6 @@ export default {
7382
mergeVNodeHook(data, 'afterEnter', performLeave)
7483
mergeVNodeHook(data, 'enterCancelled', performLeave)
7584

76-
const oldData = oldChild.data.transition
7785
mergeVNodeHook(oldData, 'delayLeave', leave => {
7886
delayedLeave = leave
7987
})

0 commit comments

Comments
 (0)