一、界面样式
说一下这个界面的设计要素:
- 兼顾1366×768,在1920×1080上效果更好。
- 该界面包含一个欢迎页。
- 左侧树报表支持二、三级节点同级排序。不过还没有处理滚动样式。
- 右侧还算标准和赏心悦目,就这样了。
二、PC端框架页代码
- src/views/layout/pc/index.vue
<template>
<div class="Dev-Layout">
<main-content></main-content>
<nav-bar></nav-bar>
<head-bar></head-bar>
</div>
</template>
<script>
import HeadBar from './HeadBar.vue'
import NavBar from './NavBar.vue'
import MainContent from './MainContent.vue'
export default {
components: {
HeadBar,
NavBar,
MainContent
}
}
</script>
<style lang="scss" scoped>
.Dev-Layout {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #f4f5f7;
}
</style>
- src/views/layout/pc/HeadBar.vue
<template>
<div class="Dev-Layout-HeadBar">
<div class="logo" :style="`background-image: url(${logoPng})`"/>
<div class="menu">
<div class="active">仪表盘</div>
<div>数据源</div>
<div>数据集</div>
<div>项目设置</div>
</div>
<div class="right-menu">
<div>
<el-badge :is-dot="true"><i class="el-icon-bell"></i></el-badge>
</div>
<div><i class="el-icon-notebook-2"></i></div>
<div style="font-size: 13px">
<el-dropdown>
<span class="el-dropdown-link">
Hi, sbling <i class="el-icon-arrow-down"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>修改密码</el-dropdown-item>
<el-dropdown-item>关于</el-dropdown-item>
<el-dropdown-item divided @click.native="logout">退出系统</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</template>
<script>
import logoPng from '@/assets/img/dev/logo.png'
import Cookies from 'js-cookie'
export default {
data () {
return {
logoPng: logoPng
}
},
methods: {
logout () {
Cookies.remove('token')
Cookies.remove('account')
this.$router.push('/login')
}
}
}
</script>
<style lang="scss" scoped>
.Dev-Layout-HeadBar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 47px;
background-color: #f1f4f7;
border-bottom: 1px solid #e4e4e4;
> .logo {
width: 86px;
height: 28px;
background-repeat: no-repeat;
background-size: 100% 100%;
float: left;
margin-top: 9px;
margin-left: 25px;
}
> .menu {
float: left;
margin-left: 109px;
> div {
float: left;
font-size: 14px;
color: #303133;
padding: 0 20px;
height: 46px;
line-height: 44px;
transition: all .2s;
cursor: pointer;
&:hover {
background-color: #e1e2e6;
}
&.active {
background-color: #fff;
border-bottom: 3px solid #409eff;
}
}
}
> .right-menu {
height: 46px;
float: right;
padding-right: 10px;
> div {
float: left;
margin-right: 20px;
height: 22px;
line-height: 20px;
color: #606266;
padding: 12px 0;
cursor: pointer;
font-size: 14px;
}
}
}
</style>
- src/views/layout/pc/NavBar.vue
<template>
<div class="Dev-Layout-NavBar">
<div class="search">
<el-input size="small">
<el-button
slot="append"
type="primary"
icon="el-icon-search"
/>
</el-input>
</div>
<div class="projects" style="overflow: scroll;">
<el-tree
draggable
:indent="5"
:props="{ children: 'children', label: 'label' }"
:data="data"
:render-content="renderContent"
:allow-drop="allowDrop"
@node-click="handleNodeClick"
@node-drop="sort"
/>
</div>
</div>
</template>
<script>
export default {
data () {
return {
data: [{
id: 0,
label: 'PC端',
icon: 'el-icon-monitor',
aboveId: null,
level: 1,
children: [{
id: 11,
label: '区域销售报告区域销售报告区域销售报告区域销售报告区域销售报告',
icon: 'el-icon-menu',
aboveId: 0,
level: 2,
children: [{
label: '区域销售报告',
icon: 'el-icon-tickets',
aboveId: 11,
level: 3
}, {
label: '区域销售报告2',
icon: 'el-icon-tickets',
aboveId: 11,
level: 3
}]
}]
}, {
id: 1,
label: '移动端',
icon: 'el-icon-mobile',
aboveId: null,
level: 1,
children: [{
id: 12,
label: '区域销售报告',
icon: 'el-icon-menu',
aboveId: 1,
level: 2,
children: [{
label: '区域销售报告',
icon: 'el-icon-tickets',
aboveId: 12,
level: 3
}]
}]
}, {
id: 2,
label: '数字大屏',
icon: 'el-icon-data-analysis',
aboveId: null,
level: 1,
children: [{
id: 13,
label: '区域销售报告',
icon: 'el-icon-menu',
aboveId: 2,
level: 2,
children: [{
label: '区域销售报告',
icon: 'el-icon-tickets',
aboveId: 13,
level: 3
}]
}]
}, {
id: 3,
label: '报告',
icon: 'el-icon-printer',
aboveId: null,
level: 1,
children: [{
id: 14,
label: '区域销售报告',
icon: 'el-icon-menu',
aboveId: 3,
level: 2,
children: [{
label: '区域销售报告',
icon: 'el-icon-tickets',
aboveId: 14,
level: 3
}]
}]
}]
}
},
methods: {
handleNodeClick () {
},
// 自定义树节点
renderContent (h, { node, data, store }) {
return (
<div class="tree-node-item">
<div class="tree-node-name" title={node.label}>
<i class={data.icon}></i> {node.label}
</div>
{data.level !== 3 && (
<div class="tree-node-plus"><i class="el-icon-plus"></i></div>
)}
<div class="tree-node-more"><i class="el-icon-more"></i></div>
</div>
)
},
// 树节点拖拽事件
allowDrop (draggingNode, dropNode, type) {
if (!draggingNode.data.aboveId) {
return false
}
if (draggingNode.data.level === dropNode.data.level) {
if (draggingNode.data.aboveId === dropNode.data.aboveId) {
return type === 'prev' || type === 'next'
}
} else {
return false
}
},
// 树节点拖拽后重新排序
sort (draggingNode, dropNode, type, event) {
let obj = {
aboveId: '',
arr: []
}
obj.aboveId = dropNode.data.aboveId
for (let item of dropNode.parent.childNodes) {
obj.arr.push(item.data.id)
}
}
}
}
</script>
<style lang="scss">
.Dev-Layout-NavBar {
position: absolute;
top: 47px;
left: 0;
bottom: 0;
width: 250px;
border-right: 1px solid #e4e4e4;
padding: 12px 10px;
background-color: #fff;
> .search {
.el-input-group__append {
padding: 0 10px;
}
}
> .projects {
margin: 0 -10px;
padding: 10px 0;
height: calc(100vh - 91px);
.tree-node-item {
height: 24px;
line-height: 24px;
flex: 1;
display: flex;
flex-direction: row;
.tree-node-name {
flex: 1;
font-size: 14px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
width: 100px;
}
.tree-node-plus {
text-align: center;
width: 24px;
color: #898989;
opacity: 0;
}
&:hover {
.tree-node-plus {
opacity: 1;
}
}
.tree-node-more {
text-align: center;
width: 24px;
color: #898989;
opacity: 0;
}
&:hover {
.tree-node-more {
opacity: 1;
}
}
}
}
}
</style>
- src/views/layout/pc/MainContent.vue
<template>
<div class="Dev-Layout-MainContent">
<!-- <el-empty description="Hi,admin,欢迎使用库铂BI。"></el-empty> -->
<div class="filter-bar">
<el-select v-model="value" placeholder="请选择" size="small">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="value" placeholder="请选择" size="small">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button type="primary" size="mini" style="height: 32px;float: right;"><span>重置</span></el-button>
</div>
<div class="chart-container">
<div class="chart-item"></div>
<div class="chart-item"></div>
<div class="chart-item"></div>
<div class="chart-item"></div>
<div class="chart-item"></div>
<div class="chart-item"></div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}],
value: ''
}
}
}
</script>
<style lang="scss" scoped>
.Dev-Layout-MainContent {
position: absolute;
top: 47px;
left: 250px;
right: 0px;
bottom: 0px;
background-color: #f2f2f2;
> .filter-bar {
background-color: #fff;
border-bottom: 1px solid #dfe4ed;
height: 52px;
padding: 10px;
}
> .chart-container {
height: calc(100vh - 99px);
padding: 2px;
> .chart-item {
width: 300px;
height: 200px;
margin: 2px;
background-color: #fff;
border: 1px solid #ebebeb;
float: left;
border-radius: 4px;
}
}
}
</style>
- router
{
path: '/dev',
name: '桌面端',
component: () => import('@/views/layout/dev')
},