Sink/app/components/dashboard/analysis/Views.vue
ccbikai 70d6632fd0 refactor: remove redundant watcher cleanup in Vue comps
Removes unnecessary manual watcher cleanup via stopWatchQueryChange across multiple Vue components.

Vue 3's watch() automatically handles cleanup when components are unmounted, making explicit stopWatchQueryChange calls and onBeforeUnmount handlers redundant.

This change:
- Improves code maintainability
- Reduces boilerplate code
- Follows Vue 3 best practices for reactive system cleanup
2025-05-18 19:13:04 +08:00

91 lines
2.1 KiB
Vue

<script setup>
import { AreaChart } from '@/components/ui/chart-area'
import { BarChart } from '@/components/ui/chart-bar'
const props = defineProps({
mode: {
type: String,
default: 'full',
},
chartType: {
type: String,
default: 'area',
},
})
const views = ref([])
const chart = computed(() => (props.chartType === 'area' && views.value.length > 1) ? AreaChart : BarChart)
const id = inject('id')
const time = inject('time')
const filters = inject('filters')
const OneHour = 60 * 60 // 1 hour in seconds
const OneDay = 24 * 60 * 60 // 1 day in seconds
function getUnit(startAt, endAt) {
if (startAt && endAt && endAt - startAt <= OneHour)
return 'minute'
if (startAt && endAt && endAt - startAt <= OneDay)
return 'hour'
return 'day'
}
async function getLinkViews() {
views.value = []
const { data } = await useAPI('/api/stats/views', {
query: {
id: id.value,
unit: getUnit(time.value.startAt, time.value.endAt),
clientTimezone: getTimeZone(),
startAt: time.value.startAt,
endAt: time.value.endAt,
...filters.value,
},
})
views.value = (data || []).map((item) => {
item.visitors = +item.visitors
item.visits = +item.visits
return item
})
}
watch([time, filters], getLinkViews, {
deep: true,
})
onMounted(async () => {
getLinkViews()
})
function formatTime(tick) {
if (Number.isInteger(tick) && views.value[tick]) {
if (getUnit(time.value.startAt, time.value.endAt) === 'hour')
return views.value[tick].time.split(' ')[1] || ''
return views.value[tick].time
}
return ''
}
</script>
<template>
<Card class="px-0 py-6 md:px-6">
<CardTitle v-if="mode === 'full'" class="px-6 md:px-0">
{{ $t('dashboard.views') }}
</CardTitle>
<component
:is="chart"
v-if="views.length"
class="w-full h-full"
index="time"
:data="views"
:categories="mode === 'full' ? ['visits', 'visitors'] : ['visits']"
:x-formatter="formatTime"
:y-formatter="formatNumber"
:show-grid-line="mode === 'full'"
:show-legend="mode === 'full'"
/>
</Card>
</template>