Comment 评论
对网站内容的反馈、评价和讨论。
何时使用
评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。
代码演示
一个基本的评论组件,带有作者、头像、时间和操作。
<template>
<a-comment>
<template #actions>
<span key="comment-basic-like">
<a-tooltip title="Like">
<template v-if="action === 'liked'">
<LikeFilled @click="like" />
</template>
<template v-else>
<LikeOutlined @click="like" />
</template>
</a-tooltip>
<span style="padding-left: 8px; cursor: auto">
{{ likes }}
</span>
</span>
<span key="comment-basic-dislike">
<a-tooltip title="Dislike">
<template v-if="action === 'disliked'">
<DislikeFilled @click="dislike" />
</template>
<template v-else>
<DislikeOutlined @click="dislike" />
</template>
</a-tooltip>
<span style="padding-left: 8px; cursor: auto">
{{ dislikes }}
</span>
</span>
<span key="comment-basic-reply-to">Reply to</span>
</template>
<template #author><a>Han Solo</a></template>
<template #avatar>
<a-avatar
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
alt="Han Solo"
/>
</template>
<template #content>
<p>
We supply a series of design principles, practical patterns and high quality design
resources (Sketch and Axure), to help people create their product prototypes beautifully and
efficiently.
</p>
</template>
<template #datetime>
<a-tooltip :title="moment().format('YYYY-MM-DD HH:mm:ss')">
<span>{{ moment().fromNow() }}</span>
</a-tooltip>
</template>
</a-comment>
</template>
<script lang="ts">
import moment from 'moment';
import { LikeFilled, LikeOutlined, DislikeFilled, DislikeOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref } from 'vue';
export default defineComponent({
components: {
LikeFilled,
LikeOutlined,
DislikeFilled,
DislikeOutlined,
},
setup() {
const likes = ref<number>(0);
const dislikes = ref<number>(0);
const action = ref<string>();
const like = () => {
likes.value = 1;
dislikes.value = 0;
action.value = 'liked';
};
const dislike = () => {
likes.value = 0;
dislikes.value = 1;
action.value = 'disliked';
};
return {
likes,
dislikes,
action,
like,
dislike,
moment,
};
},
});
</script>
评论可以嵌套。
<template>
<a-comment>
<template #actions>
<span key="comment-nested-reply-to">Reply to</span>
</template>
<template #author>
<a>Han Solo</a>
</template>
<template #avatar>
<a-avatar
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
alt="Han Solo"
/>
</template>
<template #content>
<p>
We supply a series of design principles, practical patterns and high quality design
resources (Sketch and Axure).
</p>
</template>
<a-comment>
<template #actions>
<span>Reply to</span>
</template>
<template #author>
<a>Han Solo</a>
</template>
<template #avatar>
<a-avatar
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
alt="Han Solo"
/>
</template>
<template #content>
<p>
We supply a series of design principles, practical patterns and high quality design
resources (Sketch and Axure).
</p>
</template>
<a-comment>
<template #actions>
<span>Reply to</span>
</template>
<template #author>
<a>Han Solo</a>
</template>
<template #avatar>
<a-avatar
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
alt="Han Solo"
/>
</template>
<template #content>
<p>
We supply a series of design principles, practical patterns and high quality design
resources (Sketch and Axure).
</p>
</template>
</a-comment>
<a-comment>
<template #actions>
<span>Reply to</span>
</template>
<template #author>
<a>Han Solo</a>
</template>
<template #avatar>
<a-avatar
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
alt="Han Solo"
/>
</template>
<template #content>
<p>
We supply a series of design principles, practical patterns and high quality design
resources (Sketch and Axure).
</p>
</template>
</a-comment>
</a-comment>
</a-comment>
</template>
配合 List 组件展现评论列表。
<template>
<a-list
class="comment-list"
:header="`${data.length} replies`"
item-layout="horizontal"
:data-source="data"
>
<template #renderItem="{ item }">
<a-list-item>
<a-comment :author="item.author" :avatar="item.avatar">
<template #actions>
<span v-for="(action, index) in item.actions" :key="index">{{ action }}</span>
</template>
<template #content>
<p>
{{ item.content }}
</p>
</template>
<template #datetime>
<a-tooltip :title="item.datetime.format('YYYY-MM-DD HH:mm:ss')">
<span>{{ item.datetime.fromNow() }}</span>
</a-tooltip>
</template>
</a-comment>
</a-list-item>
</template>
</a-list>
</template>
<script lang="ts">
import moment from 'moment';
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
return {
data: [
{
actions: ['Reply to'],
author: 'Han Solo',
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
content:
'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
datetime: moment().subtract(1, 'days'),
},
{
actions: ['Reply to'],
author: 'Han Solo',
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
content:
'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
datetime: moment().subtract(2, 'days'),
},
],
moment,
};
},
});
</script>
评论编辑器组件提供了相同样式的封装以支持自定义评论编辑器。
<template>
<a-list
v-if="comments.length"
:data-source="comments"
:header="`${comments.length} ${comments.length > 1 ? 'replies' : 'reply'}`"
item-layout="horizontal"
>
<template #renderItem="{ item }">
<a-list-item>
<a-comment
:author="item.author"
:avatar="item.avatar"
:content="item.content"
:datetime="item.datetime"
/>
</a-list-item>
</template>
</a-list>
<a-comment>
<template #avatar>
<a-avatar
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
alt="Han Solo"
/>
</template>
<template #content>
<a-form-item>
<a-textarea :rows="4" v-model:value="value" />
</a-form-item>
<a-form-item>
<a-button html-type="submit" :loading="submitting" type="primary" @click="handleSubmit">
Add Comment
</a-button>
</a-form-item>
</template>
</a-comment>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import moment from 'moment';
type Comment = Record<string, string>;
export default defineComponent({
setup() {
const comments = ref<Comment[]>([]);
const submitting = ref<boolean>(false);
const value = ref<string>('');
const handleSubmit = () => {
if (!value.value) {
return;
}
submitting.value = true;
setTimeout(() => {
submitting.value = false;
comments.value = [
{
author: 'Han Solo',
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
content: value.value,
datetime: moment().fromNow(),
},
...comments.value,
];
value.value = '';
}, 1000);
};
return {
comments,
submitting,
value,
handleSubmit,
};
},
});
</script>
API
Property | Description | Type | Default |
---|---|---|---|
actions | 在评论内容下面呈现的操作项列表 | Array|slot | - |
author | 要显示为注释作者的元素 | string|slot | - |
avatar | 要显示为评论头像的元素 - 通常是 antd Avatar 或者 src | string|slot | - |
content | 评论的主要内容 | string|slot | - |
datetime | 展示时间描述 | string|slot | - |