<template>
<div class="typing-container" ref="typingContainer" id="typingContainer">
<v-md-preview :text="displayedText" ref="ppp"></v-md-preview>
</div>
</template>
<script>
export default {
data () {
return {
fullText: `** AIM-9 空空导弹(以AIM-9X Block II为例)的具体参数与部件关系解析
一、基本参数
1. 型号:AIM-9X Block II(最新改进型)
2. **类型**:红外制导短程空对空导弹
3. **长度**:约3米
4. **直径**:127毫米(弹体)
5. **翼展**:430毫米(折叠式尾翼展开后)
6. **重量**:约85千克
7. **射程**:最大约35公里(受发射条件及目标机动性影响)
8. **速度**:超音速(约2.5马赫)
9. **制导方式**:红外成像(IIR,抗干扰能力强)
`,
displayedText: '', // 当前显示的文字
currentIndex: 0, // 当前字符的索引
};
},
mounted () {
this.startTyping(); //typingContainer
},
methods: {
startTyping () {
const container = this.$refs.typingContainer.childNodes[0].childNodes[0];
if (this.currentIndex < this.fullText.length) {
this.displayedText += this.fullText[this.currentIndex]; // 逐个字符添加到 displayedText
this.currentIndex++;
setTimeout(this.startTyping, 100); // 控制打字速度,50ms 显示一个字符
this.$nextTick(() => {
// 移除之前的光标(如果有)
const previousCursor = container.querySelector('.cursorCss');
if (previousCursor) {
previousCursor.remove();
}
const textNode = this.getLastTextNode(container); // 获取最后一个文本节点
const cursor = document.createElement('span')//document.createTextNode('●'); // 光标
cursor.className = 'cursorCss';
if (textNode) {
// 如果找到文本节点,将光标插入到文本节点后面
textNode.parentNode.insertBefore(cursor, textNode.nextSibling);
} else {
// 如果没有找到文本节点,将光标插入到容器末尾
container.appendChild(cursor);
}
});
} else {
// 移除之前的光标(如果有)
const previousCursor = container.querySelector('.cursorCss');
if (previousCursor) {
previousCursor.remove();
}
}
},
getLastTextNode (node) {
if (!node) {
return null;
}
// 如果当前节点是文本节点,直接返回
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== '') {
return node;
}
// 遍历子节点,从最后一个开始
for (let i = node.childNodes.length - 1; i >= 0; i--) {
const childNode = node.childNodes[i];
// 递归查找子节点中的最后一个文本节点
const textNode = this.getLastTextNode(childNode);
if (textNode) {
return textNode;
}
}
// 如果没有找到文本节点,返回 null
return null;
}
},
};
</script>
<style lang="scss">
.cursorCss {
color: blue;
font-size: 26px;
padding-top: 10px;
padding-left: 10px;
position: relative;
&::after {
content: '';
display: inline-block;
width: 10px;
height: 10px;
background-color: rgb(73, 73, 165);
border-radius: 50%;
animation: blink 1s infinite;
}
}
</style>
其中v-md-preview是解析MD的插件,可以在main.js中引用以下代码
npm i @kangc/v-md-editor -S
import VMdPreviewfrom '@kangc/v-md-editor';
import '@kangc/v-md-editor/lib/style/base-editor.css';
import githubTheme from '@kangc/v-md-editor/lib/theme/github.js';
import '@kangc/v-md-editor/lib/theme/style/github.css';
VMdPreview.use(githubTheme);
app.use(VMdPreview)