feat(components): 重构浮动面板组件并添加新功能
- 重写了 floating2 组件,增加了更多
This commit is contained in:
parent
4d358d130b
commit
e0853e1416
@ -1,93 +1,238 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div ref="floatPanel" :style="panelStyle" class="float-panel"
|
||||||
ref="bubbleRef"
|
@mousedown="handleMouseDown"
|
||||||
class="floating-bubble"
|
@touchstart="handleTouchStart">
|
||||||
:style="bubbleStyle"
|
|
||||||
@touchstart="onTouchStart"
|
|
||||||
@touchmove="onTouchMove"
|
|
||||||
@touchend="onTouchEnd"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||||
import { useThrottleFn } from '@vueuse/core'
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
offset: {
|
position: {
|
||||||
type: Number,
|
type: Object,
|
||||||
default: 0
|
default: () => ({})
|
||||||
|
},
|
||||||
|
fixedX: Boolean,
|
||||||
|
fixedY: Boolean,
|
||||||
|
snapEdge: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
const bubbleRef = ref(null)
|
const floatPanel = ref(null);
|
||||||
const position = ref({
|
const panelPos = ref({ x: 0, y: 0 });
|
||||||
right: props.offset,
|
const panelSize = ref({ width: 0, height: 0 });
|
||||||
bottom: 100
|
const windowSize = ref({ width: 0, height: 0 });
|
||||||
})
|
const dragOffset = ref({ x: 0, y: 0 });
|
||||||
|
const wasDragged = ref(false);
|
||||||
|
|
||||||
let startTouch = { x: 0, y: 0 }
|
// 更新面板和窗口尺寸信息
|
||||||
let startPos = { right: 0, bottom: 0 }
|
const updateSizes = () => {
|
||||||
let isDragging = false
|
if (floatPanel.value) {
|
||||||
|
panelSize.value = {
|
||||||
|
width: floatPanel.value.offsetWidth,
|
||||||
|
height: floatPanel.value.offsetHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
windowSize.value = {
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: window.innerHeight
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const bubbleStyle = computed(() => ({
|
// 初始位置计算
|
||||||
position: 'fixed',
|
const initPosition = () => {
|
||||||
right: `${position.value.right}px`,
|
updateSizes();
|
||||||
bottom: `${position.value.bottom}px`,
|
const { left, right, top, bottom } = props.position;
|
||||||
zIndex: 99999,
|
|
||||||
transition: isDragging ? 'none' : 'all 0.3s'
|
|
||||||
}))
|
|
||||||
|
|
||||||
const onTouchStart = (event) => {
|
if (right !== undefined) {
|
||||||
isDragging = true
|
panelPos.value.x = windowSize.value.width - parseInt(right || 0) - panelSize.value.width;
|
||||||
const touch = event.touches[0]
|
} else if (left !== undefined) {
|
||||||
startTouch = { x: touch.clientX, y: touch.clientY }
|
panelPos.value.x = parseInt(left || 0);
|
||||||
startPos = { ...position.value }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onTouchMove = useThrottleFn((event) => {
|
if (bottom !== undefined) {
|
||||||
if (!isDragging) return
|
panelPos.value.y = windowSize.value.height - parseInt(bottom || 0) - panelSize.value.height;
|
||||||
event.preventDefault()
|
} else if (top !== undefined) {
|
||||||
|
panelPos.value.y = parseInt(top || 0);
|
||||||
const touch = event.touches[0]
|
|
||||||
const { clientWidth, clientHeight } = document.documentElement
|
|
||||||
const rect = bubbleRef.value.getBoundingClientRect()
|
|
||||||
|
|
||||||
// 计算新位置
|
|
||||||
const deltaX = startTouch.x - touch.clientX
|
|
||||||
const deltaY = startTouch.y - touch.clientY
|
|
||||||
const newRight = startPos.right + deltaX
|
|
||||||
const newBottom = startPos.bottom + deltaY
|
|
||||||
|
|
||||||
// 边界检测
|
|
||||||
position.value = {
|
|
||||||
right: Math.min(Math.max(newRight, props.offset),
|
|
||||||
clientWidth - rect.width - props.offset),
|
|
||||||
bottom: Math.min(Math.max(newBottom, props.offset),
|
|
||||||
clientHeight - rect.height - props.offset)
|
|
||||||
}
|
}
|
||||||
}, 16)
|
};
|
||||||
|
|
||||||
const onTouchEnd = () => {
|
// 面板样式
|
||||||
if (!isDragging) return
|
const panelStyle = computed(() => {
|
||||||
isDragging = false
|
return {
|
||||||
|
left: `${panelPos.value.x}px`,
|
||||||
|
top: `${panelPos.value.y}px`
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const { clientWidth } = document.documentElement
|
// 处理鼠标按下事件
|
||||||
const rect = bubbleRef.value.getBoundingClientRect()
|
const handleMouseDown = (event) => {
|
||||||
const left = clientWidth - position.value.right - rect.width
|
// 只有点击浮动面板本身时才启动拖拽
|
||||||
|
if (event.target === floatPanel.value || floatPanel.value.contains(event.target)) {
|
||||||
// 吸附
|
// 判断是否是面板自身,如果是才阻止默认行为
|
||||||
position.value.right = left < clientWidth / 2
|
if (event.target === floatPanel.value) {
|
||||||
? clientWidth - rect.width - props.offset
|
event.preventDefault();
|
||||||
: props.offset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasDragged.value = false;
|
||||||
|
|
||||||
|
const startX = event.clientX;
|
||||||
|
const startY = event.clientY;
|
||||||
|
|
||||||
|
// 计算点击位置与面板左上角的偏移
|
||||||
|
dragOffset.value = {
|
||||||
|
x: startX - panelPos.value.x,
|
||||||
|
y: startY - panelPos.value.y
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseMove = (e) => {
|
||||||
|
wasDragged.value = true;
|
||||||
|
|
||||||
|
const newX = e.clientX - dragOffset.value.x;
|
||||||
|
const newY = e.clientY - dragOffset.value.y;
|
||||||
|
|
||||||
|
// 应用约束
|
||||||
|
if (!props.fixedX) {
|
||||||
|
panelPos.value.x = Math.max(0, Math.min(newX, windowSize.value.width - panelSize.value.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.fixedY) {
|
||||||
|
panelPos.value.y = Math.max(0, Math.min(newY, windowSize.value.height - panelSize.value.height));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = (e) => {
|
||||||
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
|
|
||||||
|
if (wasDragged.value && props.snapEdge) {
|
||||||
|
snapToEdge();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理触摸开始事件
|
||||||
|
const handleTouchStart = (event) => {
|
||||||
|
// 只有触摸浮动面板本身时才启动拖拽
|
||||||
|
if (event.target === floatPanel.value || floatPanel.value.contains(event.target)) {
|
||||||
|
// 判断是否是面板自身,如果是才阻止默认行为
|
||||||
|
if (event.target === floatPanel.value) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
wasDragged.value = false;
|
||||||
|
|
||||||
|
const touch = event.touches[0];
|
||||||
|
const startX = touch.clientX;
|
||||||
|
const startY = touch.clientY;
|
||||||
|
|
||||||
|
// 计算点击位置与面板左上角的偏移
|
||||||
|
dragOffset.value = {
|
||||||
|
x: startX - panelPos.value.x,
|
||||||
|
y: startY - panelPos.value.y
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTouchMove = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
wasDragged.value = true;
|
||||||
|
|
||||||
|
const touch = e.touches[0];
|
||||||
|
const newX = touch.clientX - dragOffset.value.x;
|
||||||
|
const newY = touch.clientY - dragOffset.value.y;
|
||||||
|
|
||||||
|
// 应用约束
|
||||||
|
if (!props.fixedX) {
|
||||||
|
panelPos.value.x = Math.max(0, Math.min(newX, windowSize.value.width - panelSize.value.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.fixedY) {
|
||||||
|
panelPos.value.y = Math.max(0, Math.min(newY, windowSize.value.height - panelSize.value.height));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTouchEnd = (e) => {
|
||||||
|
document.removeEventListener('touchmove', handleTouchMove);
|
||||||
|
document.removeEventListener('touchend', handleTouchEnd);
|
||||||
|
|
||||||
|
if (wasDragged.value && props.snapEdge) {
|
||||||
|
snapToEdge();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('touchmove', handleTouchMove, { passive: false });
|
||||||
|
document.addEventListener('touchend', handleTouchEnd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 执行吸附
|
||||||
|
const snapToEdge = () => {
|
||||||
|
const centerX = windowSize.value.width / 2;
|
||||||
|
const panelCenterX = panelPos.value.x + panelSize.value.width / 2;
|
||||||
|
|
||||||
|
if (panelCenterX < centerX) {
|
||||||
|
panelPos.value.x = 0; // 吸附到左边
|
||||||
|
console.log('吸附到左边边缘');
|
||||||
|
} else {
|
||||||
|
panelPos.value.x = windowSize.value.width - panelSize.value.width; // 吸附到右边
|
||||||
|
console.log('吸附到右边边缘');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 窗口大小变化处理
|
||||||
|
const handleResize = () => {
|
||||||
|
const oldWidth = windowSize.value.width;
|
||||||
|
const oldHeight = windowSize.value.height;
|
||||||
|
|
||||||
|
updateSizes();
|
||||||
|
|
||||||
|
// 保持相对右边和底部的距离
|
||||||
|
if (props.position.right !== undefined) {
|
||||||
|
const rightDistance = oldWidth - (panelPos.value.x + panelSize.value.width);
|
||||||
|
panelPos.value.x = windowSize.value.width - rightDistance - panelSize.value.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.position.bottom !== undefined) {
|
||||||
|
const bottomDistance = oldHeight - (panelPos.value.y + panelSize.value.height);
|
||||||
|
panelPos.value.y = windowSize.value.height - bottomDistance - panelSize.value.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保不超出边界
|
||||||
|
panelPos.value.x = Math.max(0, Math.min(panelPos.value.x, windowSize.value.width - panelSize.value.width));
|
||||||
|
panelPos.value.y = Math.max(0, Math.min(panelPos.value.y, windowSize.value.height - panelSize.value.height));
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('组件挂载, snapEdge =', props.snapEdge);
|
||||||
|
updateSizes();
|
||||||
|
initPosition();
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
snapToEdge
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.floating-bubble {
|
.float-panel {
|
||||||
touch-action: none;
|
position: fixed;
|
||||||
|
z-index: 1000;
|
||||||
|
cursor: move;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
touch-action: none;
|
||||||
|
transition: left 0.2s ease-out;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -6,7 +6,7 @@ import Cescribe from './components/Cescribe/index.vue'
|
|||||||
import FloatingBubble from '~/components/floating2/index.vue'
|
import FloatingBubble from '~/components/floating2/index.vue'
|
||||||
|
|
||||||
import {liveStore} from "~/stores/live/index.js";
|
import {liveStore} from "~/stores/live/index.js";
|
||||||
const {auctionDetail,getArtworkList} = goodStore();
|
const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore();
|
||||||
const {fullLive} = liveStore()
|
const {fullLive} = liveStore()
|
||||||
const changeLive = () => {
|
const changeLive = () => {
|
||||||
if (!fullLive.value){
|
if (!fullLive.value){
|
||||||
@ -16,7 +16,7 @@ const changeLive = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await getAuctionDetail()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {ref, onMounted, onBeforeUnmount, watch} from 'vue'
|
import {ref, onMounted, onBeforeUnmount, watch,useTemplateRef } from 'vue'
|
||||||
import AliyunPlayer from 'aliyun-aliplayer'
|
import AliyunPlayer from 'aliyun-aliplayer'
|
||||||
import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css'
|
import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css'
|
||||||
import sideButton from '@/pages/liveRoom/components/SideButton/index.vue'
|
import sideButton from '@/pages/liveRoom/components/SideButton/index.vue'
|
||||||
@ -14,6 +14,9 @@ import {showConfirmDialog} from 'vant';
|
|||||||
import {artworkBuy} from "@/api/goods/index.js"
|
import {artworkBuy} from "@/api/goods/index.js"
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import floating2 from '@/components/floating2/index.vue'
|
import floating2 from '@/components/floating2/index.vue'
|
||||||
|
import { UseDraggable } from '@vueuse/components'
|
||||||
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { auctionDetail,getAuctionDetail} = goodStore();
|
const { auctionDetail,getAuctionDetail} = goodStore();
|
||||||
const player = ref(null)
|
const player = ref(null)
|
||||||
@ -127,7 +130,7 @@ const goBuy = async () => {
|
|||||||
message.success(t('live_room.success_mess'))
|
message.success(t('live_room.success_mess'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const sideButtonRef = useTemplateRef('sideButtonRef')
|
||||||
const tipOpen = () => {
|
const tipOpen = () => {
|
||||||
message.warning(t('live_room.warn_mess'))
|
message.warning(t('live_room.warn_mess'))
|
||||||
}
|
}
|
||||||
@ -139,11 +142,14 @@ const tipOpen = () => {
|
|||||||
<div v-if="loading1" class="absolute left-1/2 transform translate-x--1/2 top-1/2 translate-y--1/2">
|
<div v-if="loading1" class="absolute left-1/2 transform translate-x--1/2 top-1/2 translate-y--1/2">
|
||||||
<van-loading type="spinner" >直播加载中...</van-loading>
|
<van-loading type="spinner" >直播加载中...</van-loading>
|
||||||
</div>
|
</div>
|
||||||
|
<client-only>
|
||||||
|
</client-only>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-if="fullLive">
|
<div v-if="fullLive">
|
||||||
|
<floating2
|
||||||
<floating2 top="200px">
|
:snap-edge="true"
|
||||||
|
:position="{right:0,top:300}"
|
||||||
|
>
|
||||||
<sideButton></sideButton>
|
<sideButton></sideButton>
|
||||||
</floating2>
|
</floating2>
|
||||||
<div class="absolute left-1/2 transform -translate-x-1/2 flex flex-col items-center"
|
<div class="absolute left-1/2 transform -translate-x-1/2 flex flex-col items-center"
|
||||||
@ -190,6 +196,21 @@ const tipOpen = () => {
|
|||||||
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.draggable-card {
|
||||||
|
z-index: 999999;
|
||||||
|
padding: 16px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
position: absolute;
|
||||||
|
cursor: move;
|
||||||
|
user-select: none;
|
||||||
|
transition: box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draggable-card.is-dragging {
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
/* 定义过渡动画 */
|
/* 定义过渡动画 */
|
||||||
.fade-enter-active {
|
.fade-enter-active {
|
||||||
transition: opacity 1s ease;
|
transition: opacity 1s ease;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"@fingerprintjs/fingerprintjs": "^4.5.1",
|
"@fingerprintjs/fingerprintjs": "^4.5.1",
|
||||||
"@nuxtjs/i18n": "^9.1.1",
|
"@nuxtjs/i18n": "^9.1.1",
|
||||||
"@vue-office/pdf": "^2.0.10",
|
"@vue-office/pdf": "^2.0.10",
|
||||||
|
"@vueuse/components": "^12.8.2",
|
||||||
"@vueuse/core": "^12.4.0",
|
"@vueuse/core": "^12.4.0",
|
||||||
"aliyun-aliplayer": "^2.28.5",
|
"aliyun-aliplayer": "^2.28.5",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
|
@ -20,6 +20,9 @@ importers:
|
|||||||
'@vue-office/pdf':
|
'@vue-office/pdf':
|
||||||
specifier: ^2.0.10
|
specifier: ^2.0.10
|
||||||
version: 2.0.10(vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
|
version: 2.0.10(vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
|
||||||
|
'@vueuse/components':
|
||||||
|
specifier: ^12.8.2
|
||||||
|
version: 12.8.2(typescript@5.7.3)
|
||||||
'@vueuse/core':
|
'@vueuse/core':
|
||||||
specifier: ^12.4.0
|
specifier: ^12.4.0
|
||||||
version: 12.6.1(typescript@5.7.3)
|
version: 12.6.1(typescript@5.7.3)
|
||||||
@ -1378,6 +1381,9 @@ packages:
|
|||||||
'@types/web-bluetooth@0.0.20':
|
'@types/web-bluetooth@0.0.20':
|
||||||
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
||||||
|
|
||||||
|
'@types/web-bluetooth@0.0.21':
|
||||||
|
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
|
||||||
|
|
||||||
'@types/yauzl@2.10.3':
|
'@types/yauzl@2.10.3':
|
||||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||||
|
|
||||||
@ -1617,15 +1623,27 @@ packages:
|
|||||||
'@vue/shared@3.5.13':
|
'@vue/shared@3.5.13':
|
||||||
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
|
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
|
||||||
|
|
||||||
|
'@vueuse/components@12.8.2':
|
||||||
|
resolution: {integrity: sha512-Nj27u1KsDWzoTthlChzVndJ9g0sW5APCXO3EJkSxlG11nN/ANTUlPPeoJOFvtbdDRnvsMJalboJyE0rRyg7yNg==}
|
||||||
|
|
||||||
'@vueuse/core@12.6.1':
|
'@vueuse/core@12.6.1':
|
||||||
resolution: {integrity: sha512-FpgM1tXGAHsAC5n4Tflyg0vSoJUmdevfKaAhKFdxiK9BTIdHOHOiWmo+xivwdzjYFIvI8cEeJWYuqs646jOM2w==}
|
resolution: {integrity: sha512-FpgM1tXGAHsAC5n4Tflyg0vSoJUmdevfKaAhKFdxiK9BTIdHOHOiWmo+xivwdzjYFIvI8cEeJWYuqs646jOM2w==}
|
||||||
|
|
||||||
|
'@vueuse/core@12.8.2':
|
||||||
|
resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==}
|
||||||
|
|
||||||
'@vueuse/metadata@12.6.1':
|
'@vueuse/metadata@12.6.1':
|
||||||
resolution: {integrity: sha512-2094HNXGdsU3aqRbad0vmlRgGncMC4u2f6nFdW1mUn7b7ym4hORrDZfyeq8G5BfGvX4y0zZynWfCdtB2WwpyVw==}
|
resolution: {integrity: sha512-2094HNXGdsU3aqRbad0vmlRgGncMC4u2f6nFdW1mUn7b7ym4hORrDZfyeq8G5BfGvX4y0zZynWfCdtB2WwpyVw==}
|
||||||
|
|
||||||
|
'@vueuse/metadata@12.8.2':
|
||||||
|
resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==}
|
||||||
|
|
||||||
'@vueuse/shared@12.6.1':
|
'@vueuse/shared@12.6.1':
|
||||||
resolution: {integrity: sha512-ukTb2na19KT1/YVjj4CYBDOgiV/xmsSJRL6TcKeiz2db+P5bT3I0OJxy38eRR3WSN8CmSnt7MdVJ16vX6VZFxg==}
|
resolution: {integrity: sha512-ukTb2na19KT1/YVjj4CYBDOgiV/xmsSJRL6TcKeiz2db+P5bT3I0OJxy38eRR3WSN8CmSnt7MdVJ16vX6VZFxg==}
|
||||||
|
|
||||||
|
'@vueuse/shared@12.8.2':
|
||||||
|
resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==}
|
||||||
|
|
||||||
'@webassemblyjs/ast@1.14.1':
|
'@webassemblyjs/ast@1.14.1':
|
||||||
resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
|
resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
|
||||||
|
|
||||||
@ -6016,6 +6034,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/web-bluetooth@0.0.20': {}
|
'@types/web-bluetooth@0.0.20': {}
|
||||||
|
|
||||||
|
'@types/web-bluetooth@0.0.21': {}
|
||||||
|
|
||||||
'@types/yauzl@2.10.3':
|
'@types/yauzl@2.10.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.13.4
|
'@types/node': 22.13.4
|
||||||
@ -6449,6 +6469,14 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/shared@3.5.13': {}
|
'@vue/shared@3.5.13': {}
|
||||||
|
|
||||||
|
'@vueuse/components@12.8.2(typescript@5.7.3)':
|
||||||
|
dependencies:
|
||||||
|
'@vueuse/core': 12.8.2(typescript@5.7.3)
|
||||||
|
'@vueuse/shared': 12.8.2(typescript@5.7.3)
|
||||||
|
vue: 3.5.13(typescript@5.7.3)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- typescript
|
||||||
|
|
||||||
'@vueuse/core@12.6.1(typescript@5.7.3)':
|
'@vueuse/core@12.6.1(typescript@5.7.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/web-bluetooth': 0.0.20
|
'@types/web-bluetooth': 0.0.20
|
||||||
@ -6458,14 +6486,31 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
|
'@vueuse/core@12.8.2(typescript@5.7.3)':
|
||||||
|
dependencies:
|
||||||
|
'@types/web-bluetooth': 0.0.21
|
||||||
|
'@vueuse/metadata': 12.8.2
|
||||||
|
'@vueuse/shared': 12.8.2(typescript@5.7.3)
|
||||||
|
vue: 3.5.13(typescript@5.7.3)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- typescript
|
||||||
|
|
||||||
'@vueuse/metadata@12.6.1': {}
|
'@vueuse/metadata@12.6.1': {}
|
||||||
|
|
||||||
|
'@vueuse/metadata@12.8.2': {}
|
||||||
|
|
||||||
'@vueuse/shared@12.6.1(typescript@5.7.3)':
|
'@vueuse/shared@12.6.1(typescript@5.7.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.13(typescript@5.7.3)
|
vue: 3.5.13(typescript@5.7.3)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
|
'@vueuse/shared@12.8.2(typescript@5.7.3)':
|
||||||
|
dependencies:
|
||||||
|
vue: 3.5.13(typescript@5.7.3)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- typescript
|
||||||
|
|
||||||
'@webassemblyjs/ast@1.14.1':
|
'@webassemblyjs/ast@1.14.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@webassemblyjs/helper-numbers': 1.13.2
|
'@webassemblyjs/helper-numbers': 1.13.2
|
||||||
|
Loading…
Reference in New Issue
Block a user