提交 6cae6489 authored 作者: lidongxu's avatar lidongxu

refactor(levitatedsphere): 重构悬浮工具球

从 Vue2 重构成 Vue3 的语法
上级 d292a5f1
...@@ -15,45 +15,42 @@ ...@@ -15,45 +15,42 @@
</div> </div>
</template> </template>
<script> <script setup>
export default { defineProps({
props: { /**
/** * 数据格式: [
* 数据格式: [ * { // 每一列组
* { // 每一列组 * data: [
* data: [ * {
* { * name: '系列1名字',
* name: '系列1名字', * type: 'bar', // 类型: bar 柱状图(默认),line 横线+圆圈, circle 圆圈
* type: 'bar', // 类型: bar 柱状图(默认),line 横线+圆圈, circle 圆圈 * effective: true, // 有效性
* effective: true, // 有效性 * show: true // 是否显示
* show: true // 是否显示 * },
* }, * {
* { * name: '系列2名字',
* name: '系列2名字', * type: 'line', // 类型: bar 柱状图(默认),line 横线+圆圈, circle 圆圈
* type: 'line', // 类型: bar 柱状图(默认),line 横线+圆圈, circle 圆圈 * effective: true, // 有效性
* effective: true, // 有效性 * show: true // 是否显示
* show: true // 是否显示 * }
* } * ],
* ], * orient: '一组内的排列方式' // verticalAlign 垂直排列(默认),horizontal 水平排列
* orient: '一组内的排列方式' // verticalAlign 垂直排列(默认),horizontal 水平排列 * }
* } * ]
* ] */
*/ legendData: {
legendData: { type: Array,
type: Array, default: () => []
default: () => []
},
origin: {
type: String,
default: 'horizontal' // 每组之间排列方式: verticalAlign 垂直,horizontal 水平
}
}, },
methods: { origin: {
handleClick(item) { type: String,
item.effective = !item.effective default: 'horizontal' // 每组之间排列方式: verticalAlign 垂直,horizontal 水平
this.$emit('clickItem')
}
} }
})
const emit = defineEmits(['clickItem']);
const handleClick = (item) => {
item.effective = !item.effective
emit('clickItem', item)
} }
</script> </script>
...@@ -179,7 +176,8 @@ export default { ...@@ -179,7 +176,8 @@ export default {
.e-icon { .e-icon {
background: lightgray !important; background: lightgray !important;
border-color: lightgray !important; border-color: lightgray !important;
&:before{
&:before {
border-color: lightgray !important; border-color: lightgray !important;
} }
} }
......
...@@ -22,100 +22,90 @@ ...@@ -22,100 +22,90 @@
</div> </div>
</template> </template>
<script> <script setup>
export default { const props = defineProps({
name: 'LevitatedSphere', itemWidth: {
props: { // 悬浮按钮宽度
itemWidth: { type: Number,
// 悬浮按钮宽度 default: 46,
type: Number,
default: 46,
},
itemHeight: {
// 悬浮按钮高度
type: Number,
default: 46,
},
gapWidth: {
// 距离屏幕左右两边距离
type: Number,
default: 10,
},
coefficientHeight: {
// 从上到下距离比例
type: Number,
default: 0.85,
}
},
data() {
return {
top: 0,
left: 0,
clientWidth: 0,
clientHeight: 0,
drawer: false,
downPoint: {},
upPoint: {}
};
}, },
created() { itemHeight: {
this.resize() // 悬浮按钮高度
type: Number,
default: 46,
}, },
mounted() { gapWidth: {
window.addEventListener('resize', this.resize) // 距离屏幕左右两边距离
this.$nextTick(() => { type: Number,
const sphereBtn = this.$refs.levitatedSphere; default: 10,
let isDown = false
sphereBtn.addEventListener('mousedown', (e) => {
e.preventDefault();
sphereBtn.style.transition = 'none';
this.downPoint = {
x: e.clientX,
y: e.clientY
};
isDown = true
});
// 在拖拽过程中,组件应该跟随手指的移动而移动
window.addEventListener('mousemove', (e) => {
e.preventDefault();
if (isDown) {
let touch = e;
// 限制 left 和 top 的值,使其不会超出可视区域
this.left = Math.max(this.gapWidth, Math.min(touch.clientX - 20, this.clientWidth - this.itemWidth - this.gapWidth));
this.top = Math.max(0, Math.min(touch.clientY - 25, this.clientHeight - this.itemHeight));
}
});
// 拖拽结束后,重新调整组件的位置并重新设置过渡动画
window.addEventListener('mouseup', (e) => {
sphereBtn.style.transition = 'all 0.5s';
if (this.left > document.documentElement.clientWidth / 2) {
this.left = document.documentElement.clientWidth - this.itemWidth - this.gapWidth;
} else {
this.left = this.gapWidth;
}
isDown = false
this.upPoint = {
x: e.clientX,
y: e.clientY
};
});
});
}, },
beforeDestroy() { coefficientHeight: {
window.removeEventListener('resize', this.resize) // 从上到下距离比例
}, type: Number,
methods: { default: 0.85,
resize() { }
this.clientWidth = document.documentElement.clientWidth; })
this.clientHeight = document.documentElement.clientHeight;
this.left = this.clientWidth - this.itemWidth - this.gapWidth; const levitatedSphere = ref(null)
this.top = this.clientHeight * this.coefficientHeight; const top = ref(0)
}, const left = ref(0)
handleClick() { const clientWidth = ref(0)
if (this.downPoint.x === this.upPoint.x && this.downPoint.y === this.upPoint.y) { const clientHeight = ref(0)
this.drawer = !this.drawer const drawer = ref(false)
} const downPoint = reactive({})
const upPoint = reactive({})
const resize = () => {
clientWidth.value = document.documentElement.clientWidth;
clientHeight.value = document.documentElement.clientHeight;
left.value = clientWidth.value - props.itemWidth - props.gapWidth;
top.value = clientHeight.value * props.coefficientHeight;
}
resize()
onMounted(() => {
window.addEventListener('resize', resize)
})
nextTick(() => {
let isDown = false
levitatedSphere.value.addEventListener('mousedown', (e) => {
e.preventDefault();
levitatedSphere.value.style.transition = 'none';
downPoint.x = e.clientX
downPoint.y = e.clientY
isDown = true
})
// 在拖拽过程中,组件应该跟随手指的移动而移动
window.addEventListener('mousemove', (e) => {
e.preventDefault();
if (isDown) {
let touch = e;
// 限制 left 和 top 的值,使其不会超出可视区域
left.value = Math.max(props.gapWidth, Math.min(touch.clientX - 20, clientWidth.value - props.itemWidth - props.gapWidth));
top.value = Math.max(0, Math.min(touch.clientY - 25, clientHeight.value - props.itemHeight));
}
});
// 拖拽结束后,重新调整组件的位置并重新设置过渡动画
window.addEventListener('mouseup', (e) => {
levitatedSphere.value.style.transition = 'all 0.5s';
if (left.value > document.documentElement.clientWidth / 2) {
left.value = document.documentElement.clientWidth - props.itemWidth - props.gapWidth;
} else {
left.value = props.gapWidth;
} }
isDown = false
upPoint.x = e.clientX
upPoint.y = e.clientY
})
});
onBeforeUnmount(() => {
window.removeEventListener('resize', resize)
})
const handleClick = () => {
if (downPoint.x === upPoint.x && downPoint.y === upPoint.y) {
drawer.value = !drawer.value
} }
} }
</script> </script>
...@@ -139,16 +129,20 @@ export default { ...@@ -139,16 +129,20 @@ export default {
padding: 10px; padding: 10px;
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(auto-fill, 30px); /* 明确指定行高为100px */ grid-template-rows: repeat(auto-fill, 30px);
grid-auto-rows: 30px; /* 自动生成的行高也为100px */ /* 明确指定行高为100px */
grid-gap: 20px 5px; /* 上下间距20px,左右间距5px */ grid-auto-rows: 30px;
/* 自动生成的行高也为100px */
grid-gap: 20px 5px;
/* 上下间距20px,左右间距5px */
width: 100%; width: 100%;
.el-button { .el-button {
width: 100%; width: 100%;
margin: 0; margin: 0;
} }
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.wrap { .wrap {
width: 30px; width: 30px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论