双屏 效果:

vue directives 分屏_vue directives 分屏

步骤 1:将这个组件代码 拿过去使用 :(掘金复制的 )创建公共组件

vue directives 分屏_当前版本_02

<template>
  <div ref="splitPane" class="split-pane" :class="direction" :style="{ flexDirection: direction }">
    <div class="pane pane-one" :style="lengthType + ':' + paneLengthValue">
        <slot name="one"></slot>
    </div>

    <div
      class="pane-trigger"
      :style="lengthType + ':' + triggerLengthValue"
      @mousedown="handleMouseDown"
      style="z-index: 1" // 增加样式,使这个鼠标拖拽框总在最上方(实际中没有会被覆盖住)
    >
    </div>
     // 增加 overflow:hidden 下面的页面会随着高度改变(溢出) 隐藏,提高视图效果
    <div class="pane pane-two" style="z-index: 1;overflow:hidden">
      <slot name="two"></slot>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    direction: {
      type: String,
      default: 'row'
    },

    min: {
      type: Number,
      default: 10
    },

    max: {
      type: Number,
      default: 90
    },

    paneLengthPercent: {
      type: Number,
      default: 50
    },

    triggerLength: {
      type: Number,
      default: 10
    }
  },
  data () {
    return {
      triggerLeftOffset: 0 // 鼠标距滑动器左(顶)侧偏移量
    }
  },
  computed: {
    lengthType () {
      return this.direction === 'row' ? 'width' : 'height'
    },

    paneLengthValue () {
      return `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})`
    },

    triggerLengthValue () {
      return this.triggerLength + 'px'
    }
  },

  methods: {
    // 按下滑动器
    handleMouseDown (e) {
      document.addEventListener('mousemove', this.handleMouseMove)
      document.addEventListener('mouseup', this.handleMouseUp)

      if (this.direction === 'row') {
        this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
      } else {
        this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top
      }
    },

    // 按下滑动器后移动鼠标
    handleMouseMove (e) {
      const clientRect = this.$refs.splitPane.getBoundingClientRect()
      let paneLengthPercent = 0

      if (this.direction === 'row') {
        const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
        paneLengthPercent = (offset / clientRect.width) * 100
      } else {
        const offset = e.pageY -  - this.triggerLeftOffset + this.triggerLength / 2
        paneLengthPercent = (offset / clientRect.height) * 100
      }

      if (paneLengthPercent < this.min) {
        paneLengthPercent = this.min
      }
      if (paneLengthPercent > this.max) {
        paneLengthPercent = this.max
      }
      this.$emit('update:paneLengthPercent', paneLengthPercent)
    },

    // 松开滑动器
    handleMouseUp () {
      document.removeEventListener('mousemove', this.handleMouseMove)
    }
  }
}
</script>

<style scoped lang="scss">
  .split-pane {
    background: palegreen;
    height: 100%;
    display: flex;
    &.row {
      .pane {
        height: 100%;
      }
      .pane-trigger {
        height: 100%;
        cursor: col-resize;
      }
    }
    &.column {
      .pane {
        width: 100%;
      }
      .pane-trigger {
        width: 100%;
        cursor: row-resize;
      }
    }
    .pane-one {
      background: lavender;
    }
    .pane-trigger {
      user-select: none;
      background: #303133;
    }
    .pane-two {
      flex: 1;
      background: #929292;
    }
  }
</style>

步骤 2 :新建一个分屏的组件:进行分屏使用(将上下两个页面进行嵌入)

<template>
  <div class="page">
    <div style="height: 760px">
      <SplitPane
        direction="column" // column:上下分屏 ;row:左右分屏
        :min="5" // 默认上下显示比例
        :max="95"
        :triggerLength="16" // 中间黑色的 鼠标拖拽区大小
        :paneLengthPercent.sync="paneLengthPercent"
        :append-to-body="true" // 关闭遮蔽罩
      >
        <template v-slot:one> // 上方的页面:将这个页面写在了此组件中
          <div>
            <el-button  size="mini" style="color: #bc1e21">当前版本共 {{countNum.length}} 条, 相比上一个提交版本 :</el-button>
            <el-button  disabled size="mini" type="success">增加了 {{countAdd.length}} 条</el-button>
            <el-button  disabled size="mini" type="danger">删除了 {{countDelete.length}} 条</el-button>
            <el-button  size="mini" style="color: #006af1; margin-left: 50px">提示 :增加 和 删除 分别对应 学校代码背景色的 绿色 和 红色</el-button>
          </div>
          <major-table2  :totale="total" type="query" ref="tableRef" :table-data="sTableData" show-operation="true"
                         :loading="loading" is-pl="1" :query-score="queryScore"/>
          <div class="test" :style="style2" >
            <el-pagination background layout="total, sizes, prev, pager, next,jumper"
                           :current-page="pageCurrent"
                           :page-size="pageSize"
                           :page-sizes="[20, 50, 100, 200, 500]"
                           @size-change="pageSizeChange"
                           @current-change="onPageCurrentChange"
                           :total="total" style="margin-top: 75px">
            </el-pagination>
          </div>
        </template>

        <template v-slot:two> // 下方的页面 :嵌入的完整组件
            <div id="drag31" style="height: 20px;z-index: 1">
              <open-query ref="tableRefff" :loading="loading" @cartReset="cartReset"/>
            </div>
        </template>

      </SplitPane>
    </div>
  </div>
</template>

<script>
import SplitPane from '@/components/split-pane' // 引入分屏公共组件
import OpenQuery from '@/view/main/query/SQueryTwins'
import MajorTable2 from '@/components/table/MajorTable2Version'
import Api from '@/api'

export default {
  components: {
    SplitPane,
    OpenQuery,
    MajorTable2
  },
  computed: {
    style2 () {
      return Object.assign({textAlign: 'center'}, this.screenWidthStyleObj)
    }
  },
  data () {
    return {
      paneLengthPercent: 30,
      // --------------------
      visible: false,
      sTableData: [],
      pageCurrent: 1,
      pageSize: 100,
      total: 0,
      nowCartList: [],
      lastCartList: [],
      countAdd: [], // 增加条数统计
      countDelete: [], // 减少条数统计
      countNum: [], // 本版本总数
      nowRowCartId: '', // 点击当前行的方案id
      lastRowCartId: '' // 点击当前行的上一行的 方案id
    }
  },
  created () {
    this.initShow()
  },
  // 监听route 并刷新,获得最新传的参数!!!!!!!
  watch: {
    '$route' () {
      this.initShow()
    }
  },
  methods: {
    // 以下是 上方组件的对比功能逻辑,跟分屏无关
    initShow: function () {
      // this.visible = true
      const that = this
      that.nowCartList = []
      that.lastCartList = []
      // 获得组件传的值
      that.nowCartList = JSON.parse(this.$route.query.res).nowRowCartIdStr.split(',')
      that.lastCartList = JSON.parse(this.$route.query.res).lastRowCartIdStr.split(',')
      // a : 取 nowCartList(当前版本) 与 lastCartList(上一版本)不同元素
      const nowOnlyList = [] // 当前版本独有元素
      that.nowCartList.forEach(s1 => {
        if (that.lastCartList.indexOf(s1) === -1) {
          nowOnlyList.push(s1)
        }
      })
      // b : 取 lastCartList(上一版本) 与 nowCartList(当前版本)不同元素
      const lastOnlyList = [] // 上一版本独有元素
      that.lastCartList.forEach(s2 => {
        if (that.nowCartList.indexOf(s2) === -1) {
          lastOnlyList.push(s2)
        }
      })
      // c :将 当前版本 和 上一版本的 cart[] 合并 去重,此时的查询参数为两个版本合并去重的志愿
      const newCartList = new Set(that.nowCartList.concat(that.lastCartList))
      const page = this.pageCurrent
      const size = this.pageSize
      var newCartStr = ''
      newCartList.forEach(s => {
        newCartStr += s + ','
      })
      const params = {cart: newCartStr}
      Api.QUERY.sListByCart(params, page, size)
        .then(function (res) {
          that.sTableData = res.data.records // 查询结果:当前版本 和 上一版本的 合并去重的志愿列表
          that.total = res.data.total
          // 将 2 个版本 独有的 元素和 数据库返回 id进行比对 ; 区分开 新增的 和 删除的
          for (let i = 0; i < that.sTableData.length; i++) {
            if (nowOnlyList.indexOf(that.sTableData[i].id.toString()) !== -1) {
              Object.assign(that.sTableData[i], {colorType: 'add'})
            }
            if (lastOnlyList.indexOf(that.sTableData[i].id.toString()) !== -1) {
              Object.assign(that.sTableData[i], {colorType: 'delete'})
            }
          }
          // 统计 新增 和 减少 和 当前版本 的 条数
          that.countAdd = []
          that.countDelete = []
          that.countNum = []
          const countNum1 = []
          that.sTableData.forEach(s => {
            if (s.colorType === 'add') {
              that.countAdd.push(1)
            }
            if (s.colorType === 'delete') {
              that.countDelete.push(1)
            }
            if (s.colorType === undefined) {
              countNum1.push(1)
            }
          })
          that.countNum = countNum1.concat(that.countAdd)
        })
        .finally(() => {
          that.loading = false
        })
      this.$forceUpdate()
    }
  }
}
</script>

<style scoped lang="scss">
  .page {
    height: 100%;
    padding: 10px;
    background: #000;
  }
</style>

=========================================

踩坑总结:

1:在嵌入页面的时候,嵌入上方页面后(v-slot:one),鼠标无法拖拽分屏

解决:

vue directives 分屏_vue directives 分屏_03

2: a: 中间鼠标拖拽区 被覆盖

b: 下方页面往下拖拽后,高度溢出,影响效果

解决:a 和 b

vue directives 分屏_分屏_04