打字机效果组件,支持像打字机一样模仿键入文本。支持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>