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
.vuefiles, combining HTML-like templates, JavaScript logic, and scoped CSS in one file. Thescriptsection uses anexport defaultobject 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
.jsxor.tsxfiles 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-forfor 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
datafunction (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
useStateoruseReducer. 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-routerfor 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-domfor 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
.vuefiles 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!