You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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,提问作者김수진

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:17:59