Looks like Vue.js will likely out-star React over the weekend!
Tags: vue, react, webdev, showdev
Published: 2018-06-14 21:56:33

---
title: Looks like Vue.js will likely out-star React over the weekend!
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/48kfsgtm1dod9dba01lb.jpg
tags: vue, react, webdev, showdev
---

> original post: https://www.ycmjason.com/blog/2018/06/14.html

It's almost there! It's almost there!!!!

Few weeks ago I published [vue-vs-react](https://github.com/ycmjason/vue-vs-react).

Since the star difference are getting closer and closer (268 stars gap at the moment I am typing this), I decided to add a new feature to my project. Fireworks will explode with a background audio at the moment that Vue out-star React!

You can simply open [the website](https://vue-vs-react.ycmjason.com/) in a tab and when Vue out-star React, you should get notified by the background music!

I am so so so so so excited!

# Things worth mentioning when building this project

## First time using `$refs`

There isn't many cases of obtaining direct reference to the DOM when using Vue. Most stuff could be easily handled with the power of Vue. 

In this project tho, I have an `<audio>` which will be triggered to play when `vue.stars > react.stars`. In order to do so, I must get the reference to the element and do `elem.play()`. The way to get a reference to a DOM in Vue is by adding `ref="name"`. So I just simply did the following (see [this line](https://github.com/ycmjason/vue-vs-react/blob/v0.2.0/src/components/Vs.vue#L3)):

```html
<audio src="..." ref="audio"></audio>
```

Then `this.$refs.audio` will be pointing to that element! Now I could do `this.$refs.audio.play()` and `this.$refs.audio.pause()` inside the component!!!! (see [this line](https://github.com/ycmjason/vue-vs-react/blob/v0.2.0/src/components/Vs.vue#L33))

This make me realise for the first time that `$refs` could be useful when **you want to access the native apis**.

The way that I am currently doing is quite hacky. The proper way would probably look something like:

```html
// Audio.vue
<template>
    <audio :src="src" ref="audio"></audio>
</template>

<script>
export default {
    props: ['playing'],
    watch: {
        playing(p) {
            if (p) this.$refs.audio.play();
            else this.$refs.audio.pause();
            // actually I will write: this.$refs.audio[p? 'play': 'pause']();
        },
    },
}
</script>
```

With this wrapping Audio component, we don't ever need to use `$refs` anywhere else in the codebase! `$refs` are low-level stuff and IMO, we should always wrap it around to lift the level of abstractions of the code.

## Vue can update the DOM really quickly

If you have clicked into the website, you might notice the numbers kind of grow towards the number of stars of the repos. This effect is implemented with this [TransitioningNumber](https://github.com/ycmjason/vue-vs-react/blob/v0.2.0/src/components/TransitioningNumber.vue) component.

The way this component work is that whenever the `porps.number` changes, it [calculates the animation `frames`](https://github.com/ycmjason/vue-vs-react/blob/v0.2.0/src/components/TransitioningNumber.vue#L32). The `frames` is simply a list of numbers ranging from the previous `props.number` to the current `props.number`. Since I have set the `FPS` to 22, the corresponding second per frame would be `1 / 22`. To animate this, we can simply change the `this.displayNumber` from the first frame to the last frame with a timeout of `1 / 22` seconds between each frame. I am surprised how good can Vue handle this and the result looks really satisfying to me.

I will give an example to illustrate the above implementation. Say we want to show transition from `0` to `1000` within `2` seconds. To achieve 22 FPS, we know that we need `22 * 2 = 44` frames. So we will construct a list, `frames`, with 44 frames ranging from from 0 to 1000. It is obvious that each frame would have `step = 1000 / 44 = 22.7272727 ~= 23`. Then we construct the list `frames = [0, 23, 46, 68, ..., 1000]`. Then we set `this.displayNumber` to each frame with a timeout of `1 / 22` seconds between each frame.

**This approach is more of an experiment and does look very naive. I would really appreciate if you could suggest a better approach. Please comment below!**

## Firestore is just awesome

In this project I used [firebase](https://firebase.google.com/), in case you haven't already heard, it is basically a backend-as-a-service, you won't need to care anything about the architecture of the server. It allows you to focus on the application logic.

[Firestore](https://firebase.google.com/products/firestore/) is a real-time database by firebase. It has a powerful API which includes basic CRUD (create, read, update, delete) operations and **subscription to database updates** and more!!!! You don't have to set up your own REST API anymore, just use firestore. You won't ever need to setup the very annoying WebSocket anymore, just use firestore! "Amazing! Just do everything for me please!"

Please refer to these two files ([1](https://github.com/ycmjason/vue-vs-react/blob/v0.2.0/src/services/repoSnapshots.js) and [2](https://github.com/ycmjason/vue-vs-react/blob/v0.2.0/src/App.vue)).

```js
// services/repoSnapshots.js (expanded)
import firebase from 'firebase';

export default {
    subscribe: (fn) => firebase.firestore()
      .collection('repo-snapshots')
      .orderBy("timestamp", "desc")
      .limit(20)
      .onSnapshot(snapshot => fn(snapshot.docs.map(d => d.data()))),
}

// App.vue (<script>)
import repoSnapshots from './services/repoSnapshots.js';

export default {
    ...
    data: () => ({
        snapshots: [],
    }),
    created() {
        repoSnapshots.subscribe(snapshots => this.snapshots = snapshots);
    },
    ...
}
```

As you can see, the code is insanely descriptive and easy. Although the documentation is not very complete, it takes some time to dig our the method I want. It is still very simple to use.

## Parcel is truly awesome

Vue-cli 3.0 is absolutely amazing. But I think [Parcel](https://parceljs.org/) still is the winner for the most 0-config bundler. This project is so easily bootstrapped thanks to the very powerful Parcel! I don't ever need to worry about adding `sass-loader`/`vue-loader` or whatever loader. It just, do it for you! MAGIC!

# Anyways,

I hope you are as excited as I am to see Vue out-starring React and enjoyed reading this post. Please feel free to ask me any questions I would definitely answer if I could. Thanks for reading!