style: 调整

This commit is contained in:
rd
2025-08-21 16:47:34 +08:00
parent cb9b0715b1
commit ba4878c333
3 changed files with 45 additions and 35 deletions

View File

@ -10,7 +10,7 @@ import type { BubbleProps, BubbleContentType, SlotInfoType } from './types';
export default defineComponent({
name: 'Bubble',
inheritAttrs: false,
props: {} as any,
props: {},
setup(_, { attrs, slots, expose }) {
const props = attrs as unknown as BubbleProps<BubbleContentType> & { style?: any; class?: any };
@ -18,7 +18,7 @@ export default defineComponent({
watch(
() => props.content,
(val) => {
content.value = val as any;
content.value = val;
},
{ immediate: true },
);
@ -27,13 +27,7 @@ export default defineComponent({
const [typingEnabled, typingStep, typingInterval, typingSuffix] = useTypingConfig(() => props.typing);
const abortRef = ref(false);
const [typedContent, isTyping] = useTypedEffect(
content as any,
typingEnabled,
typingStep,
typingInterval,
abortRef,
);
const [typedContent, isTyping] = useTypedEffect(content, typingEnabled, typingStep, typingInterval, abortRef);
// 提供中止打字的能力关闭typing并立即展示完整内容
const abortTyping = () => {
@ -73,10 +67,8 @@ export default defineComponent({
});
const mergedContent = computed(() => {
if (slots.message) return slots.message({ content: typedContent.value as any }) as any;
return props.messageRender
? (props.messageRender(typedContent.value as any) as any)
: (typedContent.value as any);
if (slots.message) return slots.message({ content: typedContent.value });
return props.messageRender ? props.messageRender(typedContent.value) : typedContent.value;
});
const contentNode = computed(() => {
@ -89,7 +81,7 @@ export default defineComponent({
return (
<>
{mergedContent.value as any}
{mergedContent.value}
{isTyping.value && unref(typingSuffix)}
</>
);
@ -97,16 +89,16 @@ export default defineComponent({
const renderHeader = () => {
const info: SlotInfoType = { key: props._key };
if (slots.header) return slots.header({ content: typedContent.value as any, info, item: props }) as any;
if (slots.header) return slots.header({ content: typedContent.value, info, item: props });
const h = props.header;
return typeof h === 'function' ? h({ content: typedContent.value as any, info, item: props }) : h;
return typeof h === 'function' ? h({ content: typedContent.value, info, item: props }) : h;
};
const renderFooter = () => {
const info: SlotInfoType = { key: props._key };
if (slots.footer) return slots.footer({ content: typedContent.value as any, info, item: props }) as any;
if (slots.footer) return slots.footer({ content: typedContent.value, info, item: props });
const f = props.footer;
return typeof f === 'function' ? f({ content: typedContent.value as any, info, item: props }) : f;
return typeof f === 'function' ? f({ content: typedContent.value, info, item: props }) : f;
};
expose({
@ -117,7 +109,7 @@ export default defineComponent({
<div class={mergedCls.value} style={{ ...(props.style || {}) }}>
{(slots.avatar || props.avatar) && (
<div class={[`${prefixCls}-avatar`, props.classNames?.avatar]} style={props.styles?.avatar}>
{avatarNode.value as any}
{avatarNode.value}
</div>
)}
@ -135,7 +127,7 @@ export default defineComponent({
{renderHeader()}
</div>
) : null}
{contentNode.value as any}
{contentNode.value}
{renderFooter() ? (
<div class={[`${prefixCls}-footer`, props.classNames?.footer]} style={props.styles?.footer}>
{renderFooter()}

View File

@ -23,14 +23,14 @@ import {
export default defineComponent({
name: 'BubbleList',
inheritAttrs: false,
props: {} as any,
props: {},
setup(_, { attrs, slots, expose }) {
const props = attrs as unknown as BubbleListProps & { class?: any; style?: any };
const passThroughAttrs = useAttrs();
const TOLERANCE = 1;
const domProps = computed(() => pickAttrs(mergeProps(props as any, passThroughAttrs)) as any);
const domProps = computed(() => pickAttrs(mergeProps(props as any, passThroughAttrs)));
const items = ref(props.items);
const roles = ref(props.roles as RolesType);
@ -108,7 +108,7 @@ export default defineComponent({
};
// 对外暴露能力
expose({
nativeElement: listRef as any,
nativeElement: listRef,
abortTypingByKey,
scrollTo: (info: any) => {
unref(listRef)?.scrollTo?.(info);
@ -125,20 +125,18 @@ export default defineComponent({
props.class,
{ [`${listPrefixCls}-reach-end`]: unref(scrollReachEnd) },
]}
style={props.style as any}
style={props.style}
ref={listRef}
onScroll={onInternalScroll}
>
{unref(displayData).map(({ key, onTypingComplete: onTypingCompleteBubble, ...bubble }: any) => (
{unref(displayData).map(({ key, onTypingComplete: onTypingCompleteBubble, ...bubble }) => (
<Bubble
{...bubble}
avatar={slots.avatar ? () => slots.avatar?.({ item: { key, ...bubble } }) : (bubble as any).avatar}
header={slots.header?.({ item: { key, ...bubble } }) ?? (bubble as any).header}
footer={slots.footer?.({ item: { key, ...bubble } }) ?? (bubble as any).footer}
loadingRender={
slots.loading ? () => slots.loading({ item: { key, ...bubble } }) : (bubble as any).loadingRender
}
content={slots.message?.({ item: { key, ...bubble } }) ?? (bubble as any).content}
avatar={slots.avatar ? () => slots.avatar?.({ item: { key, ...bubble } }) : bubble.avatar}
header={slots.header?.({ item: { key, ...bubble } }) ?? bubble.header}
footer={slots.footer?.({ item: { key, ...bubble } }) ?? bubble.footer}
loadingRender={slots.loading ? () => slots.loading({ item: { key, ...bubble } }) : bubble.loadingRender}
content={slots.message?.({ item: { key, ...bubble } }) ?? bubble.content}
key={key}
ref={(node: any) => {
if (node) {
@ -147,7 +145,7 @@ export default defineComponent({
delete bubbleRefs.value[key];
}
}}
typing={unref(initialized) ? (bubble as any).typing : false}
typing={unref(initialized) ? bubble.typing : false}
onTypingComplete={() => {
onTypingCompleteBubble?.();
onTypingComplete(key);

View File

@ -4,6 +4,7 @@ import { Bubble } from '@/components/xt-chat/xt-bubble';
import { downloadByUrl } from '@/utils/tools';
import markdownit from 'markdown-it';
import { message } from 'ant-design-vue';
export default {
emits: ['close'],
@ -29,6 +30,13 @@ export default {
const onDownload = () => {
// downloadByUrl('');
message.success('下载成功!');
};
const onAddMediaCenter = () => {
message.success('成功添加至“素材中心”模块。');
};
const onAddTaskManage = () => {
message.success('成功添加至“任务管理”模块。');
};
const abortTyping = () => {
bubbleRef.value?.abortTyping?.();
@ -36,10 +44,22 @@ export default {
const renderHeader = () => {
return (
<header class="header flex justify-end items-center mb-16px px-32px">
<Button type="outline" size="medium" class="mr-16px" v-slots={{ icon: () => <icon-plus size="14" /> }}>
<Button
type="outline"
size="medium"
class="mr-16px"
v-slots={{ icon: () => <icon-plus size="14" /> }}
onClick={onAddMediaCenter}
>
素材中心
</Button>
<Button type="outline" size="medium" class="mr-16px" v-slots={{ icon: () => <icon-plus size="14" /> }}>
<Button
type="outline"
size="medium"
class="mr-16px"
v-slots={{ icon: () => <icon-plus size="14" /> }}
onClick={onAddTaskManage}
>
任务管理
</Button>
<Button