vue-element-admin学习笔记--权限加载及自定义布局,4

接着之前的笔记,参考源码的布局,增加Breadcrumb组件及screenfull的全屏功能。

Breadcrumb 面包屑导航

需要引入Breadcrumb, BreadcrumbItem。看了下官方文档,有官方组件,先自己弄一下。Elemet-ui中的图标分隔符例子如下:

<el-breadcrumb separator-class="el-icon-arrow-right">
  <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
  <el-breadcrumb-item>活动管理</el-breadcrumb-item>
  <el-breadcrumb-item>活动列表</el-breadcrumb-item>
  <el-breadcrumb-item>活动详情</el-breadcrumb-item>
</el-breadcrumb>

思路还觉还好,获取当前的路由,然后遍历到顶层,在组件内生成例子中的结构就可以。

在src>components下新建Breadcrumb组件,并在NavBar中使用下。为了样式统一,根据elemet-vue-admin中的样式配置一下。Breadcrumb>index.vue代码如下(下把样子调整出来):

<template>
  <div>
    <el-breadcrumb class="app-breadcrumb" separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>活动管理</el-breadcrumb-item>
      <el-breadcrumb-item>活动列表</el-breadcrumb-item>
      <el-breadcrumb-item>活动详情</el-breadcrumb-item>
    </el-breadcrumb>
  </div>
</template>

<script>
export default {};
</script>

<style  scoped>
.app-breadcrumb.el-breadcrumb {
  display: inline-block;
  font-size: 14px;
  line-height: 50px;
  margin-left: 8px;

  .no-redirect {
    color: #97a8be;
    cursor: text;
  }
}
</style>

下面需要根据路由生成面包屑导航,同时如果点击面包屑导航的链接时,左侧的Sidebar要选中相应的菜单。

由于route.js中多级菜单都配置了meta属性及name,导致面包屑导航显示不对,修改后左侧sidebar菜单路由中有,页面显示不加载发现是sidebarItem中,判断只有一个子节点处的的代码写错了:

原代码

<item
    :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
    :title="item.meta.title"
/>

修改后代码

<item
    :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
    :title="onlyOneChild.meta.title"
/>

修改route.js,将每级菜单的meta规范下,并增加table的多级路由嵌套菜单,单独提取出来。在src>router下新建modules下新建table.js文件,内容如下

import Layout from "@/layouts";

const tableRouter = {
  path: "/table",
  component: Layout,
  name: "table",
  meta: {
    title: "Table表格",
    icon: "table",
    affix: true,
    roles: ["user"]
  },
  alwaysShow: true,
  redirect: "/table/basic-table",
  children: [
    {
      path: "/table/basic-table",
      name: "basicTable",
      meta: { title: "基础表格", icon: "table", roles: ["user"] },
      component: () =>
        import(/* webpackChunkName: "table" */ "@/views/tables/basictable.vue")
    },
    {
      path: "/table/page-table",
      name: "pageTable",
      meta: { title: "分页表格", icon: "table", roles: ["user"] },
      redirect: "/table/page-table0",
      component: { render: h => h("router-view") },
      children: [
        {
          path: "/table/page-table0",
          name: "pageTable0",
          meta: { title: "分页表格0", icon: "table", roles: ["user"] },
          component: () =>
            import(
              /* webpackChunkName: "table" */ "@/views/tables/pagetable/pagetable0.vue"
            )
        },
        {
          path: "/table/page-table1",
          name: "pageTable1",
          meta: { title: "分页表格1", icon: "table", roles: ["user"] },
          component: () =>
            import(
              /* webpackChunkName: "table" */ "@/views/tables/pagetable/pagetable1.vue"
            )
        }
      ]
    }
  ]
};
export default tableRouter;

最后在router>index.js文件中引入即可。测试页面时发现有些链接在面包屑导航上跳转正常,有的报错。经过排查发现路由中有的缺少了"redirect"属性配置,修改配置例子如下:

 {
    path: "/form",
    // component: { render: h => h("router-view") },
    component: Layout,
    name: "form",
    redirect: "/form/basic-form",
    meta: {
      title: "Form表单",
      icon: "form",
      affix: true,
      roles: ["admin", "user"]
    },
    children: [
      {
        path: "/form/basic-form",
        name: "basicForm",
        meta: {
          title: "Form基础表单1",
          icon: "form",
          affix: true,
          roles: ["admin", "user"]
        },
        component: () =>
          import(/* webpackChunkName: "form" */ "@/views/forms/basicForm.vue")
      }
     ....
    ]
  }

但发现面包屑到导航中的首页返回还是不生效,无法获取首页的redirect属性,没有找到原因。于是修改sr>compones>Breadcrumb>index.vue中的getBreadlist() 方法,在match的时候增加redirect属性,如下所示:

 if (!this.isDashboard(first)) {
        matched = [
          {
            path: "/",
            meta: { title: "首页" },
            redirect: "/dashboard"
          }
        ].concat(matched);
      }
Screenfull 全屏功能

此功能依赖screenfull.js这个库,先安装下

yarn add screenfull

参考vue-element-admin中源码,先添加一个div并添加相应的样式。在src>components下新建screenfull组件。组件逻辑需要考虑

  • 加载的时候是否全屏,根据是否全屏判断下按钮的SVG加载
  • 初始化和销毁的时候监听组件的状态

src>components>Screenfull组件如下,需要注意的是screenfull的API有所变化,"Rename screenfull.enabled to screenfull.isEnabled"vue-element-admin的源码中为"screenfull.enabled

<template>
  <div>
    <svg-icon
      :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
      @click="click"
    />
  </div>
</template>

<script>
import screenfull from "screenfull";

export default {
  name: "Screenfull",
  data() {
    return {
      isFullscreen: false
    };
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    this.destroy();
  },
  methods: {
    click() {
      if (!screenfull.isEnabled) {
        this.$message({
          message: "you browser can not work",
          type: "warning"
        });
        return false;
      }
      screenfull.toggle();
    },
    change() {
      this.isFullscreen = screenfull.isFullscreen;
    },
    init() {
      if (screenfull.isEnabled) {
        screenfull.on("change", this.change);
      }
    },
    destroy() {
      if (screenfull.isEnabled) {
        screenfull.off("change", this.change);
      }
    }
  }
};
</script>

screenfull.js的API如下:

  • .request()

Make an element fullscreen.Accepts a DOM element. Default is . If called with another element than the currently active, it will switch to that if it's a decendant.

If your page is inside an iframe you will need to add a allowfullscreen attribute (+ webkitallowfullscreen and mozallowfullscreen).

Keep in mind that the browser will only enter fullscreen when initiated by user events like click, touch, key.Returns a promise that resolves after the element enters fullscreen."

  • .exit()

Brings you out of fullscreen.Returns a promise that resolves after the element exits fullscreen.

  • .toggle()

Requests fullscreen if not active, otherwise exits.Returns a promise that resolves after the element enters/exits fullscreen.

  • .on(event, function)

Events: 'change' | 'error'.Add a listener for when the browser switches in and out of fullscreen or when there is an error.

  • .off(event, function)

Remove a previously registered event listener.

  • .onchange(function)

Alias for .on('change', function)

  • .onerror(function)

Alias for .on('error', function)

  • .isFullscreen

Returns a boolean whether fullscreen is active.

  • .element

Returns the element currently in fullscreen, otherwise null.

  • .isEnabled

Returns a boolean whether you are allowed to enter fullscreen. If your page is inside an iframe you will need to add a allow fullscreen attribute (+ webkitallowfullscreen and mozallowfullscreen).

  • .raw

Exposes the raw properties (prefixed if needed) used internally: requestFullscreen, exitFullscreen, fullscreenElement, fullscreenEnabled, fullscreenchange, fullscreenerror