🎨 Improve code readability by reformatting functions and cleaning up whitespace

This commit is contained in:
2026-01-28 19:50:00 +00:00
parent b3d6bb0772
commit 07c4379d81
6 changed files with 319 additions and 14 deletions

View File

@@ -0,0 +1,84 @@
/**
* URL State Composable
* Synchronizes component state with URL query parameters
*/
import { watch, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
/**
* Sync state with URL query parameters
* @param {Object} stateRefs - Object of refs to sync {key: ref}
* @returns {Object} Control functions
*/
export function useUrlState(stateRefs) {
const router = useRouter();
const route = useRoute();
/**
* Update URL with current state
*/
const updateUrl = () => {
const query = {};
Object.entries(stateRefs).forEach(([key, ref]) => {
const value = ref.value;
if (value !== null && value !== undefined && value !== '') {
if (Array.isArray(value)) {
query[key] = value.join(',');
} else {
query[key] = String(value);
}
}
});
router.replace({ query });
};
/**
* Load state from URL
*/
const loadFromUrl = () => {
Object.entries(stateRefs).forEach(([key, ref]) => {
const value = route.query[key];
if (value) {
if (Array.isArray(ref.value)) {
ref.value = value.split(',');
} else if (typeof ref.value === 'number') {
ref.value = parseInt(value, 10) || 0;
} else if (typeof ref.value === 'boolean') {
ref.value = value === 'true';
} else {
ref.value = value;
}
}
});
};
/**
* Handle browser back/forward
*/
const handlePopState = () => {
loadFromUrl();
};
onMounted(() => {
// Load initial state from URL
loadFromUrl();
// Listen for browser back/forward
window.addEventListener('popstate', handlePopState);
});
// Watch for state changes and update URL
Object.values(stateRefs).forEach(ref => {
watch(ref, updateUrl, { deep: true });
});
return {
updateUrl,
loadFromUrl
};
}