Vue.js and React are popular JavaScript frameworks for building user interfaces, but they differ in design philosophy, syntax, and features. Below, I’ll outline the key differences when writing Vue code (e.g., declaring components, creating pages, or routes) compared to React, focusing on practical aspects. At the end, I’ll provide a difference table summarizing the points.
Key Differences
-
Component Declaration:
- Vue: Components are defined using a single-file component (SFC) format with
.vue
files, combining HTML-like templates, JavaScript logic, and scoped CSS in one file. Thescript
section uses anexport default
object withdata
,methods
, and lifecycle hooks.<!-- MyComponent.vue --> <template> <div>{{ message }}</div> </template> <script> export default { data() { return { message: 'Hello Vue' } } } </script> <style scoped> div { color: blue; } </style>
- React: Components are typically defined in
.jsx
or.tsx
files using JavaScript/JSX syntax. Logic and markup are intertwined, and CSS is often handled separately (e.g., via CSS modules or styled-components).// MyComponent.jsx import React, { useState } from 'react'; import './MyComponent.css'; function MyComponent() { const [message, setMessage] = useState('Hello React'); return <div>{message}</div>; } export default MyComponent;
- Vue: Components are defined using a single-file component (SFC) format with
-
Template Syntax:
- Vue: Uses HTML-based templates with directives like
v-bind
,v-if
, andv-for
for declarative rendering. Templates are separate from JavaScript logic.<template> <div v-if="show">{{ message }}</div> </template>
- React: Uses JSX, embedding HTML-like syntax within JavaScript. Logic and rendering are tightly coupled, using JavaScript expressions for conditionals and loops.
<div>{show ? message : null}</div>
- Vue: Uses HTML-based templates with directives like
-
State Management:
- Vue: Reactive state is managed via the
data
function (Options API) orref
/reactive
(Composition API). Vue’s reactivity system automatically tracks dependencies.<script> import { ref } from 'vue'; export default { setup() { const count = ref(0); return { count }; } } </script>
- React: State is managed with hooks like
useState
oruseReducer
. Updates require explicit calls to state setters, and React re-renders based on state changes.const [count, setCount] = useState(0);
- Vue: Reactive state is managed via the
-
Routing:
- Vue: Uses
vue-router
for routing, with routes defined in a centralized configuration. Components are mapped to routes, and navigation is handled via<router-link>
or programmatic navigation.// router/index.js import { createRouter, createWebHistory } from 'vue-router'; import Home from '../views/Home.vue'; const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: Home } ] });
- React: Uses
react-router-dom
for routing. Routes are defined similarly, but JSX-based<Route>
components are often used in a declarative structure.// App.jsx import { BrowserRouter, Routes, Route } from 'react-router-dom'; import Home from './Home'; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> </Routes> </BrowserRouter> ); }
- Vue: Uses
-
Reactivity System:
- Vue: Has a built-in reactivity system that automatically tracks dependencies and updates the DOM when data changes, simplifying state management.
- React: Relies on explicit state updates and virtual DOM diffing. Developers must trigger re-renders via state changes, which can be more manual.
-
Styling:
- Vue: Supports scoped CSS within
.vue
files using the<style scoped>
tag, ensuring styles don’t leak to other components. - React: Requires external solutions like CSS modules, styled-components, or inline styles. No built-in scoped styling mechanism.
- Vue: Supports scoped CSS within
-
Directives vs. JavaScript Logic:
- Vue: Uses directives (
v-bind
,v-on
, etc.) for common tasks like binding attributes or handling events, reducing boilerplate.<button v-on:click="increment">Click</button>
- React: Relies on JavaScript for event handling and logic, using inline event handlers.
<button onClick={increment}>Click</button>
- Vue: Uses directives (
-
Learning Curve:
- Vue: Gentler learning curve due to its template-based syntax and built-in features like reactivity and scoped styles.
- React: Steeper learning curve due to JSX, hooks, and the need for external libraries for tasks like routing and state management.
-
Ecosystem and Tooling:
- Vue: Tightly integrated ecosystem with official tools like
vue-router
,pinia
(state management), andVue CLI
/Vite
. Fewer third-party dependencies needed. - React: Flexible but fragmented ecosystem. Relies on third-party libraries like
react-router-dom
,redux
, orzustand
, requiring more setup.
- Vue: Tightly integrated ecosystem with official tools like
-
Performance:
- Vue: Lightweight (20KB minified) with efficient reactivity and DOM updates, suitable for smaller apps.
- React: Slightly heavier (40KB minified) due to virtual DOM overhead but optimized for complex, dynamic UIs.
Difference Table
Feature | Vue.js | React |
---|---|---|
Component Declaration | Single-file components (.vue ) with template, script, and scoped CSS | JSX/TSX files with intertwined logic and markup, separate CSS |
Template Syntax | HTML-based templates with directives (v-bind , v-if , v-for ) | JSX, embedding HTML in JavaScript with JS expressions |
State Management | Built-in reactivity (data , ref , reactive ) | Hooks (useState , useReducer ) with explicit state updates |
Routing | vue-router with centralized route config and <router-link> | react-router-dom with JSX-based <Route> components |
Reactivity | Automatic dependency tracking and DOM updates | Virtual DOM diffing with explicit state-driven re-renders |
Styling | Scoped CSS in <style scoped> tag | CSS modules, styled-components, or inline styles |
Directives vs. Logic | Directives (v-on , v-bind ) for concise event/attribute handling | JavaScript-based event handling and logic |
Learning Curve | Gentler due to templates and built-in features | Steeper due to JSX, hooks, and external library reliance |
Ecosystem | Integrated (official vue-router , pinia , Vite ) | Flexible but fragmented (third-party react-router , redux , etc.) |
Performance | Lightweight (~20KB), efficient reactivity | Heavier (~40KB), optimized for complex UIs via virtual DOM |
This table and comparison focus on practical differences when writing code for components, pages, or routes. If you’d like a deeper dive into any specific aspect (e.g., a sample Vue/React app comparison), let me know!