Add image preview with vue-easy-lightbox

This commit is contained in:
Tim
2025-07-14 19:54:24 +08:00
parent fbe63b3943
commit 5625868c91
4 changed files with 67 additions and 9 deletions

View File

@@ -21,7 +21,7 @@
</DropdownMenu>
</div>
</div>
<div class="info-content-text" v-html="renderMarkdown(comment.text)"></div>
<div class="info-content-text" v-html="renderMarkdown(comment.text)" @click="handleImageClick"></div>
<div class="article-footer-container">
<ReactionsGroup v-model="comment.reactions" content-type="comment" :content-id="comment.id">
<div class="make-reaction-item comment-reaction" @click="toggleEditor">
@@ -53,12 +53,19 @@
:default-show-replies="r.openReplies"
/> -->
</div>
<vue-easy-lightbox
:visible="lightboxVisible"
:imgs="lightboxImgs"
:index="lightboxIndex"
@hide="lightboxVisible = false"
/>
</div>
</div>
</template>
<script>
import { ref, watch, computed } from 'vue'
import VueEasyLightbox from 'vue-easy-lightbox'
import { useRouter } from 'vue-router'
import CommentEditor from './CommentEditor.vue'
import { renderMarkdown } from '../utils/markdown'
@@ -96,6 +103,9 @@ const CommentItem = {
)
const showEditor = ref(false)
const isWaitingForReply = ref(false)
const lightboxVisible = ref(false)
const lightboxIndex = ref(0)
const lightboxImgs = ref([])
const toggleReplies = () => {
showReplies.value = !showReplies.value
}
@@ -182,11 +192,20 @@ const CommentItem = {
toast.success('已复制')
})
}
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply, copyCommentLink, renderMarkdown, isWaitingForReply, commentMenuItems, deleteComment }
const handleImageClick = e => {
if (e.target.tagName === 'IMG') {
const container = e.target.parentNode
const imgs = [...container.querySelectorAll('img')].map(i => i.src)
lightboxImgs.value = imgs
lightboxIndex.value = imgs.indexOf(e.target.src)
lightboxVisible.value = true
}
}
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply, copyCommentLink, renderMarkdown, isWaitingForReply, commentMenuItems, deleteComment, lightboxVisible, lightboxIndex, lightboxImgs, handleImageClick }
}
}
CommentItem.components = { CommentItem, CommentEditor, BaseTimeline, ReactionsGroup, DropdownMenu }
CommentItem.components = { CommentItem, CommentEditor, BaseTimeline, ReactionsGroup, DropdownMenu, VueEasyLightbox }
export default CommentItem
</script>

View File

@@ -47,7 +47,7 @@
<div class="user-name">{{ author.username }}</div>
<div class="post-time">{{ postTime }}</div>
</div>
<div class="info-content-text" v-html="renderMarkdown(postContent)"></div>
<div class="info-content-text" v-html="renderMarkdown(postContent)" @click="handleImageClick"></div>
<div class="article-footer-container">
<ReactionsGroup v-model="postReactions" content-type="post" :content-id="postId">
@@ -98,11 +98,18 @@
<div v-else class="scroller-time">{{ lastReplyTime }}</div>
</div>
</div>
<vue-easy-lightbox
:visible="lightboxVisible"
:index="lightboxIndex"
:imgs="lightboxImgs"
@hide="lightboxVisible = false"
/>
</div>
</template>
<script>
import { ref, computed, onMounted, nextTick, watch } from 'vue'
import VueEasyLightbox from 'vue-easy-lightbox'
import { useRoute } from 'vue-router'
import CommentItem from '../components/CommentItem.vue'
import CommentEditor from '../components/CommentEditor.vue'
@@ -122,7 +129,7 @@ hatch.register()
export default {
name: 'PostPageView',
components: { CommentItem, CommentEditor, BaseTimeline, ArticleTags, ArticleCategory, ReactionsGroup, DropdownMenu, LoginOverlay },
components: { CommentItem, CommentEditor, BaseTimeline, ArticleTags, ArticleCategory, ReactionsGroup, DropdownMenu, LoginOverlay, VueEasyLightbox },
setup() {
const route = useRoute()
const postId = route.params.id
@@ -143,6 +150,10 @@ export default {
const mainContainer = ref(null)
const currentIndex = ref(1)
const subscribed = ref(false)
const lightboxVisible = ref(false)
const lightboxIndex = ref(0)
const lightboxImgs = ref([])
const loggedIn = computed(() => authState.loggedIn)
const isAdmin = computed(() => authState.role === 'ADMIN')
const isAuthor = computed(() => authState.username === author.value.username)
@@ -231,6 +242,16 @@ export default {
return false
}
const handleImageClick = e => {
if (e.target.tagName === 'IMG') {
const container = e.target.parentNode
const imgs = [...container.querySelectorAll('img')].map(i => i.src)
lightboxImgs.value = imgs
lightboxIndex.value = imgs.indexOf(e.target.src)
lightboxVisible.value = true
}
}
const onCommentDeleted = (id) => {
removeCommentFromList(Number(id), comments.value)
}
@@ -491,7 +512,11 @@ export default {
approvePost,
onCommentDeleted,
deletePost,
rejectPost
rejectPost,
lightboxVisible,
lightboxIndex,
lightboxImgs,
handleImageClick
}
}
}