mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-04 19:10:47 +08:00
Merge pull request #430 from nagisa77/codex/add-server-side-rendering-for-index.vue
Enable SSR initial render for home and post pages
This commit is contained in:
@@ -107,7 +107,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, onMounted, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useScrollLoadMore } from '~/utils/loadMore'
|
import { useScrollLoadMore } from '~/utils/loadMore'
|
||||||
import { stripMarkdown } from '~/utils/markdown'
|
import { stripMarkdown } from '~/utils/markdown'
|
||||||
@@ -131,7 +131,7 @@ export default {
|
|||||||
SearchDropdown,
|
SearchDropdown,
|
||||||
ClientOnly: () => import('vue').then(m => m.defineAsyncComponent(() => import('vue').then(() => ({ template: '<slot />' }))))
|
ClientOnly: () => import('vue').then(m => m.defineAsyncComponent(() => import('vue').then(() => ({ template: '<slot />' }))))
|
||||||
},
|
},
|
||||||
setup() {
|
async setup() {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,14 +170,11 @@ export default {
|
|||||||
const allLoaded = ref(false)
|
const allLoaded = ref(false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* -------- 2. CLIENT‑SIDE ONLY: LDRS REGISTER --------
|
* -------- 2. INIT FETCH FOR SSR --------
|
||||||
* 这里使用动态 import 避免 SSR 阶段触发 HTMLElement 未定义错误。
|
* 服务端渲染阶段也需要获取首页内容和选项。
|
||||||
*/
|
*/
|
||||||
onMounted(async () => {
|
await loadOptions()
|
||||||
// 首次加载
|
await fetchContent()
|
||||||
fetchContent()
|
|
||||||
await loadOptions()
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* -------- 3. FETCH OPTION HELPERS --------
|
* -------- 3. FETCH OPTION HELPERS --------
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ import Dropdown from '../components/Dropdown.vue'
|
|||||||
export default {
|
export default {
|
||||||
name: 'PostPageView',
|
name: 'PostPageView',
|
||||||
components: { CommentItem, CommentEditor, BaseTimeline, ArticleTags, ArticleCategory, ReactionsGroup, DropdownMenu, VueEasyLightbox, Dropdown },
|
components: { CommentItem, CommentEditor, BaseTimeline, ArticleTags, ArticleCategory, ReactionsGroup, DropdownMenu, VueEasyLightbox, Dropdown },
|
||||||
setup() {
|
async setup() {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const postId = route.params.id
|
const postId = route.params.id
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -150,27 +150,35 @@ export default {
|
|||||||
const commentSort = ref('NEWEST')
|
const commentSort = ref('NEWEST')
|
||||||
const isFetchingComments = ref(false)
|
const isFetchingComments = ref(false)
|
||||||
|
|
||||||
// record default metadata from the main document
|
// record default metadata from the main document (client only)
|
||||||
const defaultTitle = document.title
|
const defaultTitle = process.client ? document.title : ''
|
||||||
const metaDescriptionEl = document.querySelector('meta[name="description"]')
|
const metaDescriptionEl = process.client
|
||||||
const defaultDescription = metaDescriptionEl ? metaDescriptionEl.getAttribute('content') : ''
|
? document.querySelector('meta[name="description"]')
|
||||||
const headerHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--header-height')) || 0
|
: null
|
||||||
|
const defaultDescription = process.client && metaDescriptionEl
|
||||||
|
? metaDescriptionEl.getAttribute('content')
|
||||||
|
: ''
|
||||||
|
const headerHeight = process.client
|
||||||
|
? parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--header-height')) || 0
|
||||||
|
: 0
|
||||||
|
|
||||||
watch(title, t => {
|
if (process.client) {
|
||||||
document.title = `OpenIsle - ${t}`
|
watch(title, t => {
|
||||||
})
|
document.title = `OpenIsle - ${t}`
|
||||||
|
})
|
||||||
|
|
||||||
watch(postContent, c => {
|
watch(postContent, c => {
|
||||||
if (metaDescriptionEl) {
|
if (metaDescriptionEl) {
|
||||||
metaDescriptionEl.setAttribute('content', stripMarkdownLength(c, 400))
|
metaDescriptionEl.setAttribute('content', stripMarkdownLength(c, 400))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.title = defaultTitle
|
document.title = defaultTitle
|
||||||
if (metaDescriptionEl) metaDescriptionEl.setAttribute('content', defaultDescription)
|
if (metaDescriptionEl) metaDescriptionEl.setAttribute('content', defaultDescription)
|
||||||
window.removeEventListener('scroll', updateCurrentIndex)
|
window.removeEventListener('scroll', updateCurrentIndex)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const lightboxVisible = ref(false)
|
const lightboxVisible = ref(false)
|
||||||
const lightboxIndex = ref(0)
|
const lightboxIndex = ref(0)
|
||||||
@@ -294,7 +302,7 @@ export default {
|
|||||||
})
|
})
|
||||||
isWaitingFetchingPost.value = false;
|
isWaitingFetchingPost.value = false;
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 404) {
|
if (res.status === 404 && process.client) {
|
||||||
router.replace('/404')
|
router.replace('/404')
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -581,10 +589,11 @@ export default {
|
|||||||
router.push(`/users/${author.value.id}`)
|
router.push(`/users/${author.value.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await fetchPost()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const hash = location.hash
|
const hash = location.hash
|
||||||
const id = hash.startsWith('#comment-') ? hash.substring('#comment-'.length) : null
|
const id = hash.startsWith('#comment-') ? hash.substring('#comment-'.length) : null
|
||||||
await fetchPost()
|
|
||||||
if (id) expandCommentPath(id)
|
if (id) expandCommentPath(id)
|
||||||
updateCurrentIndex()
|
updateCurrentIndex()
|
||||||
window.addEventListener('scroll', updateCurrentIndex)
|
window.addEventListener('scroll', updateCurrentIndex)
|
||||||
|
|||||||
Reference in New Issue
Block a user