Closed qianjiachun closed 9 months ago
好的好的,不仅是top和left,width和height希望也可以支持百分比的形式😂
好的
由于现有功能已足够实现百分比,就没有在内部支持,我们可以使用二次封装的方式实现
<template>
<Drager
v-bind="dragData"
boundary
rotatable
@change="onChange"
>
测试
</Drager>
</template>
<script setup lang='ts'>
import Drager, { DragData } from 'es-drager/index'
import { computed, PropType } from 'vue'
const props = defineProps({
parentRect: Object as PropType<DOMRect | null>, // 为了不频繁的去获取父级元素,采用传入的方式,这样就只获取一次即可
width: {
type: Number,
default: 0
},
height: {
type: Number,
default: 0
},
left: {
type: Number,
default: 0
},
top: {
type: Number,
default: 0
},
})
const dragData = computed(() => convert2percent(props as DragData, false))
const emit = defineEmits(['change'])
const onChange = (data: DragData) => {
emit('change', convert2percent(data))
}
/**
*
* @param data 转换的数据
* @param flag true将值转成百分比,false将百分比值转换为像素
*/
const convert2percent = (data: DragData, flag = true) => {
const result = { ...data }
if (!props.parentRect) {
return data
}
const keys = Object.keys(data)
for (let i = 0; i < keys.length; i++) {
const key = keys[i] as keyof DragData
if (['width', 'left'].includes(key)) {
result[key] = Math.round(
flag ?
result[key] / props.parentRect!.width * 100 :
result[key] / 100 * props.parentRect!.width
)
} else if (['height', 'top'].includes(key)) {
result[key] = Math.round(
flag ?
result[key] / props.parentRect!.height * 100 :
result[key] / 100 * props.parentRect!.height
)
}
}
return result
}
</script>
百分比主要设计,width、height、left、top属性,而且只会有传入百分比和在事件中得到最新的百分比数据两种情况。
内部需要进行转换,因此需要父级元素的宽高。考虑到性能原因,没有在MyDrager中获取,需手动传入
<template>
<div class="container" ref="containerRef">
<button @click="handleClick">change</button>
<MyDrager
:parent-rect="parentRect"
v-bind="dragData"
rotatable
@change="onChange"
>
测试
</MyDrager>
</div>
</template>
<script setup lang="ts">
import { DragData } from 'es-drager/index'
import MyDrager from '@/components/MyDrager.vue'
import { onMounted } from 'vue'
import { ref } from 'vue'
// 初始值,百分比
const dragData = ref({
width: 50,
height: 50,
left: 0,
top: 20
})
const containerRef = ref<HTMLElement | null>(null)
const parentRect = ref<DOMRect | null>(null)
const onChange = (data: DragData) => {
Object.keys(data).forEach(key => {
(dragData.value as any)[key] = (data as any)[key]
})
console.log(data, 'data')
}
// 手动修改
const handleClick = () => {
dragData.value.width = 20
dragData.value.height = 20
}
onMounted(() => {
parentRect.value = containerRef.value?.getBoundingClientRect() || null
})
</script>
<style>
.container {
position: relative;
width: 500px;
height: 500px;
background-color: #ccc;
}
</style>
这里只处理了change事件,如有需要其它事件采取相同的方式即可
这个可以考虑后期加上的