vue 实现打字机效果

avatar
作者
筋斗云
阅读量:3

打字机效果组件,支持像打字机一样模仿键入文本。支持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, // 记录初始dom       progress: 0, // 当前文本书写进度       // writeStatus: "NotStart",// 当前书写状态=> NotStart: 未开始;Processing:书写中;Completed 书写完毕     };   },   mounted() {     // 拷贝初始所有dom 便于重新开始     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);         // console.log(current);         // 跳过 标签渲染         if (current === "<") {           this.progress = this.initialDom.indexOf(">", this.progress) + 1;         } else {           this.progress++;         }         // console.log(this.progress & 1, "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>  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!