vue--管理后台手把手搭建-----(5)

权限写完了,开始写主页面,如下

vue--管理后台手把手搭建-----(5)

主要由侧边栏,头部,tag标签和主页面构成。

主要介绍tag标签。

a   侧边栏:

 引用element-ui框架,从全局导航钩子开始说起,当我们拉取完用户token后,需要拉取用户权限,我们需要对拉取来的用户权限做处理,判断是否为超管权限或者为该用户应展示的权限内容,将其存放到vuex中,当我们渲染的时候,在从vuex中获取数据。

b   tag标签:

   (1)在store/modules/下新建tagsview.js

const tagsView = {
  state: {
    visitedViews: [], //存放所有浏览过的且不重复的路由数据
    cachedViews: []
  },
  mutations: {
    ADD_VISITED_VIEWS: (state, view) => {  //打开新页签--添加路由数据的方法
      if (state.visitedViews.some(v => v.path === view.path))
        return
      state.visitedViews.push({
        name: view.name,
        path: view.path,
        title: view.meta.title || 'no-name'
      })
      if (!view.meta.noCache) {
        state.cachedViews.push(view.name)
      }
    },
    DEL_VISITED_VIEWS: (state, view) => { //关闭页签--删除路由数据的方法
      for (const [i, v] of state.visitedViews.entries()) {
        if (v.path === view.path) {
          state.visitedViews.splice(i, 1)
          break
        }
      }
      for (const i of state.cachedViews) {
        if (i === view.name) {
          const index = state.cachedViews.indexOf(i)
          state.cachedViews.splice(index, 1)
          break
        }
      }
    },
    DEL_OTHERS_VIEWS: (state, view) => {
      for (const [i, v] of state.visitedViews.entries()) {
        if (v.path === view.path) {
          state.visitedViews = state.visitedViews.slice(i, i + 1)
          break
        }
      }
      for (const i of state.cachedViews) {
        if (i === view.name) {
          const index = state.cachedViews.indexOf(i)
          state.cachedViews = state.cachedViews.slice(index, i + 1)
          break
        }
      }
    },
    DEL_ALL_VIEWS: (state) => {
      state.visitedViews = []
      state.cachedViews = []
    }
  },
  actions: {
    addVisitedViews({ commit }, view) {
      commit('ADD_VISITED_VIEWS', view)
    },
    delVisitedViews({ commit, state }, view) {
      return new Promise((resolve) => {
        commit('DEL_VISITED_VIEWS', view)
        resolve([...state.visitedViews])
      })
    },
    delOthersViews({ commit, state }, view) {
      return new Promise((resolve) => {
        commit('DEL_OTHERS_VIEWS', view)
        resolve([...state.visitedViews])
      })
    },
    delAllViews({ commit, state }) {
      return new Promise((resolve) => {
        commit('DEL_ALL_VIEWS')
        resolve([...state.visitedViews])
      })
    }
  }
}

export default tagsView

 接着 在store中注册,在getter.js中引用

 如何渲染,在vue页面编写如下:

<template>
  <div class="tags-view-container">
    <scroll-pane class='tags-view-wrapper' ref='scrollPane'>
      <router-link ref='tag' class="tags-view-item" :class="isActive(tag)?'active':''" v-for="tag in Array.from(visitedViews)" :to="tag.path" :key="tag.path" @contextmenu.prevent.native="openMenu(tag,$event)">
        {{(tag.title)}}
        <span  class='el-icon-close' @click.prevent.stop='closeSelectedTag(tag)'></span>
      </router-link>
    </scroll-pane>
    <!--<ul class='contextmenu' v-show="visible" :style="{left:left+'px',top:top+'px'}">-->
      <!--<li @click="closeSelectedTag(selectedTag)">关闭</li>-->
      <!--<li @click="closeOthersTags">关闭其他</li>-->
      <!--<li @click="closeAllTags">关闭所有</li>-->
    <!--</ul>-->
  </div>
</template>

   

 methods: {
      generateRoute() {
        if (this.$route.name) {
          return this.$route
        }
        return false
      },
      isActive(route) {//判断标签中的路由是否为当前路由
        return route.path === this.$route.path || route.name === this.$route.name
      },
      addViewTags() {
        const route = this.generateRoute()
        if (!route) {
          return false
        }
        this.$store.dispatch('addVisitedViews', route)
      },
      moveToCurrentTag() {
        const tags = this.$refs.tag
        this.$nextTick(() => {
          for (const tag of tags) {
            if (tag.to === this.$route.path) {
              this.$refs.scrollPane.moveToTarget(tag.$el)
              break
            }
          }
        })
      },
      closeSelectedTag(view) {//在此会执行提交store中delVisitedViews方法,需要在该方法执行完删除数组中的数据后,再进行更改路由;
        
        this.$store.dispatch('delVisitedViews', view).then((views) => {

          if (this.isActive(view)) {
            const latestView = views.slice(-1)[0]
            if (latestView) {
              this.$router.push(latestView.path)
            } else {
              this.$router.push('/')
            }
          }
        })
      },
      closeOthersTags() {
        this.$router.push(this.selectedTag.path)
        this.$store.dispatch('delOthersViews', this.selectedTag).then(() => {
          this.moveToCurrentTag()
        })
      },
      closeAllTags() {
        this.$store.dispatch('delAllViews')
        this.$router.push('/')
      },
      openMenu(tag, e) {
        this.visible = true
        this.selectedTag = tag
        this.left = e.clientX-180
        this.top = e.clientY-40
      },
      closeMenu() {
        this.visible = false
      }
    }
  }