mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-02 01:50:46 +08:00
refactor: extract comment editor component
This commit is contained in:
95
open-isle-cli/src/components/CommentEditor.vue
Normal file
95
open-isle-cli/src/components/CommentEditor.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="comment-editor-container">
|
||||
<div :id="editorId" ref="vditorElement"></div>
|
||||
<div class="comment-bottom-container">
|
||||
<div class="comment-submit" @click="submit">发布评论</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import Vditor from 'vditor'
|
||||
import 'vditor/dist/index.css'
|
||||
|
||||
export default {
|
||||
name: 'CommentEditor',
|
||||
emits: ['submit'],
|
||||
props: {
|
||||
editorId: {
|
||||
type: String,
|
||||
default: () => 'editor-' + Math.random().toString(36).slice(2)
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const vditorInstance = ref(null)
|
||||
|
||||
const submit = () => {
|
||||
if (!vditorInstance.value) return
|
||||
const text = vditorInstance.value.getValue()
|
||||
if (!text.trim()) return
|
||||
emit('submit', text)
|
||||
vditorInstance.value.setValue('')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
vditorInstance.value = new Vditor(props.editorId, {
|
||||
placeholder: '说点什么...',
|
||||
height: 120,
|
||||
theme: 'classic',
|
||||
preview: {
|
||||
theme: { current: 'light' },
|
||||
actions: [],
|
||||
markdown: { toc: false }
|
||||
},
|
||||
toolbar: [
|
||||
'emoji',
|
||||
'bold',
|
||||
'italic',
|
||||
'strike',
|
||||
'|',
|
||||
'list',
|
||||
'line',
|
||||
'quote',
|
||||
'code',
|
||||
'inline-code',
|
||||
'|',
|
||||
'undo',
|
||||
'redo',
|
||||
'|',
|
||||
'link',
|
||||
'image'
|
||||
],
|
||||
toolbarConfig: { pin: true }
|
||||
})
|
||||
})
|
||||
|
||||
return { submit }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.comment-editor-container {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 50px;
|
||||
border: 1px solid #e2e2e2;
|
||||
}
|
||||
.comment-bottom-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
padding: 10px;
|
||||
}
|
||||
.comment-submit {
|
||||
background-color: var(--primary-color);
|
||||
color: #fff;
|
||||
padding: 10px 20px;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.comment-submit:hover {
|
||||
background-color: var(--primary-color-hover);
|
||||
}
|
||||
</style>
|
||||
@@ -29,9 +29,9 @@
|
||||
<div class="reactions-count">1882</div>
|
||||
</div>
|
||||
<div class="make-reaction-container">
|
||||
<div class="make-reaction-item comment-reaction">
|
||||
<i class="far fa-comment"></i>
|
||||
</div>
|
||||
<div class="make-reaction-item comment-reaction" @click="toggleEditor">
|
||||
<i class="far fa-comment"></i>
|
||||
</div>
|
||||
<div class="make-reaction-item like-reaction">
|
||||
<i class="far fa-heart"></i>
|
||||
</div>
|
||||
@@ -41,6 +41,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CommentEditor v-if="showEditor" @submit="submitReply" />
|
||||
<div v-if="comment.reply && comment.reply.length" class="reply-toggle" @click="toggleReplies">
|
||||
{{ comment.reply.length }}条回复
|
||||
</div>
|
||||
@@ -58,6 +59,7 @@
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue'
|
||||
import CommentEditor from './CommentEditor.vue'
|
||||
const CommentItem = {
|
||||
name: 'CommentItem',
|
||||
props: {
|
||||
@@ -70,15 +72,32 @@ const CommentItem = {
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
setup(props) {
|
||||
const showReplies = ref(false)
|
||||
const showEditor = ref(false)
|
||||
const toggleReplies = () => {
|
||||
showReplies.value = !showReplies.value
|
||||
}
|
||||
return { showReplies, toggleReplies }
|
||||
const toggleEditor = () => {
|
||||
showEditor.value = !showEditor.value
|
||||
}
|
||||
const submitReply = (text) => {
|
||||
if (!text.trim()) return
|
||||
const replyList = props.comment.reply || (props.comment.reply = [])
|
||||
replyList.push({
|
||||
id: Date.now(),
|
||||
userName: '你',
|
||||
time: new Date().toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' }),
|
||||
avatar: 'https://picsum.photos/200/200',
|
||||
text,
|
||||
reply: []
|
||||
})
|
||||
showEditor.value = false
|
||||
}
|
||||
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply }
|
||||
}
|
||||
}
|
||||
CommentItem.components = { CommentItem }
|
||||
CommentItem.components = { CommentItem, CommentEditor }
|
||||
export default CommentItem
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user