Component Framework Concepts in Vue vs React

Component Framework Concepts in Vue vs React

by Lawrence Franklin Chukwudalu

Component frameworks are tools for building applications such that the UI and logic are segmented into separate reusable components. Today's component frameworks include React, Vue, Angular, Ember, Svelte, etc.

Vue and React make use of common framework concepts such as handling states, props, refs, lifecycle hooks, events, etc. These two frameworks are widely used in web development today. They use nearly similar patterns for building UI in the form of reusable components, but in this blog post you will learn about component framework concepts and how they are done in Vue compared to how they are done in React.

Installation and Setup

Let's start by comparing the installation process of both frameworks.

Vue

To install Vue CLI (command line interface), the following command is used:

npm install -g @vue/cli

To check the version, run the following command in your terminal.

vue --version

To create a new project, run the following command.

vue create project_name
cd project_name
npm run serve

React

To install React, run the following command on your terminal:

npm install -g create-react-app

To create a new project, run the following command.

npx create-react-app project_name
cd project_name
npm run start

Props

Component frameworks use props to pass data from parent to child components, a crucial technique for both.

Vue

In Vue, props are passed as strings using quotations or variables using the v-bind directive, which can also be written as just a : character.

Passing props to child component

// passing props from to Modal component
<template>
  <Modal :isOpen="pageLoaded" title="Survey Form" />
</template>

Accessing props in child component

// Modal Component
<template>
  <form v-if="isOpen">
    <p>{{ title }} </p>
    <!-- ...other form elements -->
  </form>
</template>

<script setup>
  const props = defineProps({
    isOpen: Boolean,
    title: String
  });
</script>

React

In React, props are passed as strings also using quotes or as variables using curly braces like so:

Passing props

<div>
  <Modal isOpen={pageLoaded} title="Survey Form" />
</div>

Accessing props

function Modal({isOpen, title}) {
  return (
    {isOpen &&
     <form>
        <p>{ title }</p>
        // ...other form elements
      </form>
  );
}

Events

Components can listen to specific events such as mouse events (e.g., click, mouseover, etc.) and keyboard events (e.g., keydown, keyup, etc.) Event handling is also a necessity in both frameworks.

Vue

In Vue, events are created using the v-on directive, which can also be written as @ like so

<template>
    <button @click="displayName"> Show Name </button>
<template>

<script setup>
    function displayName() {
        alert('Lawrence Franklin');
    }
</script>

React

In React, events are created using the typical JavaScript inline event methods such as onClick, onKeyDown, onKeyUp, etc.

function NameAlert() {
    const displayName = () => {
        alert('Lawrence Franklin');
    }

    return (
        <button onClick="displayName"> Show Name </button>
    );
}

State

Component frameworks use states to manage reactivity within components. States are updated in real-time across components. Handling the global state across a website is a critical issue.

Vue

In Vue, states can be created using the ref() or reactive() method, which does the same thing except ref are accessed using the .value property while reactive are used directly (they're already unwrapped). These methods help to creative reactivity within components.

<template>
  <div>
    <p>{{ firstname }}</p>
    <p>{{ lastname }}</p>
  </div>
</template>

<script setup>
  import { ref, reactive } from 'vue';

  const firstname = ref('Franklin');
  console.log(firstname.value);

  const lastname = reactive('Lawrence');
  console.log(lastname);
</script>

Reactive values can be watched using watch() and watchEffect() methods. These methods tracks changes in reactive values and runs a callback function every time those value changes. The only difference between these methods is that watchEffect() runs once initially and then starts watching for changes.

import { watch, watchEffect } from 'vue';

// watch
watch( firstname, () => alert('firstname changed!');

// watchEffect
watchEffect(lastname, () => alert('lastname changed');

React

React uses the useState() hook to track state changes in a component and create side effects.

import { useState } from 'react';

function ShowName() {
  const [firstName, setFirstName] = useState('Franklin');
  const [lastName, setLastName] = useState('Lawrence');

  console.log(firstName, lastName);

  return (
    <div>
      <p>{ firstname }</p>
      <p>{ lastname }</p>
    </div>
  )
}

To listen for state changes, React uses the useEffect() hook. This hook accepts a callback function and an array of dependencies, and it fires the callback function whenever the values of those dependencies change. Dependencies could be of any data type. Here's an example:

import { useEffect } from 'React';

useEffect(() => {
  console.log('name updated!');
}, [firstName, lastName]);

Open Source Session Replay

OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.

replayer.png

Start enjoying your debugging experience - start using OpenReplay for free.

Refs

Sometimes you need to work directly with DOM elements for things like adding some animations, setting an input field to focus or blur, etc. To do this, most component frameworks provide you with a reference functionality (Vue and React make use of ref), which can be used to reference a DOM element.

Vue

In Vue, template ref written with the ref keyword is used on the DOM element and accessed like so:

<template>
  <input type="text" ref="name" />
</template>

<script setup>
  import { ref } from 'vue';

  const name = ref(null);

  handleBtnClick(() => {
    name.value.focus();
  }
</script>

React

In React, refs are used a bit differently. They reference DOM elements using the ref keyword and the useRef() hook, which are then accessed using the .current property like so:

 import { useRef } from 'react';

function MyName() {
  const name = useRef(null);

  handleBtnClick(() => {
    name.current.focus();
  });

  return (
    <input type="text" ref="name" />
    <button onClick={handleBtnClick}> Start typing </button>
  )
}

Two-way Data Binding

Data can be (and are usually) bound in "two-way", which means that the data can be updated in two ways. This is used with form input fields such as input element, select element,textarea element, checkbox element, etc. The input value can be changed via the element and also via code in such a way that they are in sync, i.e., change in one way (e.g., in code) updates the value in the other instance (e.g., in input field).

Vue

Vue uses the v-model directive to create a two-way binding like so:

<template>
  <input v-model="searchQuery" />
</template>

<script setup>
import { ref } from 'vue';

const searchQuery = ref('');
// searchQuery.value can be updated here, and it reflects in the input field instantly
</script>

React

React uses something called controlled inputs to bind data two-way like so:

import { useState } from 'react';

function MyComponent() {
  [searchQuery, setSearchQuery] = useState('');

  const handleChange = (event) => {
     setSearchQuery(event.target.value);
  }

  return (
    <input value={searchQuery} onChange={handleChange}/>
  );
}

Dynamic Rendering

Sometimes, components are rendered based on certain conditions. In order words, components can be dynamically rendered depending on the outcome of a specified condition.

Vue

Vue uses the v-if, v-else and v-show directives to render a component dynamically based on a specified condition. The example below illustrates this concept:

<template>
  <div>
    <p v-if="isLoggedIn"> Welcome </p>
    <p v-else> Please Login </p>
    <button v-show="!isLoggedIn">Login</button>
  </div>
</template>

React

React leverages JavaScript's conditionals such as if, &&, or ternary operator to dynamically render a component. Here's an example to illustrate this:

function MyComponent() {
  return (
    {isLoggedIn ? 
     <p>Welcome</p> :
     <p> Please Login </p>
    }
    {!isLoggedIn && <button> Login </button>}
  );
}

Passing Children

Sometimes you want to pass children elements to other components, not just props. Component frameworks like Vue and React provide a means for you to achieve this.

Vue

Vue makes use of slots to pass children elements. Here's an example of how you can use them:

Modal Component, this is the component that receives children elements

// Modal.vue

<template>
  <div>
    <h1>Welcome</h1>
    <slot><slot>
  </div>
</template>

UserPage Component, this is the parent component that passes the children elements

// UserPage.vue

<template>
  <div>
    <h1>Survey Form</h1>
    <Modal>
        <p>Kindly fill out this survey...</p>
        <input type="text" />
        <button>Submit</button>
    </Modal>
  </div>
</template>

React

React provides you with the children prop value similar to slots from Vue to pass children elements. Here's an example:

Modal Component, this is the component that receives children elements

function Modal( {children} ) {
  return (
    <div>
       <h1>Welcome</h1>
       { children }
    </div>
  );
}

UserPage Component, this is the parent component that passes the children elements

 function UserPage() {
  return (
     <div>
      <h1>Survey Form</h1>
      <Modal>
        <p>Kindly fill out this survey...</p>
        <input type="text" />
        <button>Submit</button>
      </Modal>
    </div>
  );
}

Conclusion

At this point, you've learned most concepts used in component frameworks, such as states, props, components, events, etc. You have also learned how these concepts can be implemented in Vue vs. React. Seeing that these concepts are commonly used across component frameworks, it is relatively easy to transition from one framework to another once you get familiar with how these concepts work.

A TIP FROM THE EDITOR: For another comparison involving React and Vue, check out our Next.js vs NuxtJS: a comparison of two powerhouses article.

newsletter