打字机效果组件,支持像打字机一样模仿键入文本。支持vue 插值语法和表格等打印
ps: 灵感来着于vue-type-writer 但是 这个组件过于简单 就自己整了一个
一、预览
二、代码
组件:
<template>
<div :style="{ visibility: visibility }">
<slot></slot>
</div>
</template>
<script>
export default {
name: "vue-text-dot",
props: {
interval: { type: Number, default: 75 },
cursorStr: {
type: String,
default: "",
},
},
data() {
return {
visibility: "hidden",
timer: 0,
initialDom: null,
progress: 0,
};
},
mounted() {
this.initialDom = JSON.parse(JSON.stringify(this.$el.innerHTML));
},
methods: {
start() {
this.visibility = "visible";
this.progress = 0;
this.$el.innerHTML = "";
clearInterval(this.timer);
this.write();
this.$emit("writeStart");
},
pause() {
clearInterval(this.timer);
this.$emit("writePause");
},
continueWrite() {
if(!this.progress || this.progress >= this.initialDom.length){
return
}
clearInterval(this.timer);
this.write();
this.$emit("writeContinue");
},
reset() {
this.visibility = "hidden";
this.progress = 0;
this.$el.innerHTML = "";
clearInterval(this.timer);
},
write() {
this.timer = setInterval(() => {
var current = this.initialDom.substr(this.progress, 1);
if (current === "<") {
this.progress = this.initialDom.indexOf(">", this.progress) + 1;
} else {
this.progress++;
}
if (this.cursorStr) {
this.$el.innerHTML =
this.initialDom.substring(0, this.progress) +
(this.progress < this.initialDom.length && this.progress & 1
? this.cursorStr
: "");
} else {
this.$el.innerHTML = this.initialDom.substring(0, this.progress);
}
if (this.progress >= this.initialDom.length) {
clearInterval(this.timer);
this.$emit("writeEnd");
}
}, this.interval);
},
},
beforeDestroy() {
clearInterval(this.timer);
},
};
</script>
父级组件引用
<template>
<div class="app-container home">
<div class="body">
<button type="primary" @click="start">开始 / 重新开始</button>
<button type="primary" @click="pause">暂停</button>
<button type="primary" @click="continueWrite">继续</button>
<button type="primary" @click="reset">重置</button>
<VueTypewriter
class="tl"
ref="typewriter"
:interval="50"
cursorStr=""
@writeEnd="writeEnd"
>
<div class="comments">
<p>const array = [1, 2, 2, 3, 4, 4, 5];</p>
<p>const uniqueArray = Array.from(new Set(array));</p>
<p>console.log(uniqueArray);</p>
<p>{{ message }}</p>
</div>
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>0</td>
</tr>
</table>
</VueTypewriter>
</div>
</div>
</template>
<script>
import VueTypewriter from "./vue-typewriter";
export default {
name: "Demo",
components: { VueTypewriter },
data() {
return {
message: "测试插值表达式 是否能够正常渲染",
};
},
methods: {
start() {
this.$refs.typewriter.start();
},
pause() {
this.$refs.typewriter.pause();
},
continueWrite() {
this.$refs.typewriter.continueWrite();
},
reset() {
this.$refs.typewriter.reset();
},
writeEnd() {
console.log("end");
},
},
};
</script>
<style scoped lang="scss">
.home {
text-align: left;
.body {
width: 890px;
height: 500px;
padding: 20px;
border: #b2c92a solid 10px;
button {
margin-right: 20px;
padding: 8px 20px;
}
.comments {
p {
font-size: 18px;
color: green;
}
}
table {
margin: 20px 0;
border-collapse: collapse;
td {
padding: 10px 20px;
border: 1px solid #ccc;
}
}
}
}
</style>