pre { overflow-y: auto; max-height: 500px }

github地址: https://github.com/lxmghct/my-vue-components

组件介绍

  • props:

    • splitCount: 分割数量, default: 2
    • direction: 分割方向, 'vertical' or 'horizontal', default: 'horizontal'
    • defaultRatio: 默认比例, 类型为数组, default: [1/spiltCount, 1/spiltCount, ...]
  • slots:
    • ...
    • ...
    • ...
  • events:
    • @resize: 拖动分割条时触发, 参数为分割线两侧的div
    • @resize-stop: 拖动分割条结束时触发
  • methods:
    • changeItemSize(index, itemSize, dire='next') 改变第item个pane的大小, dire为next或prev, 表示修改当前pane时连带修改前一个pane还是后一个

效果展示

设计思路

整个组件采用flex布局,通过设置整体的flex-direction控制分割方向,通过修改每个pane的style.flex控制每个pane的大小。

<div class="split-main" ref="splitMain"
:class="direction === 'vertical' ? 'split-vertical' : 'split-horizontal'">
<template v-if="direction === 'vertical'">
<div v-for="i in splitCount" :key="i" ref="splitItem"
class="split-vertical-item">
<div class="split-vertical-line" v-if="i < splitCount"
@mousedown="_startDrag(i)"
@touchstart="_startDrag(i)"></div>
<div class="split-vertical-content">
<slot :name="`pane${i}`"></slot>
</div>
</div>
</template>
<template v-else>
<div v-for="i in splitCount" :key="i" ref="splitItem"
class="split-horizontal-item">
<div class="split-horizontal-line" v-if="i < splitCount"
@mousedown="_startDrag(i)"
@touchstart="_startDrag(i)"></div>
<div class="split-horizontal-content">
<slot :name="`pane${i}`"></slot>
</div>
</div>
</template>
</div>

通过v-for循环生成分割数量的pane,每个pane中间插入分割线,分割线通过@mousedown@touchstart事件绑定_startDrag方法,该方法用于监听鼠标或手指的移动事件,从而实现拖动分割线改变pane大小的功能。

_startDrag (index) {
this.dragIndex = index - 1
},
_onMouseMove (e) {
if (this.dragIndex === -1) {
return
}
let items = this.$refs.splitItem
let item1 = items[this.dragIndex]
let item2 = items[this.dragIndex + 1]
let rect1 = item1.getBoundingClientRect()
let rect2 = item2.getBoundingClientRect()
let ratio1, ratio2
let minLen = this.minLen
if (this.direction === 'vertical') {
let height = this.$refs.splitMain.clientHeight
let tempY = e.clientY - rect1.top > minLen ? e.clientY : rect1.top + minLen
tempY = rect2.bottom - tempY > minLen ? tempY : rect2.bottom - minLen
ratio1 = (tempY - rect1.top) / height
ratio2 = (rect2.bottom - tempY) / height
} else {
let width = this.$refs.splitMain.clientWidth
let tempX = e.clientX - rect1.left > minLen ? e.clientX : rect1.left + minLen
tempX = rect2.right - tempX > minLen ? tempX : rect2.right - minLen
ratio1 = (tempX - rect1.left) / width
ratio2 = (rect2.right - tempX) / width
}
item1.style.flex = ratio1
item2.style.flex = ratio2
e.preventDefault()
this.$emit('resize', item1, item2)
},
_onMouseUp () {
if (this.dragIndex === -1) {
return
}
this.dragIndex = -1
this.$emit('resize-stop')
}

完整代码在github上。https://github.com/lxmghct/my-vue-components

vue自定义组件——split-pane的更多相关文章

  1. vue自定义组件(vue.use(),install)+全局组件+局部组件

    相信大家都用过element-ui.mintui.iview等诸如此类的组件库,具体用法请参考:https://www.cnblogs.com/wangtong111/p/11522520.html ...

  2. Vue自定义组件实现v-model指令

    Tips: 本文所描述的Vue均默认是Vue2版本 在我们初次接触Vue的时候,一定会了解到一个语法糖,那就是v-model指令,它带给我们的第一印象就是它可以实现双向绑定 那么,什么是双向绑定?通俗 ...

  3. [转] vue自定义组件(通过Vue.use()来使用)即install的使用

    在vue项目中,我们可以自定义组件,像element-ui一样使用Vue.use()方法来使用,具体实现方法: 1.首先新建一个Cmponent.vue文件 // Cmponent.vue<te ...

  4. vue 自定义组件销毁

    今天在开发电商vue前端项目时,用户每次登出再换其它用户登录时,页面显示的用户名和左则导航都还是上个用户的,刚开始以为是localStorage中没有清除全局数据,然后在用户点击退出系统时手动清除lo ...

  5. Vue自定义组件插入值

    我们自定义组件的时候有时候需要往组件里面插一些内容: //定义一个组件test,插值内容用slog来代替 export default { name: 'test', template:` <d ...

  6. VUE 自定义组件之间的相互通信

    一.自定义组件 1.全局自定义组件 我们在var vm = new Vue({});的上面并列写上Vue.component('自定义组件名',{组件对象});来完成全局自定义组件的声明.示例代码如下 ...

  7. vue自定义组件并使用

    以下是使用自己写的一个简单的文件上传框为例 1.自定义组件结构(一个js文件,一个vue文件),最好单独放一个文件 2.upload.vue 内容 其中,action是父组件传递给子组件的参数,使用p ...

  8. vue自定义组件中的v-model简单解释

    在使用iview框架的时候,经常会看到组件用v-model双向绑定数据,与传统步骤父组件通过props传值子组件,子组件发送$emit来修改值相比,这种方式避免操作子组件的同时再操作父组件,显得子组件 ...

  9. 8、VUE自定义组件

    1.为什么要使用自定义组件? 自定义组件是用来封装复杂的内容,提高可重用性,比如封装复杂的表格组件.日历组件.图片轮播组件等. 2.自定义组件 2.1. 全局组件 全局组件是每个Vue对象都能使用的组 ...

  10. Vue自定义组件以及组件通信的几种方式

    本帖子来源:小贤笔记 功能 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它 ...

随机推荐

  1. vue实现学生管理系统

    开发步骤 创建一个空文件夹,取名students-system 方式一:右键新建 方式二:命令行新建(提倡) ##windows系统 md students-system##mac/linux mkd ...

  2. idea创建maven + tomcat项目

    移动文件夹: 找到tomcat文件目录 配置完成,添加测试html文件: 运行 修改默认路径:

  3. heimaJava17

    java IO流 缓冲流 概念 缓存流也称为高效流.或者高级流.之前学习的字节流也可以称为原始流 作用:缓冲流自带缓冲区.可以提高原始字节流.字符流读写数据的性能 分类 字节缓冲流 字节缓冲输入流:B ...

  4. Java代码结构

    Java代码结构 顺序结构 Java的基本结构为顺序结构,除非特别指明,否则从上到下一句一句执行 选择结构 if单选择结构 if(condition){ doSomething(); } if双选择结 ...

  5. Excel 多表头导入导出(借助Aspose)

    需求中Excell多表头,完成导入导出. Aspose 代码实现多表头方式借助代码比较繁琐, 借助模板方式. 简化逻辑. 注意,aspose从0开始索引. 导入部分代码: 实现选择导入Excel,导入 ...

  6. 艾思最新案例分享:塔蓝物流app-物流仓储管理系统app. app开发

    塔蓝物流app是一款物流仓储管理app:主要业务范围空运,海运,进出口货物及过境货物的运输代理,包括揽物订舱,仓储(危险品除外),包装,搬运装卸,中转,流通加工,集装箱拼装拆箱(危险品除外),结算运杂 ...

  7. 前端复习之HTML5

      HTML5 Day01:   *概念:     *HTML5之后,声明不在出现版本信息     *HTML5永远不可能离开JavaScript.     *HTML5在移动端支持好于PC端   * ...

  8. @click使用三元运算符

    @click="scope.row.status == 1 ? '' :  blockUp(scope.row) "

  9. Json对象转换模块(自编代码JsonObject.cs)

    namespace 信息采集系统.Common { /// <summary> /// Json类型对象,用于其它Json对象继承 /// </summary> /// < ...

  10. mongodb定时备份

    1. https://www.jianshu.com/p/a9352e28e2d6   (未测试) 通过centos 脚步来执行备份操作,使用crontab实现定时功能,并删除指定天数前的备份 具体操 ...