自动编写代码的动效组件
vue
组件代码:
<template>
<div class="code-demo">
<!-- 自动编写代码的动效组件 -->
<div class="header">
<!-- <h2>{{ title }}</h2> -->
<button @click="restart" :disabled="isPrinting"> 重播</button>
</div>
<div ref="codeBox" class="code-box" :style="{ maxHeight: height }">
<pre v-html="highlightedCode"></pre>
</div>
</div>
</template>
<script>
import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import 'highlight.js/styles/monokai-sublime.css'
hljs.registerLanguage('javascript', javascript)
export default {
name: 'AutoCodeWriter',
props: {
code: {
type: String,
default: `
function greet(name) {
return \`Hello, \${name}!\`;
}
const users = ['Alice', 'Bob', 'Charlie'];
users.forEach(user => {
console.log(greet(user));
});
// 🎉 代码生成完毕
`.trim()
},
interval: {
type: Number,
default: 30 // 每字符间隔
},
height: {
type: String,
default: '300px'
},
title: {
type: String,
default: '👨💻 正在写代码...'
}
},
data() {
return {
isPrinting: false,
printedText: '',
highlightedCode: ''
}
},
mounted() {
this.typeCode()
},
methods: {
async typeCode() {
this.printedText = ''
this.highlightedCode = ''
this.isPrinting = true
const chars = this.code.split('')
for (let i = 0; i < chars.length; i++) {
this.printedText += chars[i]
this.highlightedCode = hljs.highlight(this.printedText, { language: 'javascript' }).value
this.$nextTick(this.scrollToBottom)
await this.wait(this.interval)
}
this.isPrinting = false
},
scrollToBottom() {
const box = this.$refs.codeBox
if (box) {
box.scrollTop = box.scrollHeight
}
},
wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
},
restart() {
if (!this.isPrinting) {
this.typeCode()
}
}
}
}
</script>
<style scoped>
.code-demo {
padding: 20px;
background-color: #1e1e1e;
color: #fff;
font-family: 'Courier New', monospace;
border-radius: 12px;
border: 1px solid #444;
}
.code-box {
background-color: #2d2d2d;
overflow-y: auto;
padding: 15px;
border-radius: 8px;
white-space: pre-wrap;
font-size: 14px;
}
button {
background-color: #444;
color: #fff;
border: none;
padding: 6px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background-color: #666;
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
@media (max-width: 600px) {
.code-box {
font-size: 12px;
padding: 10px;
}
.header h2 {
font-size: 16px;
}
}
</style>
用法:
用法示例
<template>
<AutoCodeWriter
:code="myCode"
:interval="20"
height="260px"
title="⚡ 正在生成中..."
/>
</template>
<script>
import AutoCodeWriter from '@/components/AutoCodeWriter.vue'
export default {
components: { AutoCodeWriter },
data() {
return {
myCode: `
const AI = {
name: 'ChatGPT',
speak: () => console.log("Hello, Human!")
}
AI.speak();
`.trim()
}
}
}
</script>