Categories
React Vue

React vs Vue — Components and Props Basics

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *