mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-15 00:20:47 +08:00
feat: 处理nuxt部分样式问题 & 跳转问题
This commit is contained in:
@@ -26,7 +26,7 @@ export default {
|
|||||||
components: { HeaderComponent, MenuComponent, GlobalPopups },
|
components: { HeaderComponent, MenuComponent, GlobalPopups },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
menuVisible: process.client ? window.innerWidth > 768 : false
|
menuVisible: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -45,7 +45,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
// placeholder for future global initializations
|
if (typeof window !== 'undefined') {
|
||||||
|
this.menuVisible = window.innerWidth > 768
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ export default {
|
|||||||
|
|
||||||
.dropdown-menu-container {
|
.dropdown-menu-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
right: 0;
|
||||||
background-color: var(--menu-background-color);
|
background-color: var(--menu-background-color);
|
||||||
border: 1px solid var(--normal-border-color);
|
border: 1px solid var(--normal-border-color);
|
||||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
|
||||||
|
|||||||
@@ -15,27 +15,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isLogin" class="header-content-right">
|
<ClientOnly>
|
||||||
<div v-if="isMobile" class="search-icon" @click="search">
|
<div v-if="isLogin" class="header-content-right">
|
||||||
<i class="fas fa-search"></i>
|
<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>
|
</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-else class="header-content-right">
|
||||||
<div v-if="isMobile" class="search-icon" @click="search">
|
<div v-if="isMobile" class="search-icon" @click="search">
|
||||||
<i class="fas fa-search"></i>
|
<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>
|
||||||
<div class="header-content-item-main" @click="goToLogin">登录</div>
|
</ClientOnly>
|
||||||
<div class="header-content-item-secondary" @click="goToSignup">注册</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<SearchDropdown ref="searchDropdown" v-if="isMobile && showSearch" @close="closeSearch" />
|
<SearchDropdown ref="searchDropdown" v-if="isMobile && showSearch" @close="closeSearch" />
|
||||||
</div>
|
</div>
|
||||||
@@ -49,6 +51,7 @@ import { fetchUnreadCount, notificationState } from '~/utils/notification'
|
|||||||
import DropdownMenu from '~/components/DropdownMenu.vue'
|
import DropdownMenu from '~/components/DropdownMenu.vue'
|
||||||
import SearchDropdown from '~/components/SearchDropdown.vue'
|
import SearchDropdown from '~/components/SearchDropdown.vue'
|
||||||
import { isMobile } from '~/utils/screen'
|
import { isMobile } from '~/utils/screen'
|
||||||
|
import { ClientOnly } from '#components'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HeaderComponent',
|
name: 'HeaderComponent',
|
||||||
@@ -62,27 +65,82 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
avatar: '',
|
avatar: '',
|
||||||
showSearch: false
|
showSearch: false,
|
||||||
|
searchDropdown: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
setup() {
|
||||||
isLogin() {
|
const isLogin = computed(() => authState.loggedIn)
|
||||||
return authState.loggedIn
|
const isMobile = computed(() => isMobile.value)
|
||||||
},
|
const unreadCount = computed(() => notificationState.unreadCount)
|
||||||
isMobile() {
|
const router = useRouter()
|
||||||
return isMobile.value
|
|
||||||
},
|
const goToHome = () => {
|
||||||
headerMenuItems() {
|
router.push('/')
|
||||||
return [
|
}
|
||||||
{ text: '设置', onClick: this.goToSettings },
|
const search = () => {
|
||||||
{ text: '个人主页', onClick: this.goToProfile },
|
showSearch.value = true
|
||||||
{ text: '退出', onClick: this.goToLogout }
|
nextTick(() => {
|
||||||
]
|
searchDropdown.value.toggle()
|
||||||
},
|
})
|
||||||
unreadCount() {
|
}
|
||||||
return notificationState.unreadCount
|
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() {
|
async mounted() {
|
||||||
const updateAvatar = async () => {
|
const updateAvatar = async () => {
|
||||||
if (authState.loggedIn) {
|
if (authState.loggedIn) {
|
||||||
@@ -113,57 +171,6 @@ export default {
|
|||||||
this.showSearch = false
|
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>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -246,18 +246,12 @@ export default {
|
|||||||
const value = encodeURIComponent(c.id ?? c.name)
|
const value = encodeURIComponent(c.id ?? c.name)
|
||||||
this.$router
|
this.$router
|
||||||
.push({ path: '/', query: { category: value } })
|
.push({ path: '/', query: { category: value } })
|
||||||
.then(() => {
|
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
this.handleItemClick()
|
this.handleItemClick()
|
||||||
},
|
},
|
||||||
gotoTag(t) {
|
gotoTag(t) {
|
||||||
const value = encodeURIComponent(t.id ?? t.name)
|
const value = encodeURIComponent(t.id ?? t.name)
|
||||||
this.$router
|
this.$router
|
||||||
.push({ path: '/', query: { tags: value } })
|
.push({ path: '/', query: { tags: value } })
|
||||||
.then(() => {
|
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
this.handleItemClick()
|
this.handleItemClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,13 +92,9 @@ export default {
|
|||||||
router.push(`/posts/${opt.postId}#comment-${opt.id}`)
|
router.push(`/posts/${opt.postId}#comment-${opt.id}`)
|
||||||
}
|
}
|
||||||
} else if (opt.type === 'category') {
|
} else if (opt.type === 'category') {
|
||||||
router.push({ path: '/', query: { category: opt.id } }).then(() => {
|
router.push({ path: '/', query: { category: opt.id } })
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
} else if (opt.type === 'tag') {
|
} else if (opt.type === 'tag') {
|
||||||
router.push({ path: '/', query: { tags: opt.id } }).then(() => {
|
router.push({ path: '/', query: { tags: opt.id } })
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
selected.value = null
|
selected.value = null
|
||||||
keyword.value = ''
|
keyword.value = ''
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleUserClick(user) {
|
handleUserClick(user) {
|
||||||
this.$router.push(`/users/${user.id}`).then(() => {
|
this.$router.push(`/users/${user.id}`)
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -431,9 +431,7 @@ export default {
|
|||||||
|
|
||||||
const gotoTag = tag => {
|
const gotoTag = tag => {
|
||||||
const value = encodeURIComponent(tag.id ?? tag.name)
|
const value = encodeURIComponent(tag.id ?? tag.name)
|
||||||
router.push({ path: '/', query: { tags: value } }).then(() => {
|
router.push({ path: '/', query: { tags: value } })
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
const width = ref(0)
|
const width = ref(0)
|
||||||
|
const isClient = ref(false)
|
||||||
|
|
||||||
if (process.client) {
|
if (typeof window !== 'undefined') {
|
||||||
|
isClient.value = true
|
||||||
width.value = window.innerWidth
|
width.value = window.innerWidth
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
width.value = window.innerWidth
|
width.value = window.innerWidth
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isMobile = computed(() => width.value <= 768)
|
export const isMobile = computed(() => isClient.value && width.value <= 768)
|
||||||
|
|||||||
Reference in New Issue
Block a user