需求:展示日志,将每一行日志文本加上序号标识,展示为类似编辑器代码高亮文本,顶部为文本过滤搜索输入框与刷新日志按钮
实现效果图:
输入框可以输入模糊字符模糊匹配高亮,右侧有个刷新按钮实现日志刷新

思路:
1、基于vue3引入vue-codemirror及相关依赖
vue-codemirror 版本:"vue-codemirror": "^6.1.1",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/search": "^6.5.11",
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.1",
2、引入代码
3、调用插件内部search实例方法实现搜索功能
4、整体代码如下(接口获取根据接口加入调整getLog方法,后端接口直接返回日志就行,codemirror会自动把日志展示为带序号并且格式化展示):
<template>
<div class="log-content">
<div class="top-content">
<a-input-search
v-model="filterValue"
placeholder="请输入搜索内容"
allow-clear
style="width: 200px"
@search="filterLog"
@change="filterLog"
/>
<div class="refresh-btn" @click="refreshLog">
<icon-refresh />
</div>
</div>
<div class="inner-content">
<a-spin
v-if="detailLoading"
class="spin-center"
:size="32"
:tip="'加载中...'"
></a-spin>
<Codemirror
v-show="!detailLoading"
v-model="logContent"
:extensions="extensions"
:style="{ height: '100%' }"
readOnly="nocursor"
:placeholder="'日志内容加载中...'"
@ready="handleReady"
ref="cmEditor"
/>
</div>
</div>
</template>
<script setup>
import { Codemirror } from 'vue-codemirror'
import { javascript } from '@codemirror/lang-javascript'
import { EditorView } from '@codemirror/view'
import { EditorSelection } from '@codemirror/state'
import {SearchQuery, setSearchQuery } from '@codemirror/search'
import { search, highlightSelectionMatches } from '@codemirror/search'
import { ref, watch, onMounted, shallowRef, computed } from 'vue'
import { Message } from '@arco-design/web-vue'
const view = shallowRef()
const handleReady = (payload) => {
view.value = payload.view
}
let myTheme = EditorView.theme(
{
'&': {
height: '100%',
width: '100%',
},
'.cm-content': {
fontSize: '14px',
lineHeight: '1.5',
},
'.cm-selectionMatch': {
backgroundColor: '#ffdd33',
},
},
{ dark: false },
)
const extensions = computed(() => {
return [
javascript(),
myTheme,
highlightSelectionMatches(),
search({
createPanel: () => null, // 禁用默认搜索面板
}),
]
})
const filterValue = ref('')
const detailLoading = ref(false)
const cmEditor = ref(null)
const logContent = ref('')
// 从接口获取渲染的日志
const getLog = () => {
detailLoading.value = true
// 将从接口返回的数据返回logContent渲染日志
let data = 'test'
logContent.value = data || ''
// 滚动到顶部
if (view.value) {
view.value.dispatch({
effects: EditorView.scrollIntoView(0, { y: 'start' }),
})
}
}
// 首次进入调用
getLog()
// 搜索并高亮文本
const filterLog = () => {
if (!view.value) {
Message.warning('编辑器未准备好,请稍后再试')
return
}
const searchValue = filterValue.value.trim()
if (!searchValue) {
// 清空搜索框内容和日志高亮文本样式
filterValue.value = ''
view.value.dispatch({
effects: setSearchQuery.of(new SearchQuery({ search: '' })),
})
view.value.dispatch({
selection: EditorSelection.single(0), // 重置选择到文档开头
})
return
}
// 设置搜索查询
const query = new SearchQuery({
search: searchValue,
caseSensitive: false,
regexp: false,
})
view.value.dispatch({
effects: setSearchQuery.of(query),
})
// 定位到第一个匹配项
const cursor = query.getCursor(view.value.state)
if (cursor.next().done) {
Message.warning('未找到匹配的日志内容')
} else {
view.value.dispatch({
selection: EditorSelection.single(cursor.value.from, cursor.value.to),
effects: EditorView.scrollIntoView(cursor.value.from, { y: 'start' }),
})
}
}
// 刷新日志
const refreshLog = () => {
filterValue.value = '' // 清空过滤条件
logContent.value = ''
getLog()
}
</script>
<style lang="less" scoped>
.log-content {
height: 70vh;
display: flex;
flex-direction: column;
}
.top-content {
display: flex;
justify-content: space-between;
margin-bottom: 17px;
.refresh-btn {
width: 32px;
height: 32px;
line-height: 32px;
font-size: 18px;
text-align: center;
cursor: pointer;
background: #f2f3f5;
border-radius: 2px;
}
}
.inner-content {
border: 1px solid #ebebeb;
flex: 1;
overflow: auto;
min-height: 0;
position: relative;
}
.spin-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
:deep(.arco-spin) {
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
Vue3集成CodeMirror实现日志高亮查询
2687

被折叠的 条评论
为什么被折叠?



