基于Vue & Nuxt实现带页面切换动画的树形导航
实现Nuxt页面切换时菜单元素的下移动画
问题描述
刚学习Vue和Nuxt基础知识,已搭建带菜单列表的首页,以及/about、/projects、/contact三个页面。当前点击菜单链接能显示图片、内容下移且URL同步更新,但希望页面切换时菜单元素有2秒的下移动画(类似指定示例的位移效果)。尝试用transition-group实现未成功,请教实现方法及是否需要使用嵌套路由。
用户提供的代码
首页代码
<template> <div class="container"> <transition-group name="list"> <nuxt-link to="about" key="about">First item - about</nuxt-link> <img src="../assets/ours.png" alt=""> <!-- 这两个元素在移到图片下方时需要动画 --> <nuxt-link to="projects" key="projects">Second item - projects</nuxt-link> <nuxt-link to="contact" key="contact">Last item - contact</nuxt-link> </transition-group> </div> </template> <style > img{ display: block; width: 40%; } a{ display: block; color: orangered; font-family: 'Courier New', Courier, monospace; } </style>
/about页面代码
<template> <div class="container"> <transition-group name="list"> <nuxt-link to="about" key="about">First item - about</nuxt-link> <nuxt-link to="projects" key="projects">Second item - projects</nuxt-link> <nuxt-link to="contact" key="contact">Last item - contact</nuxt-link> </transition-group> </div> </template> <style > img{ display: block; width: 40%; } a{ display: block; color: orangered; font-family: 'Courier New', Courier, monospace; } </style>
尝试的CSS代码
.list-enter-active, .list-leave-active { transition: all 0.5s ease; } .list-enter-from, .list-leave-to { opacity: 0; transform: translateX(30px); }
解决方案
核心结论:不需要嵌套路由
问题根源在于之前的写法是每个页面独立渲染菜单,页面切换时整个组件销毁重建,transition-group无法追踪元素变化。正确做法是用Nuxt布局组件统一管理菜单和图片状态,让transition-group能检测到元素的增减/位移变化。
实现步骤
- 创建全局布局组件,把菜单逻辑抽离到
layouts/default.vue,复用在所有页面:
<template> <div class="layout-container"> <transition-group name="menu-list" tag="div"> <nuxt-link to="/" key="home">首页</nuxt-link> <nuxt-link to="/about" key="about">First item - about</nuxt-link> <!-- 用路由判断控制图片显示,仅首页展示 --> <img v-if="$route.path === '/'" src="@/assets/ours.png" alt="Logo" key="logo"> <nuxt-link to="/projects" key="projects">Second item - projects</nuxt-link> <nuxt-link to="/contact" key="contact">Last item - contact</nuxt-link> </transition-group> <!-- 页面内容插槽 --> <nuxt /> </div> </template> <style scoped> img { display: block; width: 40%; margin: 1rem 0; } a { display: block; color: orangered; font-family: 'Courier New', Courier, monospace; margin: 0.5rem 0; } /* 菜单元素位移动画,时长2秒 */ .menu-list-move { transition: transform 2s ease; } /* 图片的进入/离开动画(可选) */ .menu-list-enter-active, .menu-list-leave-active { transition: all 2s ease; } .menu-list-enter-from, .menu-list-leave-to { opacity: 0; transform: translateY(-20px); } </style>
- 简化页面组件,比如首页
pages/index.vue:
<template> <div class="page-content"> <h1>首页内容</h1> </div> </template>
pages/about.vue简化为:
<template> <div class="page-content"> <h1>关于我们</h1> </div> </template>
原理说明
transition-group通过tag属性渲染为div,确保所有菜单元素和图片在同一容器内排列。- 路由切换时,图片的显示/隐藏会触发
transition-group的内置move动画,让下方的菜单链接平滑下移。 .menu-list-move类是transition-group提供的位移过渡类,设置transform的过渡时长为2秒即可实现需求,同时路由正常更新URL。
内容的提问来源于stack exchange,提问作者Aurore
相关产品推荐
相关产品推荐

