使用iview的Menu组件,路由中断跳转但是路由高亮仍然改变问题

问题描述:

最近项目有一个需求,在表单填写相关页面,如果用户没有保存表单内容,点击导航栏将要离开页面的时候提示“信息未保存,离开页面数据将会丢失,是否确定离开?”

(1)选择“确定” —— 执行路由跳转

(2)选择“取消” —— 中止跳转,仍旧留在当前页

以上为需求描述,遇到的问题是:选择取消后,侧导航栏的高亮项不正确

简单示例如下图:点击“错误收集”,取消路由跳转,页面仍停留在“指令”页面,但是路由高亮已经变成了“错误收集”。

 解决思路:

1. 在当前页面中添加路由守卫,满足条件继续跳转,否则中止跳转;

2. 给导航栏menuItem添加自定义高亮样式(如 class="xmj-menu-active"),不要用iview的menu组件的默认高亮类(目前没有找到使用默认高亮类名 ".ivu-menu-item-active.ivu-menu-item-selected" 时候的解决方法);

3. 在路由更新时相应改变active-class(beforeRouteEnter,beforeRouteUpdate);

代码示例:

(1)当前表单页面:

<!-- formPage.vue -->
<template>
  <div>
    <p>模拟当前页表单数据保存状态:{{saved}}</p>
    <Modal
        v-model="modalShow"
        title="确定离开么?"
        @on-ok="ok"
        @on-cancel="cancel">
        <p>当前页面数据未保存,离开后数据将会丢失。</p>
    </Modal>
  </div>
</template>

<script>
export default {
  name: 'form_page',
  data () {
    return {
      saved: false,
      modalShow: false,
      next: null
    }
  },
  methods:
    ok () {  // 用户点击确认
      this.next()
    },
    cancel () {  // 用户点击取消
      this.modalShow = false
    }
  },
  // 在路由拦截中判断当前页表单是否保存,已保存->继续,未保存->中止跳转,展示弹窗
  beforeRouteLeave (to, from, next) {
    if (this.saved) {
      next()
    } else {
      this.modalShow = true
      this.next = next
      next(false)
    }
  }
}
</script>

(2)主页面main.vue

<!-- main.vue -->
<template>
  <div>
    <!-- ...省略 -->
    <Menu
      :active-name="routeActiveName"
      theme="light"
      width="auto"
      :accordion="true"
      :open-names="vexOpenNames?[vexOpenNames]:openNames"
      @on-select="changeMenu"
    >
      <div v-for="item in menuList.list" :key="item.id">
        <Submenu v-if="item.list&&item.list.length" :name="item.code">
          <template slot="title">{{item.name}}</template>
          <!-- ** 注意:此处自定义高亮类 xmj-menuitem-active ,添加相应样式,不使用默认的iview高亮类名 ** -->
          <MenuItem
            v-for="v in item.list"
            :name="v.code"
            :key="v.id"
            :class="['menuItem1', routeActiveName==v.code?'xmj-menuitem-active': '']"
          >
            <span>{{v.name}}</span>
          </MenuItem>
        </Submenu>
        <!-- ...省略 -->
      </div>
    </Menu>
  </div>
</template>

<script>
export default {
  name: 'main_page',
  data () {
    return {
      routeActiveName: this.$route.name,
      menuList: [] // 后台拉取的路由权限列表,动态渲染导航栏
    }
  },
  // 在当前路由改变,但是该组件被复用时调用
  beforeRouteUpdate (to, from, next) {
    this.routeActiveName = to.name
    next()
  },
  // 在渲染该组件的对应路由被 confirm 前调用, 不!能!获取组件实例 `this`, 但是在 next() 里面可以通过vm访问组件实例
  beforeRouteEnter (to, from, next) {
    next(vm => {
      vm.routeActiveName = to.name
    })
  },
  methods: {
    changeMenu () {
      this.$router.push('/' + active)
    }
  }

}
</script>

<style>
.xmj-menuitem-active {
  /* 高亮样式 */
}
</style>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值