vangleer / es-drager

A draggable, resizable, rotatable component based on vue3
https://vangleer.github.io/es-drager/
331 stars 50 forks source link

bug: 属性是没有设置响应式吗? #24

Closed kafeibei001 closed 11 months ago

kafeibei001 commented 11 months ago

bug: 属性是没有设置响应式吗? 理论上应该默认是相关属性都是响应式的吧-,但是我测试下来 ,基本属性都在第一次设置之后就不会变动了- ; DragData 类型返回的属性跟 dragList 里面的数据不一致~;

vangleer commented 11 months ago

大小位置属性都是单向的哈,需要监听change事件同步最新数据

vangleer commented 11 months ago

对于width、height、left、top、angle 是可以实现响应式的,但响应式意味着传入的这些属性必须是ref定义的属性变量,如果传入常量操作将会无效。基于这一点es-drager刚开始就没有考虑这些属性的响应式

可以通过change事件得到最新的数据,然后进行同步

<template>
  <Drager v-bind="data" @change="handleChange" />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import Drager, { DragData } from 'es-drager'

const data = ref<DragData>({
  width: 100,
  height: 100,
  left: 100,
  top: 100,
  angle: 0
})

function handleChange(dragData: DragData) {
  data.value = dragData
}
</script>

基于 es-drager 二次封装,MyDrager.vue

<template>
  <Drager v-bind="data"  @change="handleChange" />
</template>

<script setup lang="ts">
import { computed, ExtractPropTypes } from 'vue'
import Drager, { DragData, DragerProps } from 'es-drager'

type MyProps = Partial<ExtractPropTypes<typeof DragerProps>>

const props = defineProps<MyProps>()
const emit = defineEmits(['update:width', 'update:height', 'update:left', 'update:top', 'update:angle'])

const data = computed(() => ({
  ...props,
  width: props.width,
  height: props.height,
  left: props.left,
  top: props.top,
  angle: props.angle
}))

function handleChange(dragData: DragData) {
  emit('update:width', dragData.width)
  emit('update:height', dragData.height)
  emit('update:left', dragData.left)
  emit('update:top', dragData.top)
  emit('update:angle', dragData.angle)
}
</script>

使用自定义Drager组件

<template>
  <MyDrager
    v-model:width="data.width"
    v-model:height="data.height"
    v-model:left="data.left"
    v-model:top="data.top"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import MyDrager from './MyDrager.vue'

const data = ref({
  width: 100,
  height: 100,
  left: 100,
  top: 100,
  angle: 0
})
</script>