Component Framework Concepts in Vue vs React
Tags: javascript, webdev, vue, react
Published: 2022-08-16 22:00:26

by [Lawrence Franklin Chukwudalu](https://blog.openreplay.com/authors/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](https://vuejs.org) and [React](https://reactjs.org) 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](https://vuejs.org/guide/components/props.html#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](https://reactjs.org/docs/components-and-props.html) 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](https://vuejs.org/guide/essentials/event-handling.html#event-handling) 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](https://reactjs.org/docs/handling-events.html#gatsby-focus-wrapper) 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](https://vuejs.org/guide/scaling-up/state-management.html) 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](https://reactjs.org/docs/state-and-lifecycle.html) 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](https://github.com/openreplay/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](https://static.openreplay.com/images/banner-blog.png)

_Start enjoying your debugging experience - [start using OpenReplay for free](https://github.com/openreplay/openreplay)._




## 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](https://vuejs.org/guide/essentials/template-refs.html#template-refs) 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](https://reactjs.org/docs/hooks-reference.html#useref), 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](https://vuejs.org/api/built-in-directives.html#v-model) 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](https://dmitripavlutin.com/controlled-inputs-using-react-hooks/) 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](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components) 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](https://vuejs.org/guide/components/slots.html#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](https://blog.openreplay.com/next-js-vs-nuxtjs-a-comparison-of-two-powerhouses) article.

[![newsletter](https://blog.openreplay.com/static/e6b18eda7a327511296a2f27692f9c70/e9957/newsletter.png)](https://newsletter.openreplay.com/)