Skip to content

Commit b123f0f

Browse files
authored
perf: 优化文档分段前端懒加载 (#406)
1 parent cf4ce7e commit b123f0f

File tree

2 files changed

+106
-106
lines changed

2 files changed

+106
-106
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<template>
2+
<div>
3+
<InfiniteScroll
4+
:size="paragraph_list.length"
5+
:total="modelValue.length"
6+
:page_size="page_size"
7+
v-model:current_page="current_page"
8+
@load="next()"
9+
:loading="loading"
10+
>
11+
<el-card
12+
v-for="(child, cIndex) in paragraph_list"
13+
:key="cIndex"
14+
shadow="never"
15+
class="card-never mb-16"
16+
>
17+
<div class="flex-between">
18+
<span>{{ child.title || '-' }}</span>
19+
<div>
20+
<!-- 编辑分段按钮 -->
21+
<el-button link @click="editHandle(child, cIndex)">
22+
<el-icon><EditPen /></el-icon>
23+
</el-button>
24+
<!-- 删除分段按钮 -->
25+
<el-button link @click="deleteHandle(child, cIndex)">
26+
<el-icon><Delete /></el-icon>
27+
</el-button>
28+
</div>
29+
</div>
30+
<div class="lighter mt-12">
31+
{{ child.content }}
32+
</div>
33+
<div class="lighter mt-12">
34+
<el-text type="info"> {{ child.content.length }} 个字符 </el-text>
35+
</div>
36+
</el-card>
37+
</InfiniteScroll>
38+
39+
<EditParagraphDialog
40+
ref="EditParagraphDialogRef"
41+
@updateContent="updateContent"
42+
:isConnect="isConnect"
43+
/>
44+
</div>
45+
</template>
46+
<script setup lang="ts">
47+
import { cloneDeep } from 'lodash'
48+
import { defineProps, ref, computed } from 'vue'
49+
import EditParagraphDialog from './EditParagraphDialog.vue'
50+
import { MsgConfirm } from '@/utils/message'
51+
const page_size = ref<number>(20)
52+
const current_page = ref<number>(1)
53+
const currentCIndex = ref<number>(0)
54+
const EditParagraphDialogRef = ref()
55+
const emit = defineEmits(['update:modelValue'])
56+
const loading = ref<boolean>(false)
57+
const editHandle = (item: any, cIndex: number) => {
58+
currentCIndex.value = cIndex
59+
EditParagraphDialogRef.value.open(item)
60+
}
61+
62+
const props = defineProps<{ modelValue: Array<any>; isConnect: boolean }>()
63+
64+
const paragraph_list = computed(() => {
65+
return props.modelValue.slice(0, page_size.value * (current_page.value - 1) + page_size.value)
66+
})
67+
68+
const next = () => {
69+
loading.value = true
70+
current_page.value += 1
71+
loading.value = false
72+
}
73+
74+
const updateContent = (data: any) => {
75+
const new_value = [...props.modelValue]
76+
new_value[currentCIndex.value] = cloneDeep(data)
77+
emit('update:modelValue', new_value)
78+
}
79+
80+
const deleteHandle = (item: any, cIndex: number) => {
81+
MsgConfirm(`是否删除分段:${item.title || '-'} ?`, `删除后将不会存入知识库,对本地文档无影响。`, {
82+
confirmButtonText: '删除',
83+
confirmButtonClass: 'danger'
84+
})
85+
.then(() => {
86+
const new_value = [...props.modelValue]
87+
new_value.splice(cIndex, 1)
88+
emit('update:modelValue', new_value)
89+
})
90+
.catch(() => {})
91+
}
92+
</script>
93+
<style lang="scss" scoped></style>
Lines changed: 13 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<el-tabs v-model="activeName" class="paragraph-tabs" @tab-click="handleClick">
2+
<el-tabs v-model="activeName" class="paragraph-tabs">
33
<template v-for="(item, index) in newData" :key="index">
44
<el-tab-pane :label="item.name" :name="index">
55
<template #label>
@@ -8,55 +8,22 @@
88
<span class="ml-4">{{ item?.name }}</span>
99
</div>
1010
</template>
11-
<el-scrollbar ref="scrollRef" :key="index">
12-
<div class="mb-16">
13-
<el-text type="info">{{ item.content.length }} 段落</el-text>
14-
</div>
15-
<div class="paragraph-list" v-infinite-scroll="loadScroll">
16-
<el-card
17-
v-for="(child, cIndex) in scrollData"
18-
:key="cIndex"
19-
shadow="never"
20-
class="card-never mb-16"
21-
>
22-
<div class="flex-between">
23-
<span>{{ child.title || '-' }}</span>
24-
<div>
25-
<!-- 编辑分段按钮 -->
26-
<el-button link @click="editHandle(child, index, cIndex)">
27-
<el-icon><EditPen /></el-icon>
28-
</el-button>
29-
<!-- 删除分段按钮 -->
30-
<el-button link @click="deleteHandle(child, index, cIndex)">
31-
<el-icon><Delete /></el-icon>
32-
</el-button>
33-
</div>
34-
</div>
35-
<div class="lighter mt-12">
36-
{{ child.content }}
37-
</div>
38-
<div class="lighter mt-12">
39-
<el-text type="info"> {{ child.content.length }} 个字符 </el-text>
40-
</div>
41-
</el-card>
42-
</div>
43-
</el-scrollbar>
11+
<div class="mb-16">
12+
<el-text type="info">{{ item.content.length }} 段落</el-text>
13+
</div>
14+
<div class="paragraph-list" v-if="activeName == index">
15+
<el-scrollbar>
16+
<ParagraphList v-model="item.content" :isConnect="isConnect"> </ParagraphList>
17+
</el-scrollbar>
18+
</div>
4419
</el-tab-pane>
4520
</template>
4621
</el-tabs>
47-
<EditParagraphDialog
48-
ref="EditParagraphDialogRef"
49-
@updateContent="updateContent"
50-
:isConnect="isConnect"
51-
/>
5222
</template>
5323
<script setup lang="ts">
54-
import { ref, reactive, onMounted, watch, nextTick } from 'vue'
55-
import { cloneDeep } from 'lodash'
56-
import type { TabsPaneContext } from 'element-plus'
57-
import EditParagraphDialog from './EditParagraphDialog.vue'
58-
import { filesize, getImgUrl } from '@/utils/utils'
59-
import { MsgConfirm } from '@/utils/message'
24+
import { ref, onMounted, watch } from 'vue'
25+
import { getImgUrl } from '@/utils/utils'
26+
import ParagraphList from './ParagraphList.vue'
6027
6128
const props = defineProps({
6229
data: {
@@ -68,80 +35,20 @@ const props = defineProps({
6835
6936
const emit = defineEmits(['update:data'])
7037
71-
const EditParagraphDialogRef = ref()
72-
const scrollRef = ref()
73-
7438
const activeName = ref(0)
75-
const currentPIndex = ref(null) as any
76-
const currentCIndex = ref(null) as any
7739
7840
const newData = ref<any[]>([])
7941
80-
// 滚动加载数据
81-
const paginationConfig = reactive({
82-
current_page: 1,
83-
page_size: 20
84-
})
85-
86-
const scrollData = ref<any[]>([])
87-
8842
watch(
8943
() => props.data,
9044
(value) => {
9145
newData.value = value
92-
paginationConfig.current_page = 1
93-
nextTick(() => {
94-
scrollRef.value?.[activeName.value]?.scrollTo(0, 0)
95-
})
96-
scrollData.value = newData.value[activeName.value]?.content.slice(0, paginationConfig.page_size)
9746
},
9847
{
9948
immediate: true
10049
}
10150
)
10251
103-
function loadScroll() {
104-
if (newData.value[activeName.value]?.content.length > scrollData.value.length) {
105-
paginationConfig.current_page += 1
106-
scrollData.value.push(
107-
...newData.value[activeName.value].content.slice(
108-
(paginationConfig.current_page - 1) * paginationConfig.page_size,
109-
paginationConfig.current_page * paginationConfig.page_size
110-
)
111-
)
112-
}
113-
}
114-
115-
function editHandle(item: any, index: number, cIndex: number) {
116-
currentPIndex.value = index
117-
currentCIndex.value = cIndex
118-
EditParagraphDialogRef.value.open(item)
119-
}
120-
121-
function deleteHandle(item: any, index: number, cIndex: number) {
122-
MsgConfirm(`是否删除分段:${item.title || '-'} ?`, `删除后将不会存入知识库,对本地文档无影响。`, {
123-
confirmButtonText: '删除',
124-
confirmButtonClass: 'danger'
125-
})
126-
.then(() => {
127-
newData.value[index].content.splice(cIndex, 1)
128-
scrollData.value.splice(cIndex, 1)
129-
emit('update:data', newData.value)
130-
})
131-
.catch(() => {})
132-
}
133-
134-
function updateContent(data: any) {
135-
newData.value[currentPIndex.value].content[currentCIndex.value] = cloneDeep(data)
136-
scrollData.value[currentCIndex.value] = cloneDeep(data)
137-
emit('update:data', newData.value)
138-
}
139-
140-
const handleClick = (tab: TabsPaneContext, event: Event) => {
141-
paginationConfig.current_page = 1
142-
scrollData.value = newData.value[Number(tab.index)]?.content.slice(0, paginationConfig.page_size)
143-
}
144-
14552
onMounted(() => {})
14653
</script>
14754
<style scoped lang="scss">
@@ -172,6 +79,6 @@ onMounted(() => {})
17279
}
17380
}
17481
.paragraph-list {
175-
height: calc(var(--create-dataset-height) - 131px);
82+
height: calc(var(--create-dataset-height) - 101px);
17683
}
17784
</style>

0 commit comments

Comments
 (0)