diff --git a/examples/layout-transitions/README.md b/examples/layout-transitions/README.md new file mode 100644 index 0000000000..3bdd2a9092 --- /dev/null +++ b/examples/layout-transitions/README.md @@ -0,0 +1,3 @@ +# Layout transitions with Nuxt.js + +https://nuxtjs.org/examples/layout-transitions diff --git a/examples/layout-transitions/assets/main.css b/examples/layout-transitions/assets/main.css new file mode 100644 index 0000000000..dbb73ba005 --- /dev/null +++ b/examples/layout-transitions/assets/main.css @@ -0,0 +1,52 @@ +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; +} + +.container { + text-align: center; + padding-top: 200px; + font-size: 20px; + transition: all .5s cubic-bezier(.55,0,.1,1); +} + +.page-enter-active, .page-leave-active { + transition: opacity .5s +} +.page-enter, .page-leave-active { + opacity: 0 +} + +.layout-enter-active, .layout-leave-active { + transition: opacity .5s +} +.layout-enter, .layout-leave-active { + opacity: 0 +} + +.bounce-enter-active { + animation: bounce-in .8s; +} +.bounce-leave-active { + animation: bounce-out .5s; +} +@keyframes bounce-in { + 0% { transform: scale(0) } + 50% { transform: scale(1.5) } + 100% { transform: scale(1) } +} +@keyframes bounce-out { + 0% { transform: scale(1) } + 50% { transform: scale(1.5) } + 100% { transform: scale(0) } +} + +.slide-left-enter, +.slide-right-leave-active { + opacity: 0; + transform: translate(30px, 0); +} +.slide-left-leave-active, +.slide-right-enter { + opacity: 0; + transform: translate(-30px, 0); +} diff --git a/examples/layout-transitions/layouts/secondary.vue b/examples/layout-transitions/layouts/secondary.vue new file mode 100644 index 0000000000..d4a9065bd3 --- /dev/null +++ b/examples/layout-transitions/layouts/secondary.vue @@ -0,0 +1,11 @@ + diff --git a/examples/layout-transitions/nuxt.config.js b/examples/layout-transitions/nuxt.config.js new file mode 100644 index 0000000000..e1b2d64a6c --- /dev/null +++ b/examples/layout-transitions/nuxt.config.js @@ -0,0 +1,10 @@ +module.exports = { + build: { + vendor: ['axios'] + }, + css: ['~/assets/main.css'], + layoutTransition: { + name: 'layout', + mode: 'out-in' + } +} diff --git a/examples/layout-transitions/package.json b/examples/layout-transitions/package.json new file mode 100644 index 0000000000..38fd64e26c --- /dev/null +++ b/examples/layout-transitions/package.json @@ -0,0 +1,12 @@ +{ + "name": "nuxt-layout-transitions", + "dependencies": { + "axios": "^0.15.3", + "nuxt": "latest" + }, + "scripts": { + "dev": "../../bin/nuxt", + "build": "nuxt build", + "start": "nuxt start" + } +} diff --git a/examples/layout-transitions/pages/about.vue b/examples/layout-transitions/pages/about.vue new file mode 100644 index 0000000000..0ec094454f --- /dev/null +++ b/examples/layout-transitions/pages/about.vue @@ -0,0 +1,13 @@ + + + diff --git a/examples/layout-transitions/pages/index.vue b/examples/layout-transitions/pages/index.vue new file mode 100644 index 0000000000..fe5ce74005 --- /dev/null +++ b/examples/layout-transitions/pages/index.vue @@ -0,0 +1,7 @@ + diff --git a/examples/layout-transitions/pages/users.vue b/examples/layout-transitions/pages/users.vue new file mode 100644 index 0000000000..84ea80cf23 --- /dev/null +++ b/examples/layout-transitions/pages/users.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/lib/app/App.vue b/lib/app/App.vue index 37e6d69b37..771bd613f7 100644 --- a/lib/app/App.vue +++ b/lib/app/App.vue @@ -1,7 +1,9 @@ diff --git a/lib/app/components/nuxt-child.js b/lib/app/components/nuxt-child.js index 39b8e3c4e7..8df1feb71d 100644 --- a/lib/app/components/nuxt-child.js +++ b/lib/app/components/nuxt-child.js @@ -37,6 +37,19 @@ export default { name: 'nuxt-child', functional: true, render (h, { parent, data }) { + const nuxt = parent.$root.nuxt + const component = parent.$route.matched[0].components.default + + const layoutUid = parent._uid + const layoutName = component.options ? component.options.layout : null + + // If we're changing layout render the stored vnode + if (nuxt._layoutUid === layoutUid && + nuxt._layoutName !== layoutName) return nuxt._childVnode + + nuxt._layoutUid = layoutUid + nuxt._layoutName = layoutName + data.nuxtChild = true const _parent = parent const transitions = parent.$nuxt.nuxt.transitions @@ -62,11 +75,14 @@ export default { listeners[key] = transition[key].bind(_parent) } }) - return h('transition', { + + nuxt._childVnode = h('transition', { props: transitionProps, on: listeners }, [ h('router-view', data) ]) + + return nuxt._childVnode } } diff --git a/lib/app/components/nuxt.vue b/lib/app/components/nuxt.vue index 2817b3af9a..2bdd096dd8 100644 --- a/lib/app/components/nuxt.vue +++ b/lib/app/components/nuxt.vue @@ -1,6 +1,8 @@