vue页面拉动条处理+动态主题样式处理

<template>
  <div class="aseet-border"
       :class="theme[themeSelected].value">
    <!-- 头部框格 -->
    <div class="aseet-header">
      <div class="header-left">
        <img src="~@/assets/index/logo.png"
             alt="">
        <span>{{ title }}</span>
      </div>
      <div class="header-right">
        <span class="action"
              style="margin-right: 40px;"
              title="返回"
              @click="() => $router.go(-1)">
          <a-icon type="rollback"></a-icon>
        </span>
        <span class="action"
              :title="fullscreen ? '退出全屏' : '全屏显示'"
              @click="screen">
          <a-icon :type="getFullscreenIcon"></a-icon>
        </span>
        <span class="action"
              title="刷新"
              @click="() => $router.go(0)">
          <a-icon type="reload"></a-icon>
        </span>
        <a-popover :title="null"
                   trigger="hover"
                   overlayClassName="popoverClass">
          <template slot="content">
            <zhong></zhong>
          </template>
          <span class="action">
            <a-icon type="clock-circle"></a-icon>
          </span>
        </a-popover>
      </div>
    </div>
    <div class="aseet-content">
      <!-- 侧边栏标签 -->
      <div class="aseet-tag">
        <ul class="left-toolbar-container">
          <li v-for="(item, index) in tagTypeArray"
              :key="index"
              :class="tagSelect===item.dictValue?'selected':null"
              @click="chosseTagitem(item.dictValue)">{{ item.dictLabel }}
            <a-icon type="radar-chart" />
          </li>
        </ul>
      </div>
      <!-- 局部内容 -->
      <div class="aseet-center"
           ref="assetSide">
        <!-- 局部头 -->
        <div :style="{ height: topHeight }"
             class="aseet-top">
          <!-- 标签内容 -->
          <div class="tag-content">
            <tag-menu @select="handleTagsParam"
                      ref="tagMenu"></tag-menu>
          </div>
          <!-- ip内容 -->
          <div class="ip-content"></div>
        </div>
        <!-- 局部底 -->
        <div class="aseet-bottom"
             ref="bottomSide">
          <!-- 拉动条 -->
          <div v-show="isShow"
               ref="resizer"
               class="ma-resizer-y"
               @mousedown="doResizeY"></div>
          <!-- 底部内容--组件填充 -->
          <div class="bottom-content"
               v-show="isShow"
               ref="content"
               :style="{ height: bottomHeight }">
            <div class="bottom-header">
              <div class="left">
                <span>{{ bottomToolSelect | bottomFilter(bottomToolbars) }}信息展示</span>
              </div>
              <a-icon class="icon-min"
                      @click="clearHight"
                      type="minus" />
            </div>
          </div>
          <!-- 底部标签 -->
          <div class="bottom-tag">
            <ul class="ma-toolbar-container">
              <li v-for="(item, index) in bottomToolbars"
                  :key="index"
                  :class="bottomToolSelect===item.id?'selected':null"
                  @click="chosseBottomTagitem(item)">{{ item.name }}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <!-- 底部框格 -->
    <div class="aseet-footer">
      <span class="message">{{ clickMessage }}</span>
      <span class="theme"
            title="点击切换主题"
            @click="changeTheme(themeSelected)">{{ theme[themeSelected].name }}</span>
    </div>
  </div>
</template>

<script>
import VenusScroll from '@/components/pts/Scroll'
import { mapGetters } from 'vuex'
import { getDictArray } from '@/utils/dict'
import TagMenu from './modules/TagMenu.vue'
import Zhong from './modules/zhong.vue'
export default {
  name: 'AssetShow',
  components: {
    VenusScroll,
    TagMenu,
    Zhong
  },
  mounted() {
    const self = this
    window.onresize = () => {
      const assetSide = self.$refs.assetSide.getClientRects()[0].height
      const bottomSide = self.$refs.bottomSide.getClientRects()[0].height
      if (bottomSide === 31) {
        return
      }
      this.topHeight = (assetSide - bottomSide) + 'px'
    }
  },
  data() {
    return {
      /** 初始化页面参数 */
      fullscreen: false,
      theme: [
        {
          id: 1,
          name: '白色主题',
          value: 'white-theme'
        },
        {
          id: 2,
          name: '黑色主题',
          value: 'black-theme'
        }
      ],
      clickMessage: '欢迎进入资产管理首页!', // 页尾提示
      title: '资产管理', // 标题
      bottomHeight: '300px',
      topHeight: 'calc(100% - 30px)',
      /** 数据 */
      tagTypeArray: [], // 左侧标签类型数据
      bottomToolbars: [
        {
          id: 1,
          name: '端口'
        },
        {
          id: 2,
          name: '漏洞'
        },
        {
          id: 3,
          name: '客户端'
        }
      ],
      /* 参数控制 start */
      themeSelected: 1, // 主题index值
      bottomToolSelect: 0, // bottomToolbars---id
      isShow: false, // 拉动条填充
      tagSelect: '1', // 标签类型值dictValue
      tagIds: []// 资产标签值[ids]
    }
  },
  watch: {
  },
  filters: {
    dictFilter(data, map) {
      return map[data] && map[data].text || ''
    },
    bottomFilter(data, bottomToolbars) {
      if (bottomToolbars[data - 1]) {
        return bottomToolbars[data - 1].name
      }
      return ''
    }
  },
  computed: {
    ...mapGetters(['scrollInfo', 'backTop', 'backToView']),
    getFullscreenIcon: function () {
      return this.fullscreen ? 'fullscreen-exit' : 'fullscreen'
    }
  },
  created() {
    this.init()
  },
  methods: {
    handleTagsParam(value) { // 资产标签选中参数回调
      this.tagIds = value
    },
    changeTheme(index) { // 主题改动
      if (index === this.theme.length - 1) {
        this.themeSelected = 0
      } else {
        this.themeSelected = this.themeSelected + 1
      }
    },
    chosseTagitem(value) { // 侧边tag选中
      this.tagSelect = value
    },
    chosseBottomTagitem(item) { // 底部tag选中方法
      this.bottomToolSelect = item.id
      this.isShow = true
      this.refreshHight()
    },
    init() { // 初始化页面
      // 默认选中第一个tag
      this.chosseTagitem(this.tagSelect)
      getDictArray('t_penetration_tag_type').then(data => {
        this.tagTypeArray = data
      })
    },
    refreshHight() { // 重置拉动条高度
      const assetSide = this.$refs.assetSide.getClientRects()[0].height
      let bottomSide = this.$refs.bottomSide.getClientRects()[0].height
      if (bottomSide === 31) {
        bottomSide = 330
      }
      this.topHeight = (assetSide - bottomSide) + 'px'
    },
    clearHight() { // 清除拉动条
      this.topHeight = 'calc(100% - 30px)'
      this.bottomHeight = '300px'
      this.isShow = false
      this.bottomToolSelect = 0
    },
    doResizeY() { // 拉动条处理
      const box = this.$refs.content.getClientRects()[0]
      const assetSide = this.$refs.assetSide.getClientRects()[0].height
      document.onmousemove = e => {
        if (e.clientY > 150) {
          var move = box.height - (e.clientY - box.y)
          if (move > 30) {
            this.bottomHeight = move + 'px'
            this.topHeight = (assetSide - move - 30) + 'px'
          }
        }
      }
      document.onmouseup = () => {
        document.onmousemove = document.onmouseup = null
        this.$refs.resizer.releaseCapture && this.$refs.resizer.releaseCapture()
      }
    },
    screen() {
      const element = document.documentElement
      if (this.fullscreen) {
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      } else {
        if (element.requestFullscreen) {
          element.requestFullscreen()
        } else if (element.webkitRequestFullScreen) {
          element.webkitRequestFullScreen()
        } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen()
        } else if (element.msRequestFullscreen) {
          // IE11
          element.msRequestFullscreen()
        }
      }
      this.fullscreen = !this.fullscreen
    }
  }
}

</script>
<style lang="less" scoped>
@import 'index';
</style>
<style lang="less">
.popoverClass {
  .ant-popover-inner {
    background: #3c3f41;
    border: 0;
  }
  .ant-popover-arrow {
    border-color: #3c3f41 !important;
    background: #3c3f41 !important;
  }
}
</style>

less

@import 'theme.less';
@ty-border:var(--ty-border);/* 边框颜色 */
@selected-background: var(--selected-background);/* 选中时背景颜色 */
@hover-background:  var(--hover-background);/* 悬浮时背景颜色 */
@tag-color:var(--tag-color);/* 标签字体颜色 */
@ip-content-backgrund:var(--ip-content-backgrund);/* 资产页面背景 */
@ty-color: var(--ty-color);/* 全局框内颜色 */
.aseet-border{
  width: 100%;
  min-width: 1200px;
  height:100vh;
  min-height:800px;
  color: @tag-color;
  .aseet-header{
    height: 33px;
    width: 100%;
    background: @ty-color;
    border-bottom: 1px solid @ty-border;
    position: relative;
    .header-left{
      width: 50%;
      height: 100%;
      position: absolute;
      left: 0;
      img{
        position: absolute;
        width: 20px;
        left: 3px;
        top: 7px;
      }
      span{
        line-height: 33px;
        left: 25px;
        position: absolute;
      }
    }
    .header-right{
      width: 50%;
      height: 100%;
      position: absolute;
      right: 0;
      .action{
        cursor: pointer;
        transition: all 0.3s;
        width: 30px;
        height: 30px;
        line-height: 33px;
        margin-right: 6px;
        display: inline-block;
        float: right;
        text-align: center;
        font-size: 16px;
        &:hover {
          opacity: 0.6;
        }
      }
    }
    
  }
  .aseet-content{
    height: calc(100% - 33px - 30px);
    width: 100%;
    background: @ty-color;
    position: relative;
    .aseet-tag{
      height: 100%;
      width: 22px;
      position: absolute;
      left: 0px;
      .left-toolbar-container{
        padding: 0;
        background: @ty-color;
        border-right: 1px solid @ty-border;
        width: 100%;
        height: 100%;
        li {
          padding-top: 10px;
          font-size: 12px;
          font-family: 'Consolas', '微软雅黑';
          width: 22px;
          height: 100px;
          cursor: pointer;
          letter-spacing: 2px;
          text-align: center;
          &:hover{
            background: @hover-background;
          }
        }
        .selected{
          background: @selected-background;
          &:hover{
            background: @selected-background;
          }
        }
      }
    }
    .aseet-center{
      height: 100%;
      width: calc(100% - 22px);
      border-right:1px solid @ty-border;
      position: absolute;
      right: 0;
      .aseet-top{
        width: 100%;
        position: absolute;
        top: 0;
        .tag-content{
          position: absolute;
          left: 0;
          width: 272px;
          height: 100%;
          border-right:1px solid @ty-border;
        }
        .ip-content{
          position: absolute;
          right: 0;
          width: calc(100% - 272px);
          height: 100%;
          background: @ip-content-backgrund;
        }
      }
      .aseet-bottom{
        width: 100%;
        border-top: 1px solid @ty-border;
        position: absolute;
        bottom: 0;
        .ma-resizer-y {
          position: absolute;
          width: 100%;
          height: 10px;
          margin-top: -5px;
          background: none;
          cursor: n-resize;
        }
        .bottom-content{
          width: 100%;
          .bottom-header{
            height: 25px;
            border-bottom: 1px solid @ty-border;
            .left{
              width: 50%;
              float: left;
              height: 100%;
              line-height: 25px;
              span{
                color: @tag-color;
                margin-left: 10px;
              }
            }
            .icon-min{
              float: right;
              margin-right: 10px;
              line-height:25px;
            }
          }
        }
        .bottom-tag{
          height: 30px;
          width: 100%;
          border-top: 1px solid @ty-border;
          position: relative;
          .ma-toolbar-container{
            padding: 0;
            background: @ty-color;
            border-right: 1px solid @ty-border;
            width: 100%;
            height: 100%;
            li {
              width: 100px;
              height: 29px;
              line-height: 29px;
              list-style: none;
              float: left;
              cursor: pointer;
              letter-spacing: 2px;
              text-align: center;
              &:hover{
                background: @hover-background;
              }
            }
            .selected{
              background: @selected-background;
              &:hover{
                background: @selected-background;
              }
            }
          }
        }
      }
    }
  }
  .aseet-footer{
    border-top: 1px solid @ty-border;
    height: 30px;
    width: 100%;
    background: @ty-color;
    position: absolute;
    bottom: 0;
    .message{
      line-height: 30px;
      margin-left: 20px;
    }
    .theme{
      right: 30px;
      line-height: 30px;
      position: absolute;
      cursor: pointer;
    }
  }
}

动态主题

/* 白色主题 */
.white-theme {
  --ty-color:#f2f2f2;/* 全局框内颜色 */
  --ty-border:#cdcdcd;/* 边框颜色 */
  --selected-background: #bdbdbd;/* 选中时背景颜色 */
  --hover-background: #d9d9d9;/* 悬浮时背景颜色 */
  --tag-color:#000;/* 标签字体颜色 */
  --ip-content-backgrund:#b6b6b6;/* 资产页面背景 */
}

/* 黑色主题 */
.black-theme {
  --ty-color:#3c3f41;/* 全局框内颜色 */
  --ty-border:#323232;/* 边框颜色 */
  --selected-background: #303030;/* 选中时背景颜色 */
  --hover-background: #5c5656;/* 悬浮时背景颜色 */
  --tag-color:#bbbbbb;/* 标签字体颜色 */
  --ip-content-backgrund:#282828;/* 资产页面背景 */
}

 

上一篇:transform变形


下一篇:React组件方法中为什么要绑定this