Skip to content

Commit 72c386b

Browse files
committed
fix: render node transition is dynamic
fixes #52
1 parent 07ec920 commit 72c386b

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

Diff for: src/components/TransitionStub.js

+39-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ function getRealChild (vnode: ?VNode): ?VNode {
1111
}
1212
}
1313

14+
function isSameChild (child: VNode, oldChild: VNode): boolean {
15+
return oldChild.key === child.key && oldChild.tag === child.tag
16+
}
17+
1418
function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
1519
if (Array.isArray(children)) {
1620
for (let i = 0; i < children.length; i++) {
@@ -22,6 +26,16 @@ function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
2226
}
2327
}
2428

29+
function isPrimitive (value: any): boolean %checks {
30+
return (
31+
typeof value === 'string' ||
32+
typeof value === 'number' ||
33+
// $flow-disable-line
34+
typeof value === 'symbol' ||
35+
typeof value === 'boolean'
36+
)
37+
}
38+
2539
function isAsyncPlaceholder (node: VNode): boolean {
2640
return node.isComment && node.asyncFactory
2741
}
@@ -102,14 +116,37 @@ export default {
102116
return rawChild
103117
}
104118

105-
(child.data || (child.data = {})).transition = extractTransitionData(this)
119+
const id: string = `__transition-${this._uid}-`
120+
child.key = child.key == null
121+
? child.isComment
122+
? id + 'comment'
123+
: id + child.tag
124+
: isPrimitive(child.key)
125+
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
126+
: child.key
127+
128+
const data: Object = (child.data || (child.data = {})).transition = extractTransitionData(this)
129+
const oldRawChild: VNode = this._vnode
130+
const oldChild: VNode = getRealChild(oldRawChild)
131+
if (child.data.directives && child.data.directives.some(d => d.name === 'show')) {
132+
child.data.show = true
133+
}
106134

107135
// mark v-show
108136
// so that the transition module can hand over the control to the directive
109137
if (child.data.directives && child.data.directives.some(d => d.name === 'show')) {
110138
child.data.show = true
111139
}
112-
140+
if (
141+
oldChild &&
142+
oldChild.data &&
143+
!isSameChild(child, oldChild) &&
144+
!isAsyncPlaceholder(oldChild) &&
145+
// #6687 component root is a comment node
146+
!(oldChild.componentInstance && oldChild.componentInstance._vnode.isComment)
147+
) {
148+
oldChild.data = { ...data }
149+
}
113150
return rawChild
114151
}
115152
}

Diff for: test/unit/specs/TransitionStub.spec.js

+26
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,30 @@ describe('TransitionStub', () => {
3030
expect(error.args[0][0]).to.equal(msg)
3131
error.restore()
3232
})
33+
34+
it('handles keyed transitions', () => {
35+
const TestComponent = {
36+
template: `
37+
<div>
38+
<transition>
39+
<div v-if="bool" key="a">a</div>
40+
<div v-else key="b">b</div>
41+
</transition>
42+
</div>
43+
`,
44+
data () {
45+
return {
46+
bool: true
47+
}
48+
}
49+
}
50+
const wrapper = mount(TestComponent, {
51+
stubs: {
52+
'transition': TransitionStub
53+
}
54+
})
55+
expect(wrapper.text()).to.equal('a')
56+
wrapper.setData({ bool: false })
57+
expect(wrapper.text()).to.equal('b')
58+
})
3359
})

0 commit comments

Comments
 (0)