如何在Vue单页应用中实现App.vue的滑动事件在各视图页面复用?
如何在Vue单页应用中实现App.vue的滑动事件在各视图页面复用?
兄弟,你的需求我完全get到了——在App.vue里统一监听滑动事件,然后让各个路由页面能响应左右滑的prev/next操作对吧?因为页面是通过<router-view>渲染的,和App.vue不算严格的父子组件,常规的父子传值用不上,这时候用**事件总线(Event Bus)**就最合适了,轻量又直接!
下面我一步步给你说怎么改:
第一步:创建事件总线
先在你的项目里新建一个简单的事件总线文件,用来做跨组件的事件通知:
// src/eventBus.js // 如果是Vue 2 版本 import Vue from 'vue' export const EventBus = new Vue() // 如果是Vue 3 版本,需要先装 mitt 库(npm install mitt) // import mitt from 'mitt' // export const EventBus = mitt()
第二步:修改App.vue的滑动逻辑,触发事件
把你原来的滑动监听代码改成触发事件总线的自定义事件,这样各个页面就能收到通知了:
<template> <!-- 你的App.vue模板里肯定有<router-view />,用来渲染各个页面 --> <router-view /> </template> <script> // 导入刚才的事件总线 import { EventBus } from './eventBus' export default { mounted() { let start = null; window.addEventListener("touchstart", function(event){ if(event.touches.length === 1){ start = event.touches.item(0).clientX; }else{ start = null; } }); window.addEventListener("touchend", function(event){ const offset = 100; if(start){ const end = event.changedTouches.item(0).clientX; if(end > start + offset){ console.log('prev'); // 触发"上一页"的自定义事件 EventBus.$emit('swipe-prev') // Vue 2写法 // Vue 3的话用 EventBus.emit('swipe-prev') } else if(end < start - offset ){ console.log('next'); // 触发"下一页"的自定义事件 EventBus.$emit('swipe-next') // Vue 2写法 // Vue 3的话用 EventBus.emit('swipe-next') } } }); } } </script>
第三步:在各个视图页面里监听事件
比如你的某个页面(比如PageA.vue)需要响应滑动,就在页面的生命周期里监听事件,处理自己的逻辑:
<template> <div class="page-content"> <!-- 你的页面内容 --> </div> </template> <script> import { EventBus } from '../eventBus' export default { data() { return { // 可以存一下监听的回调,方便销毁时移除 prevListener: null, nextListener: null } }, mounted() { // 监听左滑(prev)事件,比如跳转到上一个路由 this.prevListener = () => { this.$router.push({ name: 'PreviousPage' }) // 这里换成你实际的路由名 // 也可以做页面内的操作,比如显示上一个tab之类的 } EventBus.$on('swipe-prev', this.prevListener) // Vue 2 // Vue 3的话用 EventBus.on('swipe-prev', this.prevListener) // 监听右滑(next)事件 this.nextListener = () => { this.$router.push({ name: 'NextPage' }) } EventBus.$on('swipe-next', this.nextListener) // Vue 2 // Vue 3的话用 EventBus.on('swipe-next', this.nextListener) }, beforeDestroy() { // 一定要在页面销毁时移除监听,避免内存泄漏! EventBus.$off('swipe-prev', this.prevListener) // Vue 2 EventBus.$off('swipe-next', this.nextListener) // Vue 3的话用 EventBus.off('swipe-prev', this.prevListener) } } </script>
额外补充:其他可选方案
如果你的项目比较复杂,后续可能有更多跨组件通信的需求,也可以用**Vuex(Vue2)或者Pinia(Vue3)**来管理,把滑动状态存在全局状态里,各个页面监听状态变化。不过对于你现在的需求,事件总线已经足够轻量好用了。
另外,你提到的这个场景属于Vue跨组件通信,如果以后再遇到类似问题,搜这个关键词就能找到更多解决方案啦~
备注:内容来源于stack exchange,提问作者김수진
相关产品推荐
相关产品推荐

