whychdw
2020-08-18 bcf3980c538b7c8b3d913e64092bc874daed3abf
内容提交
20个文件已添加
5个文件已修改
776 ■■■■■ 已修改文件
package-lock.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/basic.css 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/m-elementui.css 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/theme/science-blue.css 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/404.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/dw_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/yuanchang_logo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/unCtrl.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ContentBox.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/FlexLayout.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PageHeader.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PageMenu.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PageNav.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/index.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/404/index.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/history.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/realTime.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/home.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/routes.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -10971,6 +10971,11 @@
        }
      }
    },
    "vue-router": {
      "version": "3.4.3",
      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz",
      "integrity": "sha512-BADg1mjGWX18Dpmy6bOGzGNnk7B/ZA0RxuA6qedY/YJwirMfKXIDzcccmHbQI0A6k5PzMdMloc0ElHfyOoX35A=="
    },
    "vue-style-loader": {
      "version": "4.1.2",
      "resolved": "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.2.tgz",
package.json
@@ -9,7 +9,9 @@
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^2.6.11"
    "element-ui": "^2.13.2",
    "vue": "^2.6.11",
    "vue-router": "^3.4.3"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.5.0",
public/index.html
@@ -3,7 +3,7 @@
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
src/App.vue
@@ -1,28 +1,19 @@
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
    <div id="app" class="el-science-blue">
        <router-view></router-view>
    </div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
  name: 'App',
  components: {
    HelloWorld
  }
    name: 'App',
}
</script>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
    box-sizing: border-box;
    height: 100vh;
}
</style>
src/assets/css/basic.css
New file
@@ -0,0 +1,15 @@
/*basic.css - Written by douchaoyang in September 2015*/
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0;}
body,button,input,select,textarea{font-family:"Microsoft Yahei",arial;}
body {
    overflow: hidden;
}
em,strong,th,i{font-style:normal;font-weight:normal;}
h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}
a{text-decoration:none;cursor:pointer;outline:none;}
table{border-collapse:collapse;border-spacing:0;}
ol,ul,li{list-style:none;}
fieldset,img{border:0;}
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
.clearfix{*zoom:1;}
/*basic end*/
src/assets/css/m-elementui.css
New file
@@ -0,0 +1,18 @@
.flex-layout .el-tabs__content {
    flex: 1;
    padding: 0;
}
.flex-layout .el-tabs__content .el-tab-pane {
    box-sizing: border-box;
    padding-top: 8px;
    height: 100%;
    overflow-x: hidden;
    overflow-y: hidden;
}
.add-m-menu.el-tabs--border-card>.el-tabs__header {
    padding-left: 48px;
    padding-right: 48px;
}
.el-drawer:focus {
    outline: none;
}
src/assets/css/theme/science-blue.css
New file
@@ -0,0 +1,75 @@
.el-science-blue {
    background: url("../../images/dw_bg.png") no-repeat;
    background-size: 100% 100%;
}
/* tabs */
.el-science-blue .el-tabs--border-card {
    background: transparent;
    border: 1px solid #0ea0aa;
}
.el-science-blue .el-tabs--border-card>.el-tabs__header {
    background-color: transparent;
}
.el-science-blue .el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
    background-color: #02b0bd;
}
.el-science-blue .el-tabs--border-card>.el-tabs__header {
    border-bottom: 1px solid #0ea0aa;
}
.el-science-blue .el-tabs--border-card>.el-tabs__header .el-tabs__item,
.el-science-blue .el-tabs--border-card>.el-tabs__header .el-tabs__item:hover {
    color: #FFFFFF;
}
.el-science-blue .tab-menu-left {
    border-right: 1px solid #0ea0aa;
    color: #FFFFFF;
}
.el-science-blue .tab-menu-left:hover {
    cursor: pointer;
    background-color:  #0ea0aa;
}
.el-science-blue .tab-menu-left:active {
    cursor: pointer;
    background-color:  #15E3F3;
}
.el-science-blue .el-tabs__nav-prev,
.el-science-blue .el-tabs__nav-next {
    color: #FFFFFF;
}
/* drawer */
.el-science-blue .el-drawer{
    background-color: #000000;
}
.el-science-blue .menu-content {
    color: #FFFFFF;
}
/* menu */
.el-science-blue .el-menu {
    color: #FFFFFF;
    border-right: none;
    background-color: #000000;
}
.el-science-blue .el-menu-item {
    color: rgb(255, 255, 255);
}
.el-science-blue .el-submenu__title {
    color: #FFFFFF;
}
.el-science-blue .el-submenu__title:hover,
.el-science-blue .el-menu-item:hover{
    background-color: rgb(61, 66, 70);
}
.el-science-blue .el-menu-item.is-active{
    color: rgb(255, 208, 75);
    background-color: rgb(37, 41, 43);
}
/* tree */
.el-science-blue .el-tree{
    background: none;
}
src/assets/images/404.png
src/assets/images/dw_bg.png
src/assets/images/yuanchang_logo.png
src/assets/js/unCtrl.js
New file
@@ -0,0 +1,22 @@
document.addEventListener('keydown', function (event) {
    if ((event.ctrlKey === true || event.metaKey === true)
        && (event.which === 61 || event.which === 107
            || event.which === 173 || event.which === 109
            || event.which === 187 || event.which === 189)) {
        event.preventDefault();
    }
}, false);
// Chrome IE 360
window.addEventListener('mousewheel', function (event) {
    if (event.ctrlKey === true || event.metaKey) {
        event.preventDefault();
    }
}, { passive: false });
//firefox
window.addEventListener('DOMMouseScroll', function (event) {
    if (event.ctrlKey === true || event.metaKey) {
        event.preventDefault();
    }
}, { passive: false });
src/components/ContentBox.vue
New file
@@ -0,0 +1,93 @@
<template>
    <div class="content-box" :class="{'no-border': noborder}">
        <div class="content-box-title" :class="getTitlePos">
            <slot name="title">{{title}}</slot>
        </div>
        <div class="content-box-content">
            <slot></slot>
        </div>
        <div class="content-box-footer">
            <slot name="footer"></slot>
        </div>
    </div>
</template>
<script>
export default {
    name: 'contentBox',
    props: {
        titleLeft: {
            type: Boolean,
            default: false
        },
        title: {
            type: String,
            default: '头部信息'
        },
        noborder: {
            type: Boolean,
            default: false
        },
    },
    computed: {
        getTitlePos: function() {
            return this.titleLeft?'txt-left': '';
        }
    },
    mounted(){
        //console.log(this.titleLeft);
    }
}
</script>
<style scoped>
.content-box {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    height: 100%;
    border: 1px solid #FFFFFF;
    border-radius: 8px;
    font-size: 16px;
}
.content-box.no-border {
    border: none;
}
.content-box-title {
    margin-top: 4px;
    margin-left: 4px;
    margin-right: 4px;
    padding-left: 10px;
    border-radius: 6px;
    font-size: 14px;
    text-align: center;
    background-image: linear-gradient(rgb(62, 189, 201), #016A95,#00638D, #006999, #009EE3);
    line-height: 32px;
    font-weight: bold;
}
.content-box-title.txt-left {
    text-align: left;
}
.content-box-content {
    flex: 1;
    margin-top: 4px;
    margin-left: 4px;
    margin-right: 4px;
    overflow-y: auto;
}
.footer .content-box-content {
    bottom: 32px;
}
.content-box-footer {
    margin-left: 4px;
    margin-right: 4px;
    padding-left: 10px;
    border-radius: 6px;
    font-size: 14px;
    text-align: center;
    line-height: 32px;
    font-weight: bold;
}
</style>
src/components/FlexLayout.vue
New file
@@ -0,0 +1,63 @@
<template>
    <div class="flex-layout" :class=getRootClass :style="getRootStyle">
        <div class="flex-layout-header">
            <slot name="header"></slot>
        </div>
        <div class="flex-layout-body">
            <slot></slot>
        </div>
        <div class="flex-layout-footer">
            <slot name="footer"></slot>
        </div>
    </div>
</template>
<script>
export default {
    props: {
        direction: {
            type: String,
            default: '',
        },
        height: {
            type: String,
            default: "100%",
        }
    },
    computed: {
        getRootClass: function() {
            return {
               'direction-row':  this.direction == 'row'?true: false
            };
        },
        getRootStyle: function() {
            return {
                'height': this.height,
            }
        },
    }
}
</script>
<style scoped>
.flex-layout {
    display: flex;
    flex-direction: column;
    height: 100%;
}
.flex-layout.direction-row {
    flex-direction: row;
}
.flex-layout.full-ht {
    height: 100%;
}
.flex-layout-body {
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;
}
</style>
src/components/PageHeader.vue
New file
@@ -0,0 +1,37 @@
<template>
    <div class="page-header">
        <div class="page-header-container">
            <flex-layout direction="row" >
                <div class="page-header-left" slot="header">
                    <img src="../assets/images/yuanchang_logo.png">
                    <span>蓄电池监控平台</span>
                </div>
            </flex-layout>
        </div>
    </div>
</template>
<script>
export default {
}
</script>
<style scoped>
.page-header-container {
    height: 60px;
}
.page-header-left {
    line-height: 60px;
}
.page-header-left img {
    width: 100px;
    vertical-align: middle;
}
.page-header-left span {
    font-size: 20px;
    color: #FFFFFF;
}
</style>
src/components/PageMenu.vue
New file
@@ -0,0 +1,84 @@
<template>
    <el-menu
    :default-active="acTabs">
        <template v-for="menu in menus">
            <el-submenu
            v-if="menu.childrens"
            :key="menu.name" :index="menu.name">
                <template slot="title">
                    <i v-if="menu.icon" :class="menu.icon"></i>
                    <span>{{menu.label}}</span>
                </template>
                <el-menu-item v-for="child in menu.childrens"
                :key="child.name" :index="child.name"
                @click="select(child)">
                    {{child.label}}
                </el-menu-item>
            </el-submenu>
            <el-menu-item v-else :index="menu.name" :key="menu.name"
            @click="select(menu)">
                <i class="el-icon-s-home"></i>
                <span slot="title">{{menu.label}}</span>
            </el-menu-item>
        </template>
    </el-menu>
</template>
<script>
export default {
    props: {
        acTabs: {
            type: String,
            default: '',
        }
    },
    data() {
        return {
            menus: [
                {
                    label: '首页',
                    name: 'index',
                    src: '#/index',
                    icon: 'el-icon-s-home',
                    closable: false,
                },
                {
                    label: '测试数据',
                    name: 'testData',
                    src: '',
                    icon: 'el-icon-s-data',
                    closable: false,
                    childrens: [
                        {
                           label: '实时监测',
                            name: 'realTime',
                            src: '#/real-time',
                            closable: true,
                        },
                        {
                           label: '历史数据',
                            name: 'history',
                            src: '#/history',
                            closable: true,
                        },
                    ]
                }
            ],
        }
    },
    methods: {
        select(data) {
            if(data.name !== this.acTabs) {
                this.$emit('select', data);
            }else {
                console.log('菜单已激活');
            }
        }
    }
}
</script>
<style scoped>
</style>
src/components/PageNav.vue
New file
@@ -0,0 +1,17 @@
<template>
    <flex-layout direction="row">
    </flex-layout>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
src/components/index.js
New file
@@ -0,0 +1,5 @@
import Vue from 'vue'
import FlexLayout from './FlexLayout.vue'
// 注册全局自定义组件
Vue.component("FlexLayout", FlexLayout);
src/main.js
@@ -1,8 +1,19 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './assets/css/m-elementui.css'
import "./assets/css/theme/science-blue.css"
import './components'
import './assets/css/basic.css'
import './assets/js/unCtrl'
Vue.use(ElementUI);
Vue.config.productionTip = false
new Vue({
  render: h => h(App),
    router,
    render: h => h(App),
}).$mount('#app')
src/pages/404/index.vue
New file
@@ -0,0 +1,28 @@
<template>
    <div class="not-found">
        <div class="not-found-content">
            <div class="content-container">
                <img src="../../assets/images/404.png">
            </div>
        </div>
    </div>
</template>
<style scoped>
.not-found  {
    display: flex;
    height: 100%;
    justify-content: center; /* 水平居中 */
    align-items: center;     /* 垂直居中 */
}
.content-container {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    display: inline-block;
    margin: 0 auto;
}
</style>
src/pages/dataTest/history.vue
New file
@@ -0,0 +1,22 @@
<template>
    <flex-layout direction="row" class="page-history">
        <div style="width:360px" slot="header">
            树状导航
        </div>
        历史内容
    </flex-layout>
</template>
<script>
export default {
}
</script>
<style scoped>
.page-history {
    color: #FFFFFF;
}
</style>
src/pages/dataTest/realTime.vue
New file
@@ -0,0 +1,22 @@
<template>
    <flex-layout direction="row" class="page-real-time">
        <div style="width:360px" slot="header">
        </div>
        实时内容
    </flex-layout>
</template>
<script>
export default {
}
</script>
<style scoped>
.page-real-time {
    color: #FFFFFF;
}
</style>
src/pages/home.vue
New file
@@ -0,0 +1,123 @@
<template>
    <flex-layout class="page-home">
        <page-header slot="header" :class="{'show-drawer': drawer}"></page-header>
        <div class="page-home-content" :class="{'show-drawer': drawer}">
            <div class="tab-menu-left" @click="drawer=true">
                <i class="el-icon-s-operation"></i>
            </div>
            <el-tabs v-model="acTabs" type="border-card"
            @tab-remove="removeTab"
            class="no-selected full-height add-m-menu flex-layout">
                <el-tab-pane v-for="item in tabs" :key="item.name"
                :label="item.label" :name="item.name" :closable="item.closable">
                    <iframe :src="item.src" width="100%" height="100%" frameborder="0" scrolling="no"></iframe>
                </el-tab-pane>
            </el-tabs>
        </div>
        <el-drawer
        title="我是标题"
        :withHeader="false"
        :visible.sync="drawer"
        size="360px"
        direction="ltr">
            <page-menu
            :ac-tabs="acTabs"
            @select="changeTab"></page-menu>
        </el-drawer>
    </flex-layout>
</template>
<script>
import PageHeader from '../components/PageHeader.vue'
import PageMenu from '../components/PageMenu.vue'
export default {
    components: {
        PageHeader,
        PageMenu
    },
    data() {
        return {
            acTabs: 'index',
            tabs: [
                {
                    label: '首页',
                    name: 'index',
                    src: '#/index',
                    closable: false,
                },
            ],
            drawer: false,
        }
    },
    methods: {
        removeTab(targetName) {
            let tabs = this.tabs;
            let activeName = this.acTabs;
            if (activeName === targetName) {
                tabs.forEach((tab, index) => {
                    if (tab.name === targetName) {
                        let nextTab = tabs[index + 1] || tabs[index - 1];
                        if (nextTab) {
                            activeName = nextTab.name;
                        }
                    }
                });
            }
            this.acTabs = activeName;
            this.tabs = tabs.filter(tab => tab.name !== targetName);
        },
        changeTab(menu) {
            let tabs = this.tabs;
            // 检测name是否已经存在tabs内
            let notIn = true;
            tabs.forEach(item=>{
                if(item.name == menu.name) {
                    notIn = false;
                }
            });
            // 不在, 添加menu到tabs中
            if(notIn) {
                tabs.push(menu);
            }
            // 设置激活的导航
            this.acTabs = menu.name;
        },
    }
}
</script>
<style scoped>
.flex-layout {
    display: flex;
    height: 100%;
    box-sizing: border-box;
}
.page-home-content {
    position: relative;
    height: 100%;
}
.el-science-blue .tab-menu-left {
    position: absolute;
    box-sizing: border-box;
    width: 48px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    z-index: 1;
}
.no-selected {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.show-drawer {
    transform: translateX(360px)
}
</style>
src/pages/index.vue
New file
@@ -0,0 +1,65 @@
<template>
    <flex-layout direction="row" class="page-index">
        <content-box title="站点列表"
        slot="header" style="width:320px">
            <el-tree
            class="filter-tree"
            :data="data"
            :props="defaultProps"
            ref="tree">
            </el-tree>
        </content-box>
        <div class="map">地图</div>
        <div slot="footer" style="width:320px">
            4个饼状图
        </div>
    </flex-layout>
</template>
<script>
import ContentBox from '../components/ContentBox'
export default {
    components: {
        ContentBox
    },
    data() {
        return {
            data: [
                {
                    id: 1,
                    label: '一级 1',
                    children: [
                        {
                            id: 4,
                            label: '二级 1-1',
                            children: [
                                {
                                    id: 9,
                                    label: '三级 1-1-1'
                                },
                                {
                                    id: 10,
                                    label: '三级 1-1-2'
                                }
                            ]
                        }
                    ]
                }
            ],
            defaultProps: {
                children: 'children',
                label: 'label'
            }
        }
    }
}
</script>
<style scoped>
.page-index {
    color: #FFFFFF;
}
</style>
src/router/index.js
New file
@@ -0,0 +1,12 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter);
const router = new VueRouter({
    routes
});
export default router;
src/router/routes.js
New file
@@ -0,0 +1,30 @@
export default [
    {
        path: '/home',
        meta: {},
        component: (resolve)=>require(['../pages/home.vue'], resolve)
    },
    {
        path: '/index',
        meta: {},
        component: (resolve)=>require(['../pages/index.vue'], resolve)
    },
    {
        path: '/real-time',
        meta: {},
        component: (resolve)=>require(['../pages/dataTest/realTime.vue'], resolve)
    },
    {
        path: '/history',
        meta: {},
        component: (resolve)=>require(['../pages/dataTest/history.vue'], resolve)
    },
    {
        path: '*',
        name: '',
        meta: {
            crumb: 'NotFound'
        },
        component: (resolve)=>require(['@/pages/404/index.vue'], resolve)
    },
];