Comparison between React, Vue 2, and Vue 3:
Demo
Component
React
Function component:
function Component() {
return <p>Hello, component!</p>;
}
Class component:
class Component extends React.Component {
render() {
return <p>Hello, component!</p>;
}
}
Vue 2
Vue.component('vue-component', {
template: '<p>Hello, component!</p>',
});
It’s not named
'component'
because Vue does not like the use of built-in or reserved HTML elements as the component id.
Vue 3
Vue.createApp({}).component('vue-component', {
template: '<p>Hello, component!</p>',
});
Event
React
Handling event for function component:
function Event() {
function handleClick() {
alert();
}
return <button onClick={handleClick}>Click Event</button>;
}
Handling event for class component:
class Event extends React.Component {
handleClick() {
alert();
}
render() {
return <button onClick={this.handleClick}>Click Event</button>;
}
}
Vue 2
Vue.component('event', {
template: '<button @click="handleClick">Click Event</button>',
methods: {
handleClick: () => {
alert();
},
},
});
The
@
symbol is the shortened form of thev-on
directive.
Vue 3
Vue.createApp({}).component('event', {
template: '<button @click="handleClick">Click Event</button>',
methods: {
handleClick: () => {
alert();
},
},
});
Prop
React
Function component props:
function Prop(props) {
return <p>Hello, {props.name}!</p>;
}
Prop.defaultProps = {
name: 'prop',
};
Class component props:
class Prop extends React.Component {
static defaultProps = {
name: 'prop',
};
render() {
return <p>Hello, {this.props.name}!</p>;
}
}
Passing props:
<Prop name="prop" />
Vue 2
Component with data:
Vue.component('prop', {
data() {
return {
name: 'prop',
};
},
template: '<p>Hello, {{ name }}!</p>',
});
Component with props:
// prop.js
Vue.component('prop', {
props: ['name'],
template: '<p>Hello, {{ name }}!</p>',
});
<!-- prop.html -->
<prop name="prop"></prop>
Vue 3
Component with data:
Vue.createApp({}).component('prop', {
data() {
return {
name: 'prop',
};
},
template: '<p>Hello, {{ name }}!</p>',
});
Component with props:
// prop.js
Vue.createApp({}).component('prop', {
props: ['name'],
template: '<p>Hello, {{ name }}!</p>',
});
<!-- prop.html -->
<prop name="prop"></prop>
App with data and component with props:
// prop.js
const App = {
data() {
return {
name: 'prop',
};
},
};
const app = Vue.createApp(App);
app.component('prop', {
props: ['name'],
template: '<p>Hello, {{ name }}!</p>',
});
app.mount('#app');
<!-- prop.html -->
<div id="app">
<prop :name="name"></prop>
</div>
State
React
Function component using state hook:
function State() {
const [count, setCount] = React.useState(0);
function handleClick() {
setCount(count + 1);
}
return <button onClick={handleClick}>Clicks: {count}</button>;
}
Class component using state:
class State extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
handleClick = () => {
this.setState({
count: this.state.count + 1,
});
};
render() {
return (
<button onClick={this.handleClick}>Clicks: {this.state.count}</button>
);
}
}
Vue 2
Updating data:
Vue.component('state', {
data() {
return {
count: 0,
};
},
template: '<button @click="count += 1">Clicks: {{ count }}</button>',
});
Vue 3
Updating data:
Vue.createApp({}).component('state', {
data() {
return {
count: 0,
};
},
template: '<button @click="count += 1">Clicks: {{ count }}</button>',
});
Render
React
Rendering a component:
<!-- index.html -->
<div id="app"></div>
// render.jsx
ReactDOM.render(
<>
<Component />
<Event />
<Prop />
<State />
</>,
document.getElementById('app')
);
Vue 2
Mounting an app:
<!-- index.html -->
<div id="app">
<vue-component></vue-component>
<event></event>
<prop></prop>
<state></state>
</div>
// render.js
new Vue({
el: '#app',
});
Vue 3
Mounting an app:
<!-- index.html -->
<div id="app">
<vue-component></vue-component>
<event></event>
<prop></prop>
<state></state>
</div>
// render.js
Vue.createApp({}).mount('#app');