接着之前的笔记,参考源码的布局,增加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 lang="scss" 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 src="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/global/js/all_async_search_f2dbc0a.js"> you will need to add a allowfullscreen attribute (+ webkitallowfullscreen and mozallowfullscreen).</iframe>
- .raw
Exposes the raw properties (prefixed if needed) used internally: requestFullscreen, exitFullscreen, fullscreenElement, fullscreenEnabled, fullscreenchange, fullscreenerror