Merge branch '2.0'

This commit is contained in:
zhigang.li 2018-12-21 13:36:48 +08:00
commit 7a75e24849
11 changed files with 375 additions and 3 deletions

View File

@ -0,0 +1,18 @@
<template>
<div :class="`${prefix}-move-trigger`">
<div :class="`${prefix}-move-trigger-point`">
<i></i><i></i><i></i><i></i><i></i>
</div>
</div>
</template>
<script>
import Mixin from './mixin'
export default {
name: 'DragDrawerTrigger',
mixins: [Mixin]
}
</script>
<style>
</style>

View File

@ -0,0 +1,156 @@
<template>
<Drawer ref="drawerWrapper"
:value="value"
@input="handleInput"
:width="width"
:class-name="outerClasses"
v-bind="$attrs"
v-on="$listeners">
<!-- 所有插槽内容显示在这里 -->
<template v-for="(slots, slotsName) in $slots">
<template v-if="slotsName !== 'default'">
<render-dom v-for="(render, index) in slots"
:key="`b_drawer_${slotsName}_${index}`"
:render="() => render"
:slot="slotsName">
</render-dom>
</template>
<template v-else>
<div :class="`${prefix}-body-wrapper`"
:key="`b_drawer_${slotsName}`">
<render-dom v-for="(render, index) in slots"
:key="`b_drawer_${slotsName}_${index}`"
:render="() => render"
:slot="slotsName">
</render-dom>
</div>
</template>
</template>
<!-- 所有插槽内容显示在这里 -->
<div v-if="draggable"
:style="triggerStyle"
:class="`${prefix}-trigger-wrapper`"
@mousedown="handleTriggerMousedown">
<slot name="trigger">
<drag-drawer-trigger></drag-drawer-trigger>
</slot>
</div>
<div v-if="$slots.footer"
:class="`${prefix}-footer`">
<slot name="footer"></slot>
</div>
</Drawer>
</template>
<script>
import RenderDom from '@/libs/render-dom'
import DragDrawerTrigger from './drag-drawer-trigger.vue'
import Mixin from './mixin'
import { on, off } from '@/libs/tools'
import './index.less'
export default {
name: 'BDrawer',
components: {
RenderDom,
DragDrawerTrigger
},
mixins: [Mixin],
props: {
value: {
type: Boolean,
default: false
},
width: {
type: [String, Number],
default: 256
},
//
draggable: {
type: Boolean,
default: false
},
//
minWidth: {
type: [String, Number],
default: 256
}
},
data () {
return {
canMove: false,
wrapperWidth: 0,
wrapperLeft: 0
}
},
computed: {
outerClasses () {
const classesArray = [
`${this.prefix}-wrapper`,
this.canMove ? 'no-select pointer-events-none' : ''
]
return classesArray.join(' ')
},
placement () {
return this.$attrs.placement
},
innerWidth () {
const width = this.width
return width <= 100 ? (this.wrapperWidth * width) / 100 : width
},
triggerStyle () {
return {
[this.placement]: `${this.innerWidth}px`,
position: this.$attrs.inner ? 'absolute' : 'fixed'
}
}
},
methods: {
handleInput (status) {
this.$emit('input', status)
},
handleTriggerMousedown (event) {
this.canMove = true
this.$emit('on-resize-start')
// trigger
window.getSelection().removeAllRanges()
},
handleMousemove (event) {
if (!this.canMove) return
// window0
this.setWrapperWidth()
const left = event.pageX - this.wrapperLeft
// left
let width = this.placement === 'right' ? this.wrapperWidth - left : left
//
width = Math.max(width, parseFloat(this.minWidth))
event.atMin = width === parseFloat(this.minWidth)
// width100
if (width <= 100) width = (width / this.wrapperWidth) * 100
this.$emit('update:width', parseInt(width))
this.$emit('on-resize', event)
},
handleMouseup (event) {
this.canMove = false
this.$emit('on-resize-end')
},
setWrapperWidth () {
const {
width,
left
} = this.$refs.drawerWrapper.$el.getBoundingClientRect()
this.wrapperWidth = width
this.wrapperLeft = left
}
},
mounted () {
on(document, 'mousemove', this.handleMousemove)
on(document, 'mouseup', this.handleMouseup)
this.setWrapperWidth()
},
beforeDestroy () {
off(document, 'mousemove', this.handleMousemove)
off(document, 'mouseup', this.handleMouseup)
}
}
</script>

View File

@ -0,0 +1,2 @@
import DragDrawer from './drag-drawer.vue'
export default DragDrawer

View File

@ -0,0 +1,70 @@
@prefix: ~"drag-drawer";
@drag-drawer-trigger-height: 100px;
@drag-drawer-trigger-width: 8px;
.@{prefix}-wrapper{
&.no-select{
user-select: none;
}
&.pointer-events-none{
pointer-events: none;
& .@{prefix}-trigger-wrapper{
pointer-events: all;
}
}
.ivu-drawer{
&-header{
overflow: hidden !important;
box-sizing: border-box;
}
&-body{
padding: 0;
overflow: visible;
position: static;
display: flex;
flex-direction: column;
}
}
.@{prefix}-body-wrapper{
width: 100%;
height: 100%;
padding: 16px;
overflow: auto;
}
.@{prefix}-trigger-wrapper{
top: 0;
height: 100%;
width: 0;
.@{prefix}-move-trigger{
position: absolute;
top: 50%;
height: @drag-drawer-trigger-height;
width: @drag-drawer-trigger-width;
background: rgb(243, 243, 243);
transform: translate(-50%, -50%);
border-radius: ~"4px / 6px";
box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2);
line-height: @drag-drawer-trigger-height;
cursor: col-resize;
&-point{
display: inline-block;
width: 50%;
transform: translateX(50%);
i{
display: block;
border-bottom: 1px solid rgb(192, 192, 192);
padding-bottom: 2px;
}
}
}
}
.@{prefix}-footer{
flex-grow: 1;
width: 100%;
bottom: 0;
left: 0;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
background: #fff;
}
}

View File

@ -0,0 +1,7 @@
export default {
data () {
return {
prefix: 'drag-drawer'
}
}
}

10
src/libs/render-dom.js Normal file
View File

@ -0,0 +1,10 @@
export default {
name: 'RenderDom',
functional: true,
props: {
render: Function
},
render: (h, ctx) => {
return ctx.props.render(h)
}
}

View File

@ -39,5 +39,6 @@ export default {
cropper_page: 'Cropper', cropper_page: 'Cropper',
message_page: 'Message Center', message_page: 'Message Center',
tree_table_page: 'Tree Table', tree_table_page: 'Tree Table',
org_tree_page: 'Org Tree' org_tree_page: 'Org Tree',
drag_drawer_page: 'Draggable Drawer'
} }

View File

@ -39,5 +39,6 @@ export default {
cropper_page: '图片裁剪', cropper_page: '图片裁剪',
message_page: '消息中心', message_page: '消息中心',
tree_table_page: '树状表格', tree_table_page: '树状表格',
org_tree_page: '组织结构树' org_tree_page: '组织结构树',
drag_drawer_page: '可拖动抽屉'
} }

View File

@ -39,5 +39,6 @@ export default {
cropper_page: '圖片裁剪', cropper_page: '圖片裁剪',
message_page: '消息中心', message_page: '消息中心',
tree_table_page: '樹狀表格', tree_table_page: '樹狀表格',
org_tree_page: '組織結構樹' org_tree_page: '組織結構樹',
drag_drawer_page: '可拖動抽屜'
} }

View File

@ -125,6 +125,15 @@ export default [
}, },
component: () => import('@/view/components/drag-list/drag-list.vue') component: () => import('@/view/components/drag-list/drag-list.vue')
}, },
{
path: 'drag_drawer_page',
name: 'drag_drawer_page',
meta: {
icon: 'md-list',
title: '可拖拽抽屉'
},
component: () => import('@/view/components/drag-drawer')
},
{ {
path: 'org_tree_page', path: 'org_tree_page',
name: 'org_tree_page', name: 'org_tree_page',

View File

@ -0,0 +1,97 @@
<template>
<Card>
<h3 style="padding: 10px 0;">drag-drawer组件是对iview的drawer组件的封装在支持drawer所有api的基础上支持可拖动和footer底部插槽</h3>
<div style="padding: 10px 0">
<b>
方向
<i-switch v-model="placement">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
</b>
<b>
是否可拖动
<i-switch v-model="draggable"></i-switch>
</b>
<Button @click="showContainerBDrawer = !showContainerBDrawer" type="primary" style="margin-left: 10px">{{ showContainerBDrawer ? '关闭' : '打开' }}容器内抽屉</Button>
<Button @click="showWindowBDrawer = true" type="primary" style="margin-left: 10px">打开全屏抽屉</Button>
</div>
<div class="drag-drawer-inner-box">
<drag-drawer v-model="showContainerBDrawer"
:width.sync="width2"
min-width="30px"
:inner="true"
:transfer="false"
:placement="placementComputed"
:draggable="draggable"
@on-resize="handleResize"
:scrollable="true">
<div slot="header">
<Icon type="md-aperture" :size="18"></Icon>
<b>这是标题</b>
</div>
<p v-for="n in 200" :key="n">{{ n }}</p>
<div slot="footer">
<p>123123</p>
<p>21312</p>
</div>
</drag-drawer>
</div>
<drag-drawer v-model="showWindowBDrawer"
:width.sync="width1"
:min-width="300"
:placement="placementComputed"
:draggable="draggable"
:scrollable="true">
<div slot="header">
<Icon type="md-aperture" :size="18"></Icon>
<b>这是标题</b>
</div>
<Button @click="showBDrawer3 = true">显示多层</Button>
<p v-for="n in 200" :key="n">{{ n }}</p>
</drag-drawer>
</Card>
</template>
<script>
import DragDrawer from '_c/drag-drawer'
export default {
name: 'drag_drawer_page',
components: {
DragDrawer
},
data () {
return {
showWindowBDrawer: false,
showContainerBDrawer: false,
showBDrawer3: false,
width1: 300,
width2: 200,
placement: false,
draggable: true
}
},
computed: {
placementComputed () {
return this.placement ? 'left' : 'right'
}
},
methods: {
handleResize (event) {
const { atMin } = event
/* eslint-disable */
console.log(atMin);
},
}
}
</script>
<style lang="less">
.drag-drawer-inner-box{
position: relative;
width: 500px;
height: 400px;
background: pink;
border: 1px solid pink;
}
</style>