From d4ad65a1ea1500af2dede29e724340cb2ed0d6d0 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Fri, 31 Oct 2025 17:42:28 +0800 Subject: [PATCH] refactor: use deconstruct syntax to handle component props (#744) --- .../src/client/components/Annotation.vue | 4 +-- .../src/client/components/AudioReader.vue | 21 ++++++------ .../src/client/components/CanIUse.vue | 14 +++----- .../src/client/components/CodePen.vue | 14 ++++---- .../src/client/components/FileTreeNode.vue | 10 +++--- .../src/client/components/JsFiddle.vue | 6 ++-- .../src/client/components/Replit.vue | 10 +++--- .../src/client/components/Tabs.vue | 24 +++++++------- .../src/client/components/VPCodeTree.vue | 10 +++--- .../src/client/components/VPCollapse.vue | 6 ++-- .../src/client/components/VPCollapseItem.vue | 26 +++++++-------- .../src/client/components/VPDemoBasic.vue | 6 ++-- .../src/client/components/VPDemoNormal.vue | 12 +++---- .../src/client/components/VPTable.vue | 6 ++-- .../src/client/components/VPTimeline.vue | 10 +++--- .../src/client/components/VPTimelineItem.vue | 20 ++++++------ .../src/client/components/SearchBox.vue | 10 +++--- .../src/client/components/SearchButton.vue | 4 +-- .../client/components/Home/VPHomeBanner.vue | 16 +++++----- .../src/client/components/Home/VPHomeBox.vue | 16 +++++----- .../client/components/Home/VPHomeFeature.vue | 6 ++-- .../client/components/Home/VPHomeFeatures.vue | 26 ++++++--------- .../src/client/components/Home/VPHomeHero.vue | 25 +++++++++++---- .../client/components/Home/VPHomeProfile.vue | 16 ++++------ .../components/Home/VPHomeTextImage.vue | 12 ++----- theme/src/client/components/Nav/VPNavBar.vue | 4 +-- .../components/Nav/VPNavBarHamburger.vue | 2 +- .../components/Nav/VPNavBarMenuGroup.vue | 6 ++-- .../components/Nav/VPNavBarMenuLink.vue | 2 +- .../src/client/components/Nav/VPNavScreen.vue | 2 +- .../components/Nav/VPNavScreenMenuGroup.vue | 4 +-- .../Nav/VPNavScreenMenuGroupLink.vue | 2 +- .../Nav/VPNavScreenMenuGroupSection.vue | 2 +- .../components/Nav/VPNavScreenMenuLink.vue | 2 +- .../client/components/Posts/VPCategories.vue | 6 ++-- .../components/Posts/VPCategoriesGroup.vue | 15 ++++----- .../client/components/Posts/VPPagination.vue | 2 +- .../client/components/Posts/VPPostItem.vue | 28 ++++++++-------- .../client/components/Posts/VPPostList.vue | 4 +-- theme/src/client/components/Posts/VPPosts.vue | 6 ++-- .../client/components/Posts/VPPostsNav.vue | 4 +-- .../components/Posts/VPShortPostList.vue | 2 +- theme/src/client/components/VPBackdrop.vue | 2 +- theme/src/client/components/VPContent.vue | 4 +-- theme/src/client/components/VPDocHeader.vue | 2 +- .../client/components/VPDocOutlineItem.vue | 2 +- theme/src/client/components/VPEncryptForm.vue | 4 +-- theme/src/client/components/VPFlyout.vue | 2 +- .../src/client/components/VPFriendsGroup.vue | 2 +- theme/src/client/components/VPFriendsItem.vue | 8 ++--- theme/src/client/components/VPIcon.vue | 23 +++++++------ theme/src/client/components/VPIconFa.vue | 13 ++++---- theme/src/client/components/VPIconImage.vue | 10 +++--- theme/src/client/components/VPIconfont.vue | 8 ++--- theme/src/client/components/VPIconify.vue | 9 +++--- theme/src/client/components/VPImage.vue | 3 +- theme/src/client/components/VPLocalNav.vue | 4 +-- .../components/VPLocalNavOutlineDropdown.vue | 6 ++-- theme/src/client/components/VPMenu.vue | 2 +- theme/src/client/components/VPMenuGroup.vue | 2 +- theme/src/client/components/VPMenuLink.vue | 2 +- theme/src/client/components/VPSidebar.vue | 6 ++-- .../src/client/components/VPSidebarGroup.vue | 2 +- theme/src/client/components/VPSidebarItem.vue | 16 +++++----- theme/src/client/components/VPSocialLink.vue | 8 ++--- theme/src/client/components/VPSocialLinks.vue | 2 +- .../client/components/VPTransitionDrop.vue | 7 ++-- .../src/client/components/global/VPBadge.vue | 13 +++----- theme/src/client/components/global/VPCard.vue | 10 +++--- .../client/components/global/VPCardGrid.vue | 14 ++++---- .../components/global/VPCardMasonry.vue | 27 +++++++--------- .../client/components/global/VPImageCard.vue | 32 +++++++++---------- .../client/components/global/VPLinkCard.vue | 2 +- 73 files changed, 320 insertions(+), 350 deletions(-) diff --git a/plugins/plugin-md-power/src/client/components/Annotation.vue b/plugins/plugin-md-power/src/client/components/Annotation.vue index 263c945f..4bf88761 100644 --- a/plugins/plugin-md-power/src/client/components/Annotation.vue +++ b/plugins/plugin-md-power/src/client/components/Annotation.vue @@ -4,13 +4,13 @@ import { computed, nextTick, ref, useTemplateRef, watch } from 'vue' import '@vuepress/helper/transition/fade-in.css' -const props = defineProps<{ +const { label, total } = defineProps<{ label: string total: number }>() const active = ref(false) -const list = computed(() => Array.from({ length: props.total }, (_, i) => i)) +const list = computed(() => Array.from({ length: total }, (_, i) => i)) const position = ref({ x: 0, y: 0 }) const popover = useTemplateRef('popover') diff --git a/plugins/plugin-md-power/src/client/components/AudioReader.vue b/plugins/plugin-md-power/src/client/components/AudioReader.vue index ff704bc0..37373c23 100644 --- a/plugins/plugin-md-power/src/client/components/AudioReader.vue +++ b/plugins/plugin-md-power/src/client/components/AudioReader.vue @@ -3,7 +3,7 @@ import { useInterval } from '@vueuse/core' import { onMounted, toRef, watch } from 'vue' import { useAudioPlayer } from '../composables/audio.js' -const props = defineProps<{ +const { src, autoplay, type, volume, startTime, endTime } = defineProps<{ src: string autoplay?: boolean type?: string @@ -13,20 +13,19 @@ const props = defineProps<{ }>() const { paused, play, pause, seek, setVolume } = useAudioPlayer( - toRef(() => props.src), + toRef(() => src), { - type: toRef(() => props.type || ''), - autoplay: props.autoplay, + type: toRef(() => type || ''), + autoplay, oncanplay: () => { - if (props.startTime) { - seek(props.startTime) - } + if (startTime) + seek(startTime) }, ontimeupdate: (time) => { - if (props.endTime && time >= props.endTime) { + if (endTime && time >= endTime) { pause() - if (props.startTime) { - seek(props.startTime) + if (startTime) { + seek(startTime) } } }, @@ -56,7 +55,7 @@ function toggle() { } onMounted(() => { - watch(() => props.volume, (volume) => { + watch(() => volume, (volume) => { if (typeof volume !== 'undefined') { setVolume(volume) } diff --git a/plugins/plugin-md-power/src/client/components/CanIUse.vue b/plugins/plugin-md-power/src/client/components/CanIUse.vue index b7fb0c9f..1cae46fb 100644 --- a/plugins/plugin-md-power/src/client/components/CanIUse.vue +++ b/plugins/plugin-md-power/src/client/components/CanIUse.vue @@ -12,16 +12,12 @@ interface MessageData { } } -const props = withDefaults(defineProps<{ +const { feature, past = 2, future = 1, meta = '' } = defineProps<{ feature: string past?: number future?: number meta?: string -}>(), { - past: 2, - future: 1, - meta: '', -}) +}>() const url = 'https://caniuse.pengzhanbo.cn/' @@ -29,7 +25,7 @@ const height = ref('330px') const isDark = useDarkMode() const source = computed(() => { - const source = `${url}${props.feature}#past=${props.past}&future=${props.future}&meta=${props.meta}&theme=${isDark.value ? 'dark' : 'light'}` + const source = `${url}${feature}#past=${past}&future=${future}&meta=${meta}&theme=${isDark.value ? 'dark' : 'light'}` return source }) @@ -40,8 +36,8 @@ useEventListener('message', (event) => { if ( type === 'ciu_embed' && payload - && payload.feature === props.feature - && payload.meta === props.meta + && payload.feature === feature + && payload.meta === meta ) { height.value = `${Math.ceil(payload.height)}px` } diff --git a/plugins/plugin-md-power/src/client/components/CodePen.vue b/plugins/plugin-md-power/src/client/components/CodePen.vue index ef19e19e..548381d6 100644 --- a/plugins/plugin-md-power/src/client/components/CodePen.vue +++ b/plugins/plugin-md-power/src/client/components/CodePen.vue @@ -2,7 +2,7 @@ import { useDarkMode } from '@vuepress/helper/client' import { computed } from 'vue' -const props = defineProps<{ +const { user, slash, title, preview, editable, tab, theme, width, height } = defineProps<{ user: string slash: string title?: string @@ -19,16 +19,16 @@ const CODEPEN_LINK = 'https://codepen.io/' const isDark = useDarkMode() const link = computed(() => { - const middle = props.preview ? '/embed/preview/' : '/embed/' + const middle = preview ? '/embed/preview/' : '/embed/' const params = new URLSearchParams() - props.editable && params.set('editable', 'true') - props.tab && params.set('default-tab', props.tab) + editable && params.set('editable', 'true') + tab && params.set('default-tab', tab) - const theme = props.theme ?? (isDark.value ? 'dark' : 'light') - theme && params.set('theme-id', theme) + const themeMode = theme ?? (isDark.value ? 'dark' : 'light') + themeMode && params.set('theme-id', themeMode) - return `${CODEPEN_LINK}${props.user}${middle}${props.slash}?${params.toString()}` + return `${CODEPEN_LINK}${user}${middle}${slash}?${params.toString()}` }) diff --git a/plugins/plugin-md-power/src/client/components/FileTreeNode.vue b/plugins/plugin-md-power/src/client/components/FileTreeNode.vue index f313dba0..60b3c5e3 100644 --- a/plugins/plugin-md-power/src/client/components/FileTreeNode.vue +++ b/plugins/plugin-md-power/src/client/components/FileTreeNode.vue @@ -2,7 +2,7 @@ import type { Ref } from 'vue' import { inject, ref } from 'vue' -const props = defineProps<{ +const { type, filename, level, diff, expanded, focus, filepath } = defineProps<{ type: 'file' | 'folder' filename: string level: number @@ -18,17 +18,17 @@ const onNodeClick = inject< (filename: string, type: 'file' | 'folder') => void >('on-file-tree-node-click', () => {}) -const active = ref(props.expanded) +const active = ref(expanded) function nodeClick() { - if (props.filename === '…' || props.filename === '...') + if (filename === '…' || filename === '...') return - onNodeClick(props.filepath || props.filename, props.type) + onNodeClick(filepath || filename, type) } function toggle(ev: MouseEvent) { - if (props.type === 'folder') { + if (type === 'folder') { const el = ev.target as HTMLElement if (!el.matches('.comment, .comment *')) { active.value = !active.value diff --git a/plugins/plugin-md-power/src/client/components/JsFiddle.vue b/plugins/plugin-md-power/src/client/components/JsFiddle.vue index a24eca09..6a40176f 100644 --- a/plugins/plugin-md-power/src/client/components/JsFiddle.vue +++ b/plugins/plugin-md-power/src/client/components/JsFiddle.vue @@ -2,7 +2,7 @@ import { useDarkMode } from '@vuepress/helper/client' import { computed } from 'vue' -const props = defineProps<{ +const { source, title, tab, theme, width, height } = defineProps<{ source: string title?: string tab: string @@ -14,8 +14,8 @@ const props = defineProps<{ const isDark = useDarkMode() const link = computed(() => { - const theme = props.theme === 'dark' ? '/dark/' : isDark.value ? '/dark/' : '' - return `https://jsfiddle.net/${props.source}/embedded/${props.tab}${theme}` + const themeMode = theme === 'dark' ? '/dark/' : isDark.value ? '/dark/' : '' + return `https://jsfiddle.net/${source}/embedded/${tab}${themeMode}` }) diff --git a/plugins/plugin-md-power/src/client/components/Replit.vue b/plugins/plugin-md-power/src/client/components/Replit.vue index d7ba5773..26516779 100644 --- a/plugins/plugin-md-power/src/client/components/Replit.vue +++ b/plugins/plugin-md-power/src/client/components/Replit.vue @@ -8,7 +8,7 @@ defineOptions({ inheritAttrs: false, }) -const props = defineProps() +const { source, theme, width, height: h, title } = defineProps() // magic height const height = ref('47px') @@ -19,18 +19,18 @@ const REPLIT_LINK = 'https://replit.com/' const isDark = useDarkMode() const link = computed(() => { - const url = new URL(`/${props.source}`, REPLIT_LINK) + const url = new URL(`/${source}`, REPLIT_LINK) url.searchParams.set('embed', 'true') - const theme = props.theme || (isDark.value ? 'dark' : 'light') - url.searchParams.set('theme', theme) + const themeMode = theme || (isDark.value ? 'dark' : 'light') + url.searchParams.set('theme', themeMode) return url.toString() }) function onload() { loaded.value = true - height.value = props.height || '450px' + height.value = h || '450px' } diff --git a/plugins/plugin-md-power/src/client/components/Tabs.vue b/plugins/plugin-md-power/src/client/components/Tabs.vue index b480bc82..4381c007 100644 --- a/plugins/plugin-md-power/src/client/components/Tabs.vue +++ b/plugins/plugin-md-power/src/client/components/Tabs.vue @@ -5,27 +5,27 @@ import { onMounted, ref, shallowRef, watch } from 'vue' interface TabProps extends Record { id: string } -const props = withDefaults(defineProps<{ +const { id, tabId = '', active = 0, data } = defineProps<{ id: string tabId?: string active?: number data: TabProps[] -}>(), { active: 0, tabId: '' }) +}>() const TAB_STORE_NAME = 'VUEPRESS_TAB_STORE' const tabStore = useStorage>(TAB_STORE_NAME, {}) // Index of current active item -const activeIndex = ref(props.active) +const activeIndex = ref(active) // Refs of the tab buttons const tabRefs = shallowRef([]) // Update store function updateStore(): void { - if (props.tabId) - tabStore.value[props.tabId] = props.data[activeIndex.value].id + if (tabId) + tabStore.value[tabId] = data[activeIndex.value]?.id } // Activate next tab @@ -59,26 +59,26 @@ function keyboardHandler(event: KeyboardEvent, index: number): void { } function getInitialIndex(): number { - if (props.tabId) { - const valueIndex = props.data.findIndex( - ({ id }) => tabStore.value[props.tabId] === id, + if (tabId) { + const valueIndex = data.findIndex( + ({ id }) => tabStore.value[tabId] === id, ) if (valueIndex !== -1) return valueIndex } - return props.active + return active } onMounted(() => { activeIndex.value = getInitialIndex() watch( - () => tabStore.value[props.tabId], + () => tabStore.value[tabId], (newValue, oldValue) => { - if (props.tabId && newValue !== oldValue) { - const index = props.data.findIndex(({ id }) => id === newValue) + if (tabId && newValue !== oldValue) { + const index = data.findIndex(({ id }) => id === newValue) if (index !== -1) activeIndex.value = index diff --git a/plugins/plugin-md-power/src/client/components/VPCodeTree.vue b/plugins/plugin-md-power/src/client/components/VPCodeTree.vue index 78905e23..cae7e733 100644 --- a/plugins/plugin-md-power/src/client/components/VPCodeTree.vue +++ b/plugins/plugin-md-power/src/client/components/VPCodeTree.vue @@ -1,13 +1,13 @@ diff --git a/plugins/plugin-md-power/src/client/components/VPCollapseItem.vue b/plugins/plugin-md-power/src/client/components/VPCollapseItem.vue index 7a28022e..e3e2fac7 100644 --- a/plugins/plugin-md-power/src/client/components/VPCollapseItem.vue +++ b/plugins/plugin-md-power/src/client/components/VPCollapseItem.vue @@ -6,7 +6,7 @@ import { INJECT_COLLAPSE_KEY } from '../options.js' import '@vuepress/helper/transition/fade-in-height-expand.css' -const props = defineProps<{ +const { expand, index } = defineProps<{ expand?: boolean index: number }>() @@ -20,36 +20,36 @@ if (__VUEPRESS_DEV__ && !collapse) { throw new Error(' must be used inside ') } -const expand = ref( +const expanded = ref( collapse?.accordion && typeof collapse.index.value !== 'undefined' - ? props.index === collapse.index.value - : props.expand, + ? index === collapse.index.value + : expand, ) if (collapse?.accordion) { watch(collapse?.index, () => { - expand.value = collapse?.index.value === props.index + expanded.value = collapse?.index.value === index }) } function toggle() { if (collapse?.accordion) { - if (collapse.index.value === props.index && expand.value) { - expand.value = false + if (collapse.index.value === index && expanded.value) { + expanded.value = false } else { - collapse!.index.value = props.index! - expand.value = true + collapse!.index.value = index! + expanded.value = true } } else { - expand.value = !expand.value + expanded.value = !expanded.value } }