Typewriter Component for Vue.js
Tags: vue, webdev, beginners, javascript
Published: 2020-03-28 15:19:14

---
title: Typewriter Component for Vue.js
published: true
description: Create a simple typewriter component using Vue.js
tags: vuejs, webdev, beginner, javascript
---

_"A typewriter forces you to keep going, to march forward."_ - James McBride

I'm taking a break this week from writing about writing. Instead, I will demonstrate how to create a Typewriter Component in Vue.js. 

Here's a preview: 
{% codepen https://codepen.io/meditatingdragon/pen/abOReEG default-tab=result %}

### Template
The template is quite simple. To create the typewriter effect, you need an element for static text and an element for changing text. This component contains two `span` tags encapsulated in a `div`. I also tried a variant of a `p` tag encapsulating the `span` tag of the changing text. 

```html
  <div class="pl-10">
    <span class="text-4xl text-black">
      {{ title }}
    </span>
    <span class="text-4xl text-bold text-red-500">
        {{ displayText.join("") }}
    </span>
  </div>
```

### Styles
For simplicity, I've used [Tailwind CSS](https://tailwindcss.com/) for styling. 

### Script

#### Props & Computed Values
This component takes in 4 props: title, speed, deleteSpeed, and words. The `title` prop is the static text. The `speed` prop is the typing speed, and the `deleteSpeed` prop is the delete speed. The `words` prop is an array of changing words. While computed values are not needed in this simple example, I pondered if there might be a use case where certain conditions may require internally changing the values (such as having a super slow delete speed for words that match a certain value).

#### Data
There's only 3 data values - a `displayText` array, which keeps track of which values to display, the `currentWord` being "typed", and the index of the current word from the `words` array.  

#### Methods
##### Start
This begins the typing sequence, setting the `currentWord` and using a `setTimeout` interval for a delay before calling the type function to continue the typing sequence.

##### Type
This method contains all the logic to determine which word is being typed, whether to type or delete, or to change to the next word. Take a look below. 

```js
      // if typing...
      if (this.currentWord.length > 0) {
        this.displayText.push(this.currentWord.shift());
        // if done typing, then delete
      } else if (this.currentWord.length === 0 && 
             this.displayText.length > 0) {
        this.timeoutSpeed = this.DELETE_SPEED;
        this.displayText.pop();
        // if done typing & deleting
      } else if (
        this.currentWord.length === 0 &&
        this.displayText.length === 0
      ) {
        // change words
        if (this.wordIdx < this.words.length) {
          this.currentWord = this.words[this.wordIdx].split("");
          this.wordIdx++;
          this.timeoutSpeed = this.TYPE_SPEED;
          this.displayText.push(this.currentWord.shift());
        } else {
          // reset
          this.wordIdx = 0;
          this.currentWord = this.words[this.wordIdx].split("");
          this.displayText.push(this.currentWord.shift());
        }
      }
      setTimeout(this.type, this.timeoutSpeed);
```

#### Mounted Lifecycle
When the component is mounted, it calls the `start()` method to begin the typing sequence. 

Here's the final Codepen code:

{% codepen https://codepen.io/meditatingdragon/pen/abOReEG default-tab=js %}

And a Github Gist for the Single Page Component:
{% gist https://gist.github.com/meditatingdragon/1b3cc4f74277fa8e2843e8d0268a42e2 %}

Code reviews welcome. Let me know if I can do something better.

**Update [16 Oct 2020]**: Take a look at [Theo's](https://dev.to/theobittencourt) Comment for ways to improve this component! 

{% comment 16kjb %}