diff --git a/src/platforms/web/runtime/directives/show.js b/src/platforms/web/runtime/directives/show.js
index 57ac3ed3..0dd9ec77 100644
--- a/src/platforms/web/runtime/directives/show.js
+++ b/src/platforms/web/runtime/directives/show.js
@@ -3,16 +3,25 @@
import { isIE9 } from 'web/util/index'
import { enter, leave } from '../modules/transition'
+// recursively search for possible transition defined inside the component root
+function locateNode (vnode: VNode): VNodeWithData {
+ return vnode.child && (!vnode.data || !vnode.data.transition)
+ ? locateNode(vnode.child._vnode)
+ : vnode
+}
+
export default {
bind (el: HTMLElement, { value }: VNodeDirective, vnode: VNodeWithData) {
- const transition = vnode.data.transition
+ vnode = locateNode(vnode)
+ const transition = vnode.data && vnode.data.transition
if (value && transition && transition.appear && !isIE9) {
enter(vnode)
}
el.style.display = value ? '' : 'none'
},
update (el: HTMLElement, { value }: VNodeDirective, vnode: VNodeWithData) {
- const transition = vnode.data.transition
+ vnode = locateNode(vnode)
+ const transition = vnode.data && vnode.data.transition
if (transition && !isIE9) {
if (value) {
enter(vnode)
diff --git a/test/unit/features/transition/transition.spec.js b/test/unit/features/transition/transition.spec.js
index 8d406138..b47ac04d 100644
--- a/test/unit/features/transition/transition.spec.js
+++ b/test/unit/features/transition/transition.spec.js
@@ -449,6 +449,42 @@ if (!isIE9) {
}).then(done)
})
+ it('transition with v-show, inside child component', done => {
+ const vm = new Vue({
+ template: `
+
+
+
+ `,
+ data: { ok: true },
+ components: {
+ test: {
+ template: `foo
`
+ }
+ }
+ }).$mount(el)
+
+ // should not apply transition on initial render by default
+ expect(vm.$el.textContent).toBe('foo')
+ expect(vm.$el.children[0].style.display).toBe('')
+ vm.ok = false
+ waitForUpdate(() => {
+ expect(vm.$el.children[0].className).toBe('test test-leave test-leave-active')
+ }).thenWaitFor(nextFrame).then(() => {
+ expect(vm.$el.children[0].className).toBe('test test-leave-active')
+ }).thenWaitFor(duration + 10).then(() => {
+ expect(vm.$el.children[0].style.display).toBe('none')
+ vm.ok = true
+ }).then(() => {
+ expect(vm.$el.children[0].style.display).toBe('')
+ expect(vm.$el.children[0].className).toBe('test test-enter test-enter-active')
+ }).thenWaitFor(nextFrame).then(() => {
+ expect(vm.$el.children[0].className).toBe('test test-enter-active')
+ }).thenWaitFor(duration + 10).then(() => {
+ expect(vm.$el.children[0].className).toBe('test')
+ }).then(done)
+ })
+
it('leaveCancelled (v-show only)', done => {
const spy = jasmine.createSpy('leaveCancelled')
const vm = new Vue({
@@ -668,6 +704,44 @@ if (!isIE9) {
}).then(done)
})
+ it('transition inside child component', done => {
+ const vm = new Vue({
+ template: `
+
+
+
+ `,
+ data: { ok: true },
+ components: {
+ test: {
+ template: `
+
+ foo
+
+ `
+ }
+ }
+ }).$mount(el)
+
+ // should not apply transition on initial render by default
+ expect(vm.$el.innerHTML).toBe('foo
')
+ vm.ok = false
+ waitForUpdate(() => {
+ expect(vm.$el.children[0].className).toBe('test v-leave v-leave-active')
+ }).thenWaitFor(nextFrame).then(() => {
+ expect(vm.$el.children[0].className).toBe('test v-leave-active')
+ }).thenWaitFor(duration + 10).then(() => {
+ expect(vm.$el.children.length).toBe(0)
+ vm.ok = true
+ }).then(() => {
+ expect(vm.$el.children[0].className).toBe('test v-enter v-enter-active')
+ }).thenWaitFor(nextFrame).then(() => {
+ expect(vm.$el.children[0].className).toBe('test v-enter-active')
+ }).thenWaitFor(duration + 10).then(() => {
+ expect(vm.$el.children[0].className).toBe('test')
+ }).then(done)
+ })
+
it('custom transition higher-order component', done => {
const vm = new Vue({
template: '',