Vue中使用vue-drag-resize组件溢出父容器、内部下拉框无法选择的问题
问题1:组件脱离父容器、显示在视口左上角
- 问题成因
vue-drag-resize为绝对定位组件,定位参照遵循CSS定位规则:只有父容器设置了非static的定位属性(如position: relative),组件才会以该父容器为坐标计算边界;当前代码中的#canvas为默认static定位,组件的定位计算会直接穿透所有无定位的祖先元素,最终以视口为参照,自然会出现在视口左上角。- 开启
:parentLimitation="true"也无法解决该问题:这个属性仅负责限制拖拽、缩放的边界范围,不会主动补全父容器的定位规则,找不到正确参照系时,边界限制逻辑也会完全失效。 - 组件默认x、y坐标为0,没有传入初始位置参数时,会直接贴在参照容器的左上角;同时代码中
resize方法修改的width、height、top、left变量没有在data中初始化,也没有绑定回组件的props,属于无效逻辑。 - 样式中
#canvas的边框写法不完整:border: 20px black;缺少边框样式值,会造成布局计算异常。
- 修复方案
- 给
#canvas添加position: relative;,明确作为组件的定位参照父级 - 在data中声明组件需要的初始位置、尺寸变量,给组件传入
:x、:y的初始值 - 修正canvas的边框样式为
border: 20px solid black;
- 给
问题2:内嵌下拉菜单无法点击操作
- 问题成因
activated是<VueDragResize>组件自身抛出的自定义事件,不属于原生<select>的内置事件,把v-on:activated="onActivated"绑在select标签上完全不会生效,属于无效代码。vue-drag-resize默认会把组件内部所有鼠标事件绑定到容器的拖拽逻辑上,无特殊标识的元素上的点击、拖动操作都会被拦截,导致内部原生表单元素无法触发自身的交互。
- 修复方案
- 给需要保留原生交互的select标签添加
no-drag属性:这个标识会告诉组件,鼠标落在该元素上时不要拦截拖拽事件,把操作权交还给元素本身。 - 如果需要在组件被激活时自动聚焦下拉框,要把
@activated事件绑定在<VueDragResize>组件本身,而不是内部的select标签上。
- 给需要保留原生交互的select标签添加
修正后可正常运行的完整代码
<template> <div id="app"> <div id="canvas"> <VueDragResize :isActive="true" :w="200" :h="200" :x="20" :y="20" @resizing="resize" @dragging="resize" :parentLimitation="true" @activated="onActivated" > <h3>Drag and Resize Me!</h3> <select name="cars" id="cars" ref="dropdown-cars" no-drag > <option value="volvo">Volvo</option> <option value="saab">Saab</option> </select> </VueDragResize> </div> </div> </template> <script> import VueDragResize from 'vue-drag-resize' export default { name: 'App', components: { VueDragResize, }, data() { return { width: 200, height: 200, top: 20, left: 20 } }, methods: { resize(newRect) { this.width = newRect.width; this.height = newRect.height; this.top = newRect.top; this.left = newRect.left; }, onActivated() { this.$refs['dropdown-cars'].focus(); } } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } #canvas { width: 40vw; height: 40vw; background-color: #2f3f50; border: 20px solid black; position: relative; } </style>
内容的提问来源于stack exchange,提问作者lazarea
相关产品推荐
相关产品推荐

