一步步创建一个vue项目(五)标签栏

一步步创建一个vue项目(五)标签栏

实现根据route内容实现标签栏

这里是依据vue-element-admin中的代码,通过自己整理后将自己整理的一些内容列出来:

在这里插入图片描述
首先是要实现的功能:
1.点击左面的导航栏右面会出现相对应的标签和页面(可关闭)
2.判断页面是否活跃,哪些页面是活跃状态
目前只实现了这两个功能
这里的标签页的记录使用了store,把哪些页面打开,哪些页面关闭使用store记录,主要代码以及注释我都标了出来:
首先在store里创建一个值用来存路由的状态:visitedViews
然后是标签页的页面:

//TabsView.vue
<template>
  <div class="tabs-view-container">
    <router-link
      class="tabs-view"
      v-for="tag in Array.from(visitedViews)"
      :to="tag.path"
      :key="tag.path"
    >
      <el-tag
        :closable="true"
        :class="isActive(tag.path) ? 'active' : ''"
        @close.prevent="closeViewTabs(tag, $event)"
      >
        {{ tag.name }}
      </el-tag>
    </router-link>
  </div>
</template>

<script>
export default {
  data () {
    return {}
  },
  created () {
    this.addViewTabs()
  },
  computed: {
    // 获取当前的路由
    visitedViews () {
      return this.$store.state.app.visitedViews.slice(-6)
    }
  },
  methods: {
    closeViewTabs (view, $event) {
      this.$store.dispatch('delVisitedViews', view)
      // 判断删掉的元素是否是当前正在浏览的页面
      if (this.isActive(view.path)) {
        // 切换活跃页面
        this.toLastView(this.visitedViews, view)
      }
    },
    generateRoute () {
      if (this.$route.matched[this.$route.matched.length - 1].name) {
        return this.$route.matched[this.$route.matched.length - 1]
      }
      this.$route.matched[0].path = '/'
      return this.$route.matched[0]
    },
    addViewTabs () {
      this.$store.dispatch('addVisitedViews', this.generateRoute())
    },
    isActive (path) {
      return path === this.$route.path
    },
    toLastView (visitedViews, view) {
      // slice()方法截取某个范围的数组的元素
      // 比如slice(1,3),数组从0开始,包前不包后截取两个数,负数从后往前数
      // 这里是截取最后一个元素
      // 截取最后一个元素,也就是关闭页面后当前活跃页
      console.log(view)
      const latestView = visitedViews.slice(-1)[0]
      console.log(latestView)
      // 如果存在最后一页
      if (latestView) {
        this.$router.push(latestView.path)
      } else {
        // 否则显示默认页
        if (view.name === '首页') {
          // 重定向首页
          this.$router.replace({ path: view.path })
        } else {
          this.$router.push('/')
        }
      }
    }
  },
  watch: {
    $route () {
      this.addViewTabs()
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.tabs-view-container {
  display: inline-block;
  vertical-align: top;
  margin-left: 10px;
  .tabs-view {
    margin-left: 10px;
  }
}
.active {
  background-color: #42b983;
  color: #fff;
  border-color: #42b983;
  &::before {
    content: "";
    background: #fff;
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    position: relative;
    margin-right: 2px;
  }
}
</style>

在想引入的页面中引入后就是store里面写一些增加和删除的功能:

//app.js
// 标签栏
const app = {
  state: {
    visitedViews: []
  },
  mutations: {
    // 添加tab
    ADD_VISITED_VIEWS: (state, view) => {
      // 判断添加的tab如果路径已经存在则return
      if (state.visitedViews.some(v => v.path === view.path)) return
      // 否则添加
      state.visitedViews.push({ name: view.name, path: view.path })
    },
    // 删除tab
    DEL_VISITED_VIEWS: (state, view) => {
      // entries()方法返回数组中的每一项键值对
      // splice()方法添加或删除,格式splice(i,i,obj,obj···),前两个是两个数字,后面是元素,第一个数字代表从第几个删除或添加,第二个数字代表删除几个元素
      // 两个数字后面的元素代表添加这些元素,返回值是被删除掉的元素
      for (const [i, v] of state.visitedViews.entries()) {
        if (v.path === view.path) {
          // 返回被删掉的数组元素
          state.visitedViews.splice(i, 1)
          break
        }
      }
    }
  },
  actions: {
    addVisitedViews: ({ commit }, view) => {
      commit('ADD_VISITED_VIEWS', view)
    },
    delVisitedViews: ({ commit }, view) => {
      commit('DEL_VISITED_VIEWS', view)
    }
  }
}

export default app

主要的思路应该就是通过点击侧边栏后路由会发生变化,然后将发生变化的路由(增加或者减少的)记录在store中的数组,将数组拆开就是各个标签,将拆开后的每一项进行删除就实现了删除标签。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别出声~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值