Categories
React Vue

React vs Vue — Components and Props Basics

React is the most popular front end library for the last few years.

Vue is a front end framework that’s catching up in popularity with React in the last few years.

It’s hard to choose between the 2 frameworks since they both their pros and cons. When we choose one, we’ve to stick with it for a few years.

In this article, we’ll compare how we can create React and Vue components, handle props and which one is more convenient for developers.

Creating Components

With React, we create components by creating a function, with the props passed in the props parameter.

For example, we can create a component and pass a prop into it by writing the following code:

import React from "react";

function Foo({ msg }) {
  return <div>{msg}</div>;
}

export default function App() {
  return (
    <div className="App">
      <Foo msg="hello" />
    </div>
  );
}

In the code above, we created a Foo component with a msg prop that’s passed from App to Foo . Then we accessed the msg property of the prop parameter in the Foo component and displayed msg there.

With Vue, the way we define components and use them is similar to the React example.

We can create a Vue component and pass a prop into it as follows:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <Foo msg="hello"></Foo>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

Vue.component("Foo", {
  props: ["msg"],
  template: "<div>{{msg}}</div>"
});

const app = new Vue({
  el: "#app",
  data: {}
});

In the code above, we created a Foo component with Vue.component , and then designate the msg attribute as a prop.

Then in index.html , we reference Foo and pass in the msg prop as we did with the React example.

As we can see, this simple example is pretty comparable between React and Vue.

Passing Data From Child to Parent

React and Vue both have the capability to pass data from child to parent.

With React, we can pass a function to a child component that takes some arguments.

The child calls the function so that the parent can get the data.

We can do what we described with React as follows:

import React, { useState } from "react";

function FooInput({ setMsg }) {
  return <input onChange={e => setMsg(e.target.value)} />;
}

export default function App() {
  const [msg, setMsg] = useState();
  return (
    <div className="App">
      <FooInput setMsg={setMsg} />
      <br />
      <span>{msg}</span>
    </div>
  );
}

In the code above, we passed in the setMsg function returned from the useState hook to our FooInput component.

Then FooInput calls the setMsg function which we passed in from the props with the value of the input.

This will then set the inputted value as the value of msg .

Finally, we display the value of msg in the span.

With Vue, we don’t have to pass in the parent’s functions directly into the child component.

Instead, we can emit an event with the value that we want to send to the parent. Then the parent can do whatever they want with the value.

We can do the same thing in our React example with Vue as follows:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <foo-input v-bind:value="msg" v-on:input="msg = $event"></foo-input>
      <br />
      <span>{{msg}}</span>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

Vue.component("foo-input", {
  props: ["value"],
  data() {
    return {
      msg: ""
    };
  },
  watch: {
    value(val) {
      this.msg = val;
    }
  },
  template: `<input v-model="msg" @input="$emit('input', $event.target.value)">`
});

const app = new Vue({
  el: "#app",
  data: {
    msg: ""
  }
});

In the code above, we have the foo-input conponent, which takes a value prop, which we set the latest value to this.msg with the watcher so we aren’t mutating the value prop directly.

Then we call $emit with the input event name and the entered value, which is stored in $event.target.value .

The value entered is then sent to the parent and is available in the $event object.

We listen to the event set the value to the msg field by writing:

v-on:input="msg = $event"

as a directive on the foo-input component.

We then display the value of msg in the span below the foo-input component.

Once we did all that, we should see what we typed in displayed below the input.

A shorthand for:

v-bind:value="msg" v-on:input="msg = $event"

is:

v-model='msg'

This is a special case and doesn’t apply to app emitted events.

So we can instead write:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <foo-input v-model="msg"></foo-input>
      <br />
      <span>{{msg}}</span>
    </div>
    <script src="index.js"></script>
  </body>
</html>

In any case, the React example is simpler. Passing data from child and parent components is definitely easier to React than Vue.

Verdict

The process for creating components and passing props from parent and child are pretty much the same when comparing React and Vue.

React does make passing data from child to parent easier than with Vue. We just pass in a function into the child and call it from there instead of emitting events and listening to them.

Categories
React Vue

React vs Vue — Event Handling

React is the most popular front end library for the last few years.

Vue is a front end framework that’s catching up in popularity with React in the last few years.

It’s hard to choose between the 2 frameworks since they both their pros and cons. When we choose one, we’ve to stick with it for a few years.

In this article, we’ll look at how we write event handling code with React and Vue and which one is more convenient.

Basic Event Handling

With React, we bind our event handlers straight into the JSX components.

For example, we can write the following code to do handle clicks with React:

import React, { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);
  const increment = () => {
    setCount(count + 1);
  };

  return (
    <div className="App">
      <button onClick={increment}>Increment</button>
      <div>{count}</div>
    </div>
  );
}

In the code above, we added the increment click handler and we pass that into the onClick prop so that when we click the Increment button, we’ll see the count value increase.

With Vue, we can write the following to do the same thing:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click="increment">Increment</button>
      <div>{{count}}</div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    count: 0
  },
  methods: {
    increment() {
      this.count++;
    }
  }
});

In the code above, we have the increment handler as we did with the React example.

However, updating values is easier since we update the count directly instead of calling a function returned from the useState hook to update the count.

Passing in the click handler is pretty much done the same way, except that we have to remember to use the @click directive.

Handling clicks is pretty much the same in either case.

Modifying Event Handling Behavior

Vue has event modifiers to modify the behavior of how event handlers handle events.

We can put them after the event handling directive. For example, if we want to prevent the default submit behavior in a form, we write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <form v-on:submit.prevent="onSubmit">
        <input v-model="name" />
      </form>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    name: ""
  },
  methods: {
    onSubmit() {
      alert(this.name);
    }
  }
});

to add a form with a submit handler that doesn’t do the default submit behavior.

The .prevent modifier is a handy shortcut for calling e.preventDefault in our submit handler.

With React, we have to call preventDefault() .

The equivalent example in React would be:

import React, { useState } from "react";

export default function App() {
  const [name, setName] = useState("");
  const onSubmit = e => {
    e.preventDefault();
    alert(name);
  };

  return (
    <div className="App">
      <form onSubmit={onSubmit}>
        <input onChange={e => setName(e.target.value)} />
      </form>
    </div>
  );
}

The Vue version is slightly shorter, but it’s not too much different.

Photo by Jens Johnsson on Unsplash

Handling Key Presses

With Vue, we can handle keypresses with our event handlers with the v-on directive’s modifiers as we did with clicks.

For example, if we want to display an alert when we control-click on a div, we can write:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <div v-on:click.ctrl="help">Help</div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {},
  methods: {
    help() {
      alert("help");
    }
  }
});

In the code above, we have:

v-on:click.ctrl="help"

to run the help method when we control-click on the div.

With React, we have to use plain JavaScript to do this:

import React from "react";

export default function App() {
  const onClick = e => {
    e.stopPropagation();
    if (e.ctrlKey) {
      alert("help");
    }
  };

  return (
    <div className="App">
      <div onClick={onClick}>Help</div>
    </div>
  );
}

In the code above, we have an onClick handler that first stops the propagation of the events to its parent.

Then we check if the ctrlKey is pressed with the click.

Then we display the alert if e.ctrlKey is true , which means the control key is pressed.

This is definitely more complex with React. If we want to handle even more complex keyboard and mouse press combinations, this gets even harder.

Verdict

Event handling is better with Vue since it has modifiers to modify the behavior of event handling directives.

This is especially true when we need to handle more complex interactions like keyboard and mouse combinations.

There’s no easy way to do that with React.

Categories
React Vue

React vs Vue — Watching for Data

React is the most popular front end library for the last few years.

Vue is a front end framework that’s catching up in popularity with React in the last few years.

It’s hard to choose between the 2 frameworks since they both their pros and cons. When we choose one, we’ve to stick with it for a few years.

In this article, we’ll look at how we handle data with React and Vue and which one does a better job.

Computed Properties

Computed properties are data that are derived from another piece of data.

Vue has computed properties, which we can derive from existing data.

For example, we add the computed property to a Vue component as follows to add a computed property:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click="randomMsg">Random Msg</button>
      <div>{{msg}}</div>
      <div>{{reverseMsg}}</div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    msg: "Hello world"
  },
  computed: {
    reverseMsg() {
      return this.msg
        .split("")
        .reverse()
        .join("");
    }
  },
  methods: {
    randomMsg() {
      const msgs = ["Hello world", "Hello Jane"];
      this.msg = msgs[Math.floor(Math.random() * msgs.length)];
    }
  }
});

In the code above, we have the randomMsg method which sets the message randomly.

The reverseMsg property will then be automatically computed according to what we return.

By default, computed properties are getter only, so it’s impossible for us to accidentally change a Vue computed property.

Then we can display them both on our template as we did above.

This is efficient for both developers and on computing resources since computed properties are only updated when the original data changed and developers only have to define one piece of code and use it everywhere.

With React, there’s no direct way to do the same thing. We have to use the useEffect hook to do the same thing by watching the original value that we want to create the computed property from.

Then we call the function returned from useState to make the change.

We do this as follows:

import React, { useState, useEffect } from "react";

export default function App() {
  const [msg, setMsg] = useState("Hello world");
  const [reverseMsg, setReverseMsg] = useState("");

  const randomMsg = () => {
    const msgs = ["Hello world", "Hello Jane"];
    setMsg(msgs[Math.floor(Math.random() * msgs.length)]);
  };

  useEffect(() => {
    setReverseMsg(
      msg
        .split("")
        .reverse()
        .join("")
    );
  }, [msg]);

  return (
    <div className="App">
      <button onClick={randomMsg}>Random Msg</button>
      <div>{msg}</div>
      <div>{reverseMsg}</div>
    </div>
  );
}

As we can see, this is more complex than the computed property solution that’s provided with Vue.

We have to watch the value of msg explicitly with the useEffect hook and then call setReverseMsg to set the value of it by reversing the string as we did with the Vue example.

The array [msg] tells React to watch for changes in value for msg .

We also have the randonMsg function to set the value of msg as we did with the Vue example.

Vue’s logic is definitely cleaner with computed properties. Also, we can do anything inside the useEffect hook callback, so we have to be careful not to accidentally change data that we don’t want to change.

Photo by John Torcasio on Unsplash

Watched Property

We can also watch for property changes with Vue. With React, we use the useEffect above as we did above to do that.

The equivalent of that with Vue os the watch property. We can use that as follows:

const app = new Vue({
  el: "#app",
  data: {
    msg: "Hello world",
    reverseMsg: ""
  },
  watch: {
    msg(val) {
      this.reverseMsg = val
        .split("")
        .reverse()
        .join("");
    }
  },
  methods: {
    randomMsg() {
      const msgs = ["Hello world", "Hello Jane"];
      this.msg = msgs[Math.floor(Math.random() * msgs.length)];
    }
  }
});

The code above watches for changes in the msg field. Then we can react to it by taking the val parameter, which has the current value of msg .

Then we reverse the string as we did before.

Vue is more flexible in that it provides both options.

Verdict

Computed properties is definitely a great feature that comes with Vue. This isn’t available to React.

The closest equivalent to Vue computed properties with React is the useEffect hook, where we can do anything.

Vue computed properties are getter-only by default so we can’t accidentally change computed properties unless we add a setter to it.

If we want to be more flexible, Vue also has watchers that do something equivalent to useEffect callbacks.

Therefore, Vue wins when it comes to creating derived properties.

Categories
React Vue

React vs Vue — App Creation and Display

React is the most popular front end library for the last few years.

Vue is a front end framework that’s catching up in popularity with React in the last few years.

It’s hard to choose between the 2 frameworks since they both their pros and cons. When we choose one, we’ve to stick with it for a few years.

In this article, we’ll look compare the most basic features of these 2 frameworks, which are creating the app and displaying data.

Creating the App

React has the Create React App command-line program which lets us create a scaffold of the app with JavaScript or TypeScript.

It has built-in support for building a progressive web app.

Create React App can run tests that are in the __tests__ folder.

Vue has the Vue CLI to create an app with a JavaScript or TypeScript, plus we can incorporate CSS, SASS, Less, etc. for styling. We can also add testing infrastructure right into our scaffold by changing the options that are shown in the Vue CLI.

We can also add Vue Router and Vuex from Vue CLI.

It also has support for building a progressive web app.

Vue CLI has a GUI for creating quick projects to prototype apps.

In addition to using CLI programs, we can use the script tag to add React and Vue to our app.

However, most React libraries are only available as NPM packages. Whereas many Vue libraries can be added via a script tag.

This means that Vue is more suitable for enhancing legacy apps since they often don’t have front ends that are built with modern frameworks and build tools.

It also makes Vue a better choice for quick prototyping since we can just add libraries via script tags and use them without thinking about build tools and scaffolding.

Template Syntax

Most React apps use JSX to display data on the screen. It’s a shortcut for calling the React.createElement method.

Vue templates have their own syntax. For example, we use double curly braces to display variables on the screen.

For example, we can write the following to display a variable’s value in a React app:

import React, { useState } from "react";

export default function App() {
  const [foo] = useState("foo");
  return <div className="App">{foo}</div>;
}

Whereas we write the following to display a variable’s value in a Vue app:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      {{foo}}
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    foo: "foo"
  }
});

In the code above, we display the value of the foo property in data in the template by writing:

{{foo}}

The React way is slightly simpler in that we put everything in the same component function.

On the other hand, we added what we want to display with Vue in a separate template.

In both cases, we have some new syntax to learn.

Conditionally Display Data

In React apps, we display items conditionally with normal if or switch statements in the render method of class components or returning JSX in function components.

The logic to toggle them on and off is all in the component file itself.

For example, we can write the following to toggle something on and off in a React app:

import React, { useState } from "react";

export default function App() {
  const [show, setShow] = useState();
  const toggleShow = () => {
    setShow(!show);
  };

  return (
    <div className="App">
      <button onClick={toggleShow}>Toggle</button>
      {show && <div>foo</div>}
    </div>
  );
}

In the code above, we added a Toggle button, and then the show state with the setShow function toggle the show state between true and false .

Then we show the div conditionally with:

{show && <div>foo</div>}

With Vue, we display items on the template and use v-if to control it.

For example, we can write the following code to do that:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click="toggle">Toggle</button>
      <div v-if="show">foo</div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    show: false
  },
  methods: {
    toggle() {
      this.show = !this.show;
    }
  }
});

In the code above, we made the toggle method to toggle this.show on and off.

Then we added a Toggle button to call toggle and display it conditionally with the v-if directive.

As we can see, the React implementation is simpler than the Vue implementation.

We also have to understand the parts of a Vue component like when are components methods calls and where are states stored.

With the useState React hook, this is more obvious. We also don’t have to add things to templates and components to add something.

We can add everything to one file with React components. This is more convenient for simple components.

However, Vue’s approach is more convenient for separating logic from the display code.

This is a cleaner approach for organizing a component when things are more complex.

Verdict

Vue is more of a full-fledged framework, as opposed to React, which is more of a library.

The Vue CLI has many more options for creating an app with the options required for creating an app.

Create React App only has options for creating a basic app that doesn’t have routing or any state management solution.

This isn’t ideal since most people want a single-page app rather than enhancing a legacy app.

Also, Vue libraries are available as script tags, whereas most React libraries are only available as Node packages.

Vue is the clear winner with the Vue CLI with its options.

Displaying data are similar to both React and Vue. They both require some logic and display items and conditionally display items on the screen.

They both have their own workflows, but Vue’s design has cleaner separation between logic and templates, whereas React puts everything in one place.

Categories
React Vue

React vs Vue — Handling Selections

React is the most popular front end library for the last few years. Vue is a front end framework that’s catching up quickly.

It’s hard to choose between the 2 frameworks since they both have their pros and cons.

In this article, we’ll compare how React and Vue frameworks handle form radio button and drop-down selections and which one is easier for developers.

Radio Buttons

With Vue, we can use the v-model directive to bind the radio button choices to the component’s model directly.

For example, with Vue, we write the following to add a set of radio buttons and display the selected choice on the screen:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <input type="radio" value="One" v-model="picked" />
      <label>One</label>
      <br />
      <input type="radio" value="Two" v-model="picked" />
      <label>Two</label>
      <br />
      <span>Picked: {{ picked }}</span>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    picked: ""
  }
});

In the code above, we just set the value of v-model of both radio buttons to the same picked model.

Then when we click either radio button, we’ll see the selected choice show in the span.

With React, we have to add the checked prop to each radio button so that only the value that’s selected is checked.

For instance, we write the following to rewrite the example above with React:

import React, { useState } from "react";

export default function App() {
  const [picked, setPicked] = useState("");
  const handleClick = e => setPicked(e.target.value);

  return (
    <div className="App">
      <input
        type="radio"
        value="One"
        checked={picked === "One"}
        onClick={handleClick}
      />
      <label>One</label>
      <br />
      <input
        type="radio"
        value="Two"
        checked={picked === "Two"}
        onClick={handleClick}
      />
      <label>Two</label>
      <br />
      <span>Picked: {picked}</span>
    </div>
  );
}

In the code above, we have the same 2 radio buttons as in the Vue example, but we added a onClick handler to set the picked state, and we also have the checked attribute to indicate when they should be checked.

We indicate that we only want them selected when the given value is picked.

This is extra work that we don’t have to with Vue.

Handling Drop-Down Selections

We can use v-model to bind directly to the selected value of the dropdown with Vue.

Therefore, we can write the following to create a drop-down and then display the selected choice:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <select v-model="picked">
        <option>One</option>
        <option>Two</option>
      </select>
      <br />
      <span>Picked: {{ picked }}</span>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    picked: ""
  }
});

In the code above, we created a dropdown and then bind the selected value to the picked model in the Vue component.

Then we referenced picked to display the selected choice in the span.

We didn’t have to specify the value if the value and the displayed text are the same.

With React, we write the following code to handle setting the selected value from a dropdown:

import React, { useState } from "react";

export default function App() {
  const [picked, setPicked] = useState("");

  return (
    <div className="App">
      <select onChange={e => setPicked(e.target.value)}>
        <option>One</option>
        <option>Two</option>
      </select>
      <br />
      <span>Picked: {picked}</span>
    </div>
  );
}

To handle change in the value of a dropdown, we pass in an event handler to set the selected value to the picked state.

Then we display it in the span below the dropdown.

The Vue and React examples are pretty close with respect to handling dropdowns.

Multiple Selections

With Vue, it’s easy to handle the values of select elements that let users select multiple values.

We can write the following code to do that:

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <select v-model="picked" multiple>
        <option>One</option>
        <option>Two</option>
        <option>Three</option>
      </select>
      <br />
      <span>Picked: {{ picked }}</span>
    </div>
    <script src="index.js"></script>
  </body>
</html>

index.js :

const app = new Vue({
  el: "#app",
  data: {
    picked: []
  }
});

In the code above, we have a select element with the multiple attribute to enable multiple selection.

Then we just bind to the picked array with v-model and reference the picked array straight in the template to display the selected choices.

With React, we have to write the following to get the selected choices and display them:

import React, { useState } from "react";

export default function App() {
  const [picked, setPicked] = useState([]);

  return (
    <div className="App">
      <select
        multiple
        onChange={e =>
          setPicked([...e.target.selectedOptions].map(o => o.value))
        }
      >
        <option>One</option>
        <option>Two</option>
        <option>Three</option>
      </select>
      <br />
      <span>Picked: {picked.join(", ")}</span>
    </div>
  );
}

In the code, we reference:

[...e.target.selectedOptions].map(o => o.value)

to get the selected options from the select element and then get the value property of each entry and put them in the picked array.

Then we display the picked entries by call join to combine the choices into one string.

As we can see, we have to do lots of things that we didn’t have to do in the Vue example to get equivalent functionality.

There’s way more logic involved just to get the selections from a select element that lets the user choose multiple choices.

Also, we have to spread the e.target.selectedOptions object so that we convert it to an array. e.target.selectedOptions is an array-like object, which isn’t an array.

Verdict

Vue is definitely better with handling radio buttons and select elements that let us choose multiple choices.

The v-model directive took care of most of the hard work of extracting the selected choices and displaying the data.

With React, we have to write our own code to extract the selected choices and display them also takes some work.