init
This commit is contained in:
61
src/components/SplitPane/Pane.vue
Normal file
61
src/components/SplitPane/Pane.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div :class="classes">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Pane',
|
||||
props: {
|
||||
// split: {
|
||||
// validator: function (value) {
|
||||
// return ['vertical', 'horizontal'].indexOf(value) >= 0
|
||||
// },
|
||||
// required: true
|
||||
// }
|
||||
},
|
||||
// computed:{
|
||||
// classes () {
|
||||
// return this.$parent.split
|
||||
// },
|
||||
// },
|
||||
data() {
|
||||
const classes = ['Pane', this.$parent.split, 'className'];
|
||||
return {
|
||||
classes: classes.join(' '),
|
||||
percent: 50
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.$parent.split)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.splitter-pane.vertical.splitter-paneL{
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
.splitter-pane.vertical.splitter-paneR{
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
.splitter-pane.horizontal.splitter-paneL{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
.splitter-pane.horizontal.splitter-paneR{
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
75
src/components/SplitPane/Resizer.vue
Normal file
75
src/components/SplitPane/Resizer.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div :class="classes" @mousedown="onMouseDown"></div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.Resizer {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: #000;
|
||||
position: absolute;
|
||||
opacity: .2;
|
||||
z-index: 1;
|
||||
/*-moz-background-clip: padding;*/
|
||||
/*-webkit-background-clip: padding;*/
|
||||
/*background-clip: padding-box;*/
|
||||
}
|
||||
|
||||
/*.Resizer:hover {*/
|
||||
/*-webkit-transition: all 2s ease;*/
|
||||
/*transition: all 2s ease;*/
|
||||
/*}*/
|
||||
|
||||
.Resizer.horizontal {
|
||||
height: 11px;
|
||||
margin: -5px 0;
|
||||
border-top: 5px solid rgba(255, 255, 255, 0);
|
||||
border-bottom: 5px solid rgba(255, 255, 255, 0);
|
||||
cursor: row-resize;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.Resizer.horizontal:hover {
|
||||
border-top: 5px solid rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.Resizer.vertical {
|
||||
width: 11px;
|
||||
height: 100%;
|
||||
/*margin: 0 -5px;*/
|
||||
|
||||
border-left: 5px solid rgba(255, 255, 255, 0);
|
||||
border-right: 5px solid rgba(255, 255, 255, 0);
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.Resizer.vertical:hover {
|
||||
border-left: 5px solid rgba(0, 0, 0, 0.5);
|
||||
border-right: 5px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
split: {
|
||||
validator(value) {
|
||||
return ['vertical', 'horizontal'].indexOf(value) >= 0
|
||||
},
|
||||
required: true
|
||||
},
|
||||
onMouseDown: {
|
||||
type: Function,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const classes = ['Resizer', this.split, 'className'];
|
||||
return {
|
||||
classes: classes.join(' ')
|
||||
}
|
||||
},
|
||||
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
175
src/components/SplitPane/SplitPane-backup.vue
Normal file
175
src/components/SplitPane/SplitPane-backup.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<!--<template>-->
|
||||
<!--<div :style="{ cursor, userSelect }" class="vue-splitter-container clearfix" @mouseup="onMouseUp"-->
|
||||
<!--@mousemove="onMouseMove">-->
|
||||
|
||||
<!--<Pane split="vertical" :style="{ width: percent+'%' }" class="left-container splitter-pane">-->
|
||||
<!--orange-->
|
||||
<!--</Pane>-->
|
||||
|
||||
<!--<Resizer split="vertical" :onMouseDown="onMouseDown" @click="onClick"></Resizer>-->
|
||||
<!--<div class="todel" :style="{ width: 100-percent+'%'}">-->
|
||||
<!--<Pane split="horizontal" class="top-container">-->
|
||||
<!--<div slot>apple banana</div>-->
|
||||
<!--</Pane>-->
|
||||
<!--<Resizer split="horizontal" :onMouseDown="onMouseDown" @click="onClick"></Resizer>-->
|
||||
<!--<Pane split="horizontal" class="bottom-container">-->
|
||||
<!--<div slot>apple banana</div>-->
|
||||
<!--</Pane>-->
|
||||
<!--</div>-->
|
||||
|
||||
<!--</div>-->
|
||||
|
||||
<!--</template>-->
|
||||
<style scoped>
|
||||
.clearfix:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
.vue-splitter-container {
|
||||
height: inherit;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
import Resizer from './Resizer';
|
||||
import vue from 'vue'
|
||||
export default {
|
||||
name: 'splitPane',
|
||||
components: {Resizer},
|
||||
props: {
|
||||
margin: {
|
||||
type: Number,
|
||||
default: 10
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
active: false,
|
||||
percent: 50,
|
||||
hasMoved: false,
|
||||
panes: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
split: {
|
||||
validator: function (value) {
|
||||
return ['vertical', 'horizontal'].indexOf(value) >= 0
|
||||
},
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userSelect () {
|
||||
return this.active ? 'none' : ''
|
||||
},
|
||||
cursor () {
|
||||
return this.active ? 'col-resize' : ''
|
||||
},
|
||||
// $paneItems () {
|
||||
// return this.$children.filter(child => {
|
||||
// console.log(child)
|
||||
// })
|
||||
// }
|
||||
},
|
||||
render(h){
|
||||
const temp = [];
|
||||
this.$slots.default.map((item, i) => {
|
||||
if (item.tag && item.tag.toUpperCase().indexOf('PANE') >= 0) {
|
||||
temp.push(item)
|
||||
}
|
||||
});
|
||||
const newSlots = [];
|
||||
const length = temp.length;
|
||||
temp.map((item, index)=> {
|
||||
newSlots.push(item)
|
||||
if (index != length - 1) {
|
||||
newSlots.push(
|
||||
h('Resizer', {
|
||||
props: {
|
||||
split: this.split,
|
||||
onMouseDown: this.onMouseDown
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
return h('div', {
|
||||
on: {
|
||||
mousemove: this.onMouseMove
|
||||
}
|
||||
}, [
|
||||
h('div', {
|
||||
'class': {
|
||||
'vue-splitter-container': true
|
||||
},
|
||||
}, newSlots)
|
||||
])
|
||||
},
|
||||
// beforeMount(){
|
||||
// this.$slots.default=this.$slots.default.map((item, i) => {
|
||||
// if (item.tag&&item.tag.toUpperCase().indexOf('PANE') >= 0) {
|
||||
// return item
|
||||
// }else{
|
||||
// return null
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// },
|
||||
created(){
|
||||
|
||||
},
|
||||
mounted(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
onClick () {
|
||||
if (!this.hasMoved) {
|
||||
this.percent = 50;
|
||||
this.$emit('resize');
|
||||
}
|
||||
},
|
||||
onMouseDown () {
|
||||
this.active = true;
|
||||
this.hasMoved = false;
|
||||
},
|
||||
onMouseUp () {
|
||||
this.active = false;
|
||||
},
|
||||
onMouseMove (e) {
|
||||
if (e.buttons === 0 || e.which === 0) {
|
||||
this.active = false;
|
||||
}
|
||||
if (this.active) {
|
||||
|
||||
let offset = 0;
|
||||
let target = e.currentTarget;
|
||||
while (target) {
|
||||
offset += target.offsetLeft;
|
||||
target = target.offsetParent;
|
||||
}
|
||||
const percent = Math.floor(((e.pageX - offset) / e.currentTarget.offsetWidth) * 10000) / 100;
|
||||
if (percent > this.margin && percent < 100 - this.margin) {
|
||||
this.percent = percent;
|
||||
}
|
||||
console.log(percent)
|
||||
this.$children.map((v, i)=> {
|
||||
if (i == 0) {
|
||||
v.percent = percent
|
||||
} else {
|
||||
v.percent = 100 - percent
|
||||
}
|
||||
|
||||
})
|
||||
this.$emit('resize');
|
||||
this.hasMoved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
117
src/components/SplitPane/SplitPane.vue
Normal file
117
src/components/SplitPane/SplitPane.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div ref :style="{ cursor, userSelect}" class="vue-splitter-container clearfix" @mouseup="onMouseUp"
|
||||
@mousemove="onMouseMove">
|
||||
<Pane class="splitter-pane splitter-paneL" :split="split" :style="{ [type]: percent+'%'}">
|
||||
<slot name="paneL"></slot>
|
||||
</Pane>
|
||||
<Resizer :style="{ [resizeType]: percent+'%'}" :split="split" :onMouseDown="onMouseDown"
|
||||
@click="onClick"></Resizer>
|
||||
<Pane class="splitter-pane splitter-paneR" :split="split" :style="{ [type]: 100-percent+'%'}">
|
||||
<slot name="paneR"></slot>
|
||||
</Pane>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.clearfix:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
.vue-splitter-container {
|
||||
height: 100%;
|
||||
/*display: flex;*/
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import Resizer from './Resizer';
|
||||
import Pane from './Pane';
|
||||
export default {
|
||||
name: 'splitPane',
|
||||
components: { Resizer, Pane },
|
||||
props: {
|
||||
margin: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
split: {
|
||||
validator(value) {
|
||||
return ['vertical', 'horizontal'].indexOf(value) >= 0
|
||||
},
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: false,
|
||||
hasMoved: false,
|
||||
height: null,
|
||||
percent: 50,
|
||||
type: this.split === 'vertical' ? 'width' : 'height',
|
||||
resizeType: this.split === 'vertical' ? 'left' : 'top'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userSelect() {
|
||||
return this.active ? 'none' : ''
|
||||
},
|
||||
cursor() {
|
||||
return this.active ? 'col-resize' : ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const element = this.$el;
|
||||
const elementOffset = element.getBoundingClientRect();
|
||||
console.log(elementOffset.height)
|
||||
// this.height = elementOffset.height+'px';
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
if (!this.hasMoved) {
|
||||
this.percent = 50;
|
||||
this.$emit('resize');
|
||||
}
|
||||
},
|
||||
onMouseDown() {
|
||||
this.active = true;
|
||||
this.hasMoved = false;
|
||||
},
|
||||
onMouseUp() {
|
||||
this.active = false;
|
||||
},
|
||||
onMouseMove(e) {
|
||||
if (e.buttons === 0 || e.which === 0) {
|
||||
this.active = false;
|
||||
}
|
||||
if (this.active) {
|
||||
let offset = 0;
|
||||
let target = e.currentTarget;
|
||||
if (this.split === 'vertical') {
|
||||
while (target) {
|
||||
offset += target.offsetLeft;
|
||||
target = target.offsetParent;
|
||||
}
|
||||
} else {
|
||||
while (target) {
|
||||
offset += target.offsetTop;
|
||||
target = target.offsetParent;
|
||||
}
|
||||
}
|
||||
|
||||
const currentPage = this.split === 'vertical' ? e.pageX : e.pageY;
|
||||
const targetOffset = this.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight;
|
||||
const percent = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100;
|
||||
if (percent > this.margin && percent < 100 - this.margin) {
|
||||
this.percent = percent;
|
||||
}
|
||||
this.$emit('resize');
|
||||
this.hasMoved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
7
src/components/SplitPane/index.js
Normal file
7
src/components/SplitPane/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import SplitPane from './a.vue';
|
||||
import Pane from './Pane.vue';
|
||||
|
||||
export {
|
||||
SplitPane,
|
||||
Pane
|
||||
}
|
||||
Reference in New Issue
Block a user