组件导航守卫 常见的使用场景

组件导航守卫通常用于处理组件级别的特定逻辑。以下是一些常见的使用场景:

1、表单数据保存提醒:

<template>
  <div>
    <form @submit.prevent="handleSubmit">
      <input v-model="formData.name" />
      <!-- 其他表单字段 -->
    </form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        name: '',
      },
      isFormDirty: false
    }
  },
  // 监听表单变化
  watch: {
    formData: {
      handler() {
        this.isFormDirty = true
      },
      deep: true
    }
  },
  // 离开路由前确认
  beforeRouteLeave(to, from, next) {
    if (this.isFormDirty) {
      const answer = window.confirm('表单未保存,确定要离开吗?')
      if (answer) {
        next()
      } else {
        next(false)
      }
    } else {
      next()
    }
  }
}
</script>

2、组件数据预加载:

<script>
export default {
  data() {
    return {
      pageData: null,
      loading: true
    }
  },
  beforeRouteEnter(to, from, next) {
    // 在渲染组件前获取数据
    fetchPageData(to.params.id)
      .then(data => {
        next(vm => {
          vm.pageData = data
          vm.loading = false
        })
      })
      .catch(error => {
        next(vm => {
          vm.error = error
          vm.loading = false
        })
      })
  }
}
</script>

3、记录/恢复滚动位置:

<script>
export default {
  data() {
    return {
      scrollPosition: 0
    }
  },
  // 离开前保存位置
  beforeRouteLeave(to, from, next) {
    this.scrollPosition = window.scrollY
    localStorage.setItem('scrollPosition', this.scrollPosition)
    next()
  },
  // 返回时恢复位置
  beforeRouteEnter(to, from, next) {
    next(vm => {
      const savedPosition = localStorage.getItem('scrollPosition')
      if (savedPosition) {
        window.scrollTo(0, parseInt(savedPosition))
      }
    })
  }
}
</script>

4、组件内参数变化处理:

<script>
export default {
  beforeRouteUpdate(to, from, next) {
    // 路由参数改变时重新获取数据
    // 例如: /user/1 到 /user/2
    this.userData = null
    this.fetchUserData(to.params.id)
    next()
  },
  methods: {
    fetchUserData(id) {
      // 获取数据的逻辑
    }
  }
}
</script>

5、权限切换处理:

<script>
export default {
  beforeRouteUpdate(to, from, next) {
    // 检查用户是否仍有权限访问新路由
    if (to.meta.requiredRole && !this.hasRole(to.meta.requiredRole)) {
      next({ name: 'unauthorized' })
    } else {
      next()
    }
  },
  methods: {
    hasRole(role) {
      // 检查权限的逻辑
    }
  }
}
</script>

6、组件状态重置:

<script>
export default {
  data() {
    return {
      filters: {},
      sortBy: 'default',
      currentPage: 1
    }
  },
  beforeRouteLeave(to, from, next) {
    // 离开组件时重置状态
    this.resetState()
    next()
  },
  methods: {
    resetState() {
      this.filters = {}
      this.sortBy = 'default'
      this.currentPage = 1
    }
  }
}
</script>

7、缓存控制:

<script>
export default {
  beforeRouteLeave(to, from, next) {
    // 离开时决定是否保留组件缓存
    if (to.meta.clearCache) {
      this.$destroy()
      this.$el.parentNode.removeChild(this.$el)
    }
    next()
  }
}
</script>

8、动画状态处理:

<script>
export default {
  beforeRouteEnter(to, from, next) {
    next(vm => {
      vm.startEntryAnimation()
    })
  },
  beforeRouteLeave(to, from, next) {
    // 确保离开动画完成后再跳转
    this.startExitAnimation().then(() => {
      next()
    })
  },
  methods: {
    startEntryAnimation() {
      // 入场动画逻辑
    },
    startExitAnimation() {
      // 离场动画逻辑
      return new Promise(resolve => {
        setTimeout(resolve, 500) // 动画时长
      })
    }
  }
}
</script>

组件导航守卫主要用于:

  1. 处理组件特定的路由逻辑
  2. 表单处理和数据保存
  3. 组件状态管理
  4. 数据预加载
  5. 权限控制
  6. 动画处理
  7. 缓存控制
  8. 用户体验优化(如滚动位置)

而全局性的逻辑(如用户认证、全局权限等)则应该放在全局导航守卫中处理。

posted @ 2025-01-14 16:05  非法关键字  阅读(48)  评论(0)    收藏  举报