feat: 处理nuxt部分样式问题 & 跳转问题

This commit is contained in:
Tim
2025-08-08 11:24:52 +08:00
parent 2b1958a603
commit 44daa255c8
8 changed files with 107 additions and 108 deletions

View File

@@ -26,7 +26,7 @@ export default {
components: { HeaderComponent, MenuComponent, GlobalPopups },
data() {
return {
menuVisible: process.client ? window.innerWidth > 768 : false
menuVisible: true
}
},
computed: {
@@ -45,7 +45,9 @@ export default {
}
},
async mounted() {
// placeholder for future global initializations
if (typeof window !== 'undefined') {
this.menuVisible = window.innerWidth > 768
}
},
methods: {}
}

View File

@@ -69,6 +69,8 @@ export default {
.dropdown-menu-container {
position: absolute;
top: 100%;
right: 0;
background-color: var(--menu-background-color);
border: 1px solid var(--normal-border-color);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);

View File

@@ -15,27 +15,29 @@
</div>
</div>
<div v-if="isLogin" class="header-content-right">
<div v-if="isMobile" class="search-icon" @click="search">
<i class="fas fa-search"></i>
<ClientOnly>
<div v-if="isLogin" class="header-content-right">
<div v-if="isMobile" class="search-icon" @click="search">
<i class="fas fa-search"></i>
</div>
<DropdownMenu ref="userMenu" :items="headerMenuItems">
<template #trigger>
<div class="avatar-container">
<img class="avatar-img" :src="avatar" alt="avatar">
<i class="fas fa-caret-down dropdown-icon"></i>
</div>
</template>
</DropdownMenu>
</div>
<DropdownMenu ref="userMenu" :items="headerMenuItems">
<template #trigger>
<div class="avatar-container">
<img class="avatar-img" :src="avatar" alt="avatar">
<i class="fas fa-caret-down dropdown-icon"></i>
</div>
</template>
</DropdownMenu>
</div>
<div v-else class="header-content-right">
<div v-if="isMobile" class="search-icon" @click="search">
<i class="fas fa-search"></i>
<div v-else class="header-content-right">
<div v-if="isMobile" class="search-icon" @click="search">
<i class="fas fa-search"></i>
</div>
<div class="header-content-item-main" @click="goToLogin">登录</div>
<div class="header-content-item-secondary" @click="goToSignup">注册</div>
</div>
<div class="header-content-item-main" @click="goToLogin">登录</div>
<div class="header-content-item-secondary" @click="goToSignup">注册</div>
</div>
</ClientOnly>
<SearchDropdown ref="searchDropdown" v-if="isMobile && showSearch" @close="closeSearch" />
</div>
@@ -49,6 +51,7 @@ import { fetchUnreadCount, notificationState } from '~/utils/notification'
import DropdownMenu from '~/components/DropdownMenu.vue'
import SearchDropdown from '~/components/SearchDropdown.vue'
import { isMobile } from '~/utils/screen'
import { ClientOnly } from '#components'
export default {
name: 'HeaderComponent',
@@ -62,27 +65,82 @@ export default {
data() {
return {
avatar: '',
showSearch: false
showSearch: false,
searchDropdown: null
}
},
computed: {
isLogin() {
return authState.loggedIn
},
isMobile() {
return isMobile.value
},
headerMenuItems() {
return [
{ text: '设置', onClick: this.goToSettings },
{ text: '个人主页', onClick: this.goToProfile },
{ text: '退出', onClick: this.goToLogout }
]
},
unreadCount() {
return notificationState.unreadCount
setup() {
const isLogin = computed(() => authState.loggedIn)
const isMobile = computed(() => isMobile.value)
const unreadCount = computed(() => notificationState.unreadCount)
const router = useRouter()
const goToHome = () => {
router.push('/')
}
const search = () => {
showSearch.value = true
nextTick(() => {
searchDropdown.value.toggle()
})
}
const closeSearch = () => {
nextTick(() => {
showSearch.value = false
})
}
const goToLogin = () => {
router.push('/login')
}
const goToSettings = () => {
router.push('/settings')
}
const goToProfile = async () => {
if (!authState.loggedIn) {
router.push('/login')
return
}
let id = authState.username || authState.userId
if (!id) {
const user = await loadCurrentUser()
if (user) {
id = user.username || user.id
}
}
if (id) {
router.push(`/users/${id}`)
}
}
const goToSignup = () => {
router.push('/signup')
}
const goToLogout = () => {
clearToken()
this.$router.push('/login')
}
const headerMenuItems = computed(() => [
{ text: '设置', onClick: goToSettings },
{ text: '个人主页', onClick: goToProfile },
{ text: '退出', onClick: goToLogout }
])
return {
isLogin,
isMobile,
headerMenuItems,
unreadCount,
goToHome,
search,
closeSearch,
goToLogin,
goToSettings,
goToProfile,
goToSignup,
goToLogout
}
},
async mounted() {
const updateAvatar = async () => {
if (authState.loggedIn) {
@@ -113,57 +171,6 @@ export default {
this.showSearch = false
})
},
methods: {
goToHome() {
this.$router.push('/').then(() => {
window.location.reload()
})
},
search() {
this.showSearch = true
nextTick(() => {
this.$refs.searchDropdown.toggle()
})
},
closeSearch() {
nextTick(() => {
this.showSearch = false
})
},
goToLogin() {
this.$router.push('/login')
},
goToSettings() {
this.$router.push('/settings')
},
async goToProfile() {
if (!authState.loggedIn) {
this.$router.push('/login')
return
}
let id = authState.username || authState.userId
if (!id) {
const user = await loadCurrentUser()
if (user) {
id = user.username || user.id
}
}
if (id) {
this.$router.push(`/users/${id}`).then(() => {
window.location.reload()
})
}
},
goToSignup() {
this.$router.push('/signup')
},
goToLogout() {
clearToken()
this.$router.push('/login')
}
}
}
</script>

View File

@@ -246,18 +246,12 @@ export default {
const value = encodeURIComponent(c.id ?? c.name)
this.$router
.push({ path: '/', query: { category: value } })
.then(() => {
window.location.reload()
})
this.handleItemClick()
},
gotoTag(t) {
const value = encodeURIComponent(t.id ?? t.name)
this.$router
.push({ path: '/', query: { tags: value } })
.then(() => {
window.location.reload()
})
this.handleItemClick()
}
}

View File

@@ -92,13 +92,9 @@ export default {
router.push(`/posts/${opt.postId}#comment-${opt.id}`)
}
} else if (opt.type === 'category') {
router.push({ path: '/', query: { category: opt.id } }).then(() => {
window.location.reload()
})
router.push({ path: '/', query: { category: opt.id } })
} else if (opt.type === 'tag') {
router.push({ path: '/', query: { tags: opt.id } }).then(() => {
window.location.reload()
})
router.push({ path: '/', query: { tags: opt.id } })
}
selected.value = null
keyword.value = ''

View File

@@ -22,9 +22,7 @@ export default {
},
methods: {
handleUserClick(user) {
this.$router.push(`/users/${user.id}`).then(() => {
window.location.reload()
})
this.$router.push(`/users/${user.id}`)
}
}
}

View File

@@ -431,9 +431,7 @@ export default {
const gotoTag = tag => {
const value = encodeURIComponent(tag.id ?? tag.name)
router.push({ path: '/', query: { tags: value } }).then(() => {
window.location.reload()
})
router.push({ path: '/', query: { tags: value } })
}
const init = async () => {

View File

@@ -1,12 +1,14 @@
import { ref, computed } from 'vue'
const width = ref(0)
const isClient = ref(false)
if (process.client) {
if (typeof window !== 'undefined') {
isClient.value = true
width.value = window.innerWidth
window.addEventListener('resize', () => {
width.value = window.innerWidth
})
}
export const isMobile = computed(() => width.value <= 768)
export const isMobile = computed(() => isClient.value && width.value <= 768)