外层大盒子处理分发的拖拽事件,里层的盒子负责展示各个Item的内容;
实现方式;1. 在component里面新建dragBox.vue 来存放外层的盒子,通过插槽实现子元素的嵌套; 2. 在component里面新建dragItem.vue 通过插槽实现drag-item内部元素的嵌套; 3.新建list.vue 来引入在component中新建的组件,进行调用,同时处理需要拖动的一些逻辑;
list.vue中的内容代码;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | <template> <div style= "width: 100%; height:100%; border:1px solid #ccc;" > <drag-box ref= "dragBox" style= "width: 100%; height: 100%;" > <drag-item :style= "{'width': !dragHide ? '100%' : '20%'}" > <!------用来设置一开始是100%的宽度,详情出现时第一个drag-item 的内容呈现20%-------> <div @click= "dragChange" >列表内容呈现</div> <!-----可以将需要的内容直接写在这里,也可以设置引用组件进行使用-------> </drag-item> <drag-item v- if = "dragHide" :resize-show= "false" >详情内容呈现</drag-item> </drag-box> </div> </template> <script> import dragBox from './component/dragBox' import dragItem from './component/dragItem' export default { components: { dragBox, dragItem }, data() { return { defaultFlex: true , resizeBox: null , currentBox: null , rightBox: null , curLen: 0, otherBoxWidth: 0, startX: 0, dragHide: false } }, mounted() { this .setDragItemFlex() this .dragControllerDiv() }, methods: { dragChange() { this .dragHide = true }, onMouseDown(e) { this .resizeBox = e.target this .currentBox = this .resizeBox.parentNode // 当前盒子 this .rightBox = this .getNextElement( this .currentBox) // 当前盒子的下个兄弟节点 if (! this .rightBox) return this .curLen = this .currentBox.clientWidth this .otherBoxWidth = this .$refs.dragBox.clientWidth - this .currentBox.clientWidth - this .rightBox.clientWidth // 其他盒子的宽度 // 颜色改变提醒 this .resizeBox.style.background = '#818181' this .startX = e.clientX document.addEventListener( 'mousemove' , this .onMousemove) document.addEventListener( 'mouseup' , this .onMouseup) }, onMouseup() { // 颜色恢复 this .resizeBox.style.background = '#d6d6d6' document.removeEventListener( 'mousedown' , this .onMouseDown) document.removeEventListener( 'mousemove' , this .onMousemove) }, onMousemove(e) { const endX = e.clientX const moveLen = endX - this .startX // (endx-startx)= 移动的距离 const CurBoxLen = this .curLen + moveLen // resize[i].left+移动的距离=左边区域最后的宽度 const rightBoxLen = this .$refs.dragBox.clientWidth - CurBoxLen - this .otherBoxWidth // 右侧宽度=总宽度-左侧宽度-其它盒子宽度 // 当最小宽度时,无法继续拖动 if (CurBoxLen <= 200 || rightBoxLen <= 200) return this .currentBox.style.width = CurBoxLen + 'px' // 当前盒子的宽度 this .resizeBox.style.left = CurBoxLen // 设置左侧区域的宽度 this .rightBox.style.width = rightBoxLen + 'px' }, // 获取下一个兄弟元素的兼容函数 getNextElement(element) { if (element.nextElementSibling) { return element.nextElementSibling } else { var next = element.nextSibling // 下一个兄弟节点 while (next && next.nodeType !== 1) { // 有 并且 不是我想要的 next = next.nextSibling } return next } }, dragControllerDiv() { const resize = document.getElementsByClassName( 'resize' ) // 拖拽条 // 循环为每个拖拽条添加事件 for ( let i = 0; i < resize.length; i++) { // 鼠标按下事件 resize[i].addEventListener( 'mousedown' , this .onMouseDown) } }, // 如果dragItem 没有定义宽度,则flex=1 setDragItemFlex() { const dragBox = this .$refs.dragBox const childsLen = dragBox.$children.length for ( let i = 0; i < childsLen; i++) { const node = dragBox.$children[i] if (!node.$el.style.width) { // 如果没有定义宽度,则flex=1 node.$el.style.flex = 1 } } } } } </script> <style lang= "scss" scoped> </style> |
dragBox.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <template> <div style= "display: flex; width: 100%; height: 100%;" > <slot /> </div> </template> <script> export default { name: 'DragBox' , data() { return {} }, methods: {} } </script> <style lang= "scss" scoped> </style> |
dragItem.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <template> <!-- <div ref= "container" class = "d-flex" style= "min-width: 200px; position: relative;" > --> <div ref= "container" class = "d-flex" style= "position: relative;" > <div style= "width: 100%; height: 100%;" > <slot /> </div> <!-- 拖拽条 --> <div v- if = "resizeShow" class = "resize" /> </div> </template> <script> export default { name: 'DragItem' , props: { // 控制拖拽条的是否显示,默认显示 resizeShow: { type: Boolean, default : true } } } </script> <style> .resize { position: absolute; top: 0; right: 0; width: 2px; height: 100%; cursor: col-resize; background-color: #f2f2f2; } </style> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~