这是我参与「第四届青训营 」笔记创作活动的第12天
在组件开发中,为了实现可以动态获取组件的大小,实现缩放组件大小的功能。
当我们把组件拖拽到编辑区,并选中组件后,会发现组件有八个小圆点。这八个小圆点是牢牢附着在组件的八个位置,这 8 个小圆点就是用来放大缩小用的。实现原理如下:
在每个组件外面包一层 Shape 组件,Shape 组件里包含 8 个小圆点和一个 <slot> 插槽,用于放置组件。
<!--页面组件列表展示-->
<Shape
v-for="(item, index) in componentData"
:key="item.id"
:default-style="item.style"
:style="getShapeStyle(item.style)"
:active="item.id === (curComponent || {}).id"
:element="item"
:index="index"
:class="{ lock: item.isLock }"
>
<component
:is="item.component"
:id="'component' + item.id"
class="component"
:style="getComponentStyle(item.style)"
:prop-value="item.propValue"
:element="item"
:request="item.request"
@input="handleInput"
/>
</Shape>
<!--Shape 组件内部结构-->
<div
class="shape"
:class="{ active }"
@click="selectCurComponent"
@mousedown="handleMouseDownOnShape"
>
<div
v-for="item in (isActive()? getPointList() : [])"
:key="item"
class="shape-point"
:style="getPointStyle(item)"
@mousedown="handleMouseDownOnPoint(item, $event)"
>
</div>
<slot></slot>
</div>
// 拖动小圆点获取新的坐标位置,核心代码
handleMouseDownOnShape(e) {
e.stopPropagation()
const pos = { ...this.defaultStyle }
const startY = e.clientY
const startX = e.clientX
// 如果直接修改属性,值的类型会变为字符串,所以要转为数值型
const startTop = Number(pos.top)
const startLeft = Number(pos.left)
const move = (moveEvent) => {
const curX = moveEvent.clientX
const curY = moveEvent.clientY
pos.top = curY - startY + startTop
pos.left = curX - startX + startLeft
// 修改当前组件样式
this.$store.commit('setShapeStyle', pos)
}
const up = () => {
document.removeEventListener('mousemove', move)
document.removeEventListener('mouseup', up)
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', up)
},
总结思路:
- 点击小圆点时,记录点击的坐标 xy。
- 假设我们现在向下拖动,那么 y 坐标就会增大。
- 用新的 y 坐标减去原来的 y 坐标,就可以知道在纵轴方向的移动距离是多少。
- 最后再将移动距离加上原来组件的高度,就可以得出新的组件高度。
- 如果是正数,说明是往下拉,组件的高度在增加。如果是负数,说明是往上拉,组件的高度在减少。