likes
comments
collection
share

你知道 React 和 Vue 的区别?

作者站长头像
站长
· 阅读数 17

说下ReactVue的区别

你知道 React  和 Vue 的区别?

你知道 React  和 Vue 的区别?

前言

面试时候,有没有面试官问你:“那你说下React 和 Vue 有什么区别?”

该学习了,童鞋!!!

一、编程风格 (Template)

Vue

使用基于 HTML 的模板语法,允许开发者直接在模板中使用指令和插值表达式

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="handleClick">Click me</button>
  </div>
</template>


<script>
export default {
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    handleClick() {
      alert('Button clicked!');
    }
  }
};
</script>
<style>
// 样式
</style>

React

使用 JSX 语法,将 HTML 和 JavaScript 结合在一起,需要在代码中编写类似 HTML 的结构。

import React, { useState } from 'react';


function App() {
  const [message, setMessage] = useState('Hello, React!');
  
  const handleClick = () => {
    alert('Button clicked!');
  };
  
  return (
    <div>
      <p>{message}</p>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
}


export default App;

二、指令功能 (Directives)

1、条件渲染

Vue

v-if:用于条件性地渲染元素。它基于表达式的值来决定是否显示或隐藏元素。

<div v-if="isShown">这个元素会根据 isShown 的值进行条件渲染</div>

React

在React中,可以使用条件语句(如ifswitch)或三元表达式来实现条件渲染。

{isShown && <div>这个元素会根据 isShown 的值进行条件渲染</div>}

2、列表渲染

Vue

v-for:用于基于数组或对象的数据来循环渲染元素。它可以遍历数组或对象的每个条目,并为每个条目生成相应的元素。

<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>

React

使用map函数来遍历数组或对象,并返回相应的元素。

<ul>
  {items.map(item => (
    <li key={item.id}>{item.name}</li>
  ))}
</ul>

3、属性绑定

Vue

v-bind(简写为 :):用于动态地绑定属性或表达式到元素上。它可以将数据绑定到元素的属性、样式或其他特性上。

<img :src="imageSrc" :alt="imageAlt">

React

在React中,可以直接使用JavaScript表达式来动态地设置元素的属性

<img src={imageUrl} alt={imageAlt} />

4、事件处理

Vue

v-on(简写为 @):用于监听DOM事件并触发相应的方法。它可以将方法绑定到元素的事件上,如点击、鼠标移入等。

<button v-on:click="handleClick">点击我触发 handleClick 方法</button>

React

在React中,可以直接将事件处理函数指定为元素的属性。使用箭头函数或绑定this来确保正确的上下文。

<button onClick={handleClick}>点击我触发 handleClick 方法</button>

5、表单双向绑定

Vue

v-model:用于在表单元素和应用程序状态之间创建双向数据绑定。它可以将表单元素的值与Vue实例中的数据进行同步。

<input v-model="message" type="text">

React

在React中,可以通过将表单元素的值与组件的状态(state)进行绑定,使用onchange事件来更新状态。

<input value={message} onChange={(e) => setMessage(e.target.value)} 
type="text" />

三、组件风格 (Components)

这里介绍 React16.8 后的 的 函数组件 和 Vue3.0 后的组合式API

React Hook

React Hook 是 React 16.8 版本引入的一项新特性,它能够让函数组件拥有类组件中的状态(state)和生命周期方法(lifecycle methods)等功能。React Hook 包括了多个钩子函数(hook functions),如 useState、useEffect、useContext 等,在函数组件中使用这些钩子函数可以实现一系列常见的功能,如管理组件内部的状态、处理副作用等。React Hook 的出现使得函数组件可以更加灵活地处理复杂的逻辑,同时也提供了一种清晰且可重用的代码结构,使得代码易于维护和扩展。

import React, { useState, useEffect } from 'react';


const Counter = () => {
  const [count, setCount] = useState(0);


  useEffect(() => {
    console.log('Component did mount');


    return () => {
      console.log('Component will unmount');
    };
  }, []);


  const increment = () => {
    setCount(count + 1);
  };


  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
};


export default Counter;

这个组件使用了useState钩子来保存并更新一个计数器的状态。当用户点击按钮时,计数器会增加,并且在 UI 中显示出来。该 Hook 接受初始状态作为参数,并返回当前状态和一个更新状态的函数。在此示例中,我们使用数组解构将状态值和更新函数分配给count和setCount变量。每次用户单击按钮时,我们用setCount函数更新count的状态。

 

Vue hook

Vue 3.x 开始引入了 Hooks API,用于在函数式组件中实现状态和生命周期的管理。类似于 React 中的 Hooks,Vue 的 Hooks API 包括 setup() 和一些预置的 hooks 函数,如 ref()、watch()、onMounted() 等等,可以让我们更方便地编写函数式组件,并且具有更好的性能表现。其中,setup() 函数会在组件创建之前被调用,它接收两个参数:props 和 context。在 setup() 函数内部,我们可以使用预置的 hooks 函数来定义响应式数据、监听数据变化、执行副作用等操作,最后返回一个对象,该对象中包含模板中所需要使用的数据和方法。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>


<script>
import { ref, onMounted, onUnmounted } from 'vue';


export default {
  name: 'Counter',
  setup() {
    const count = ref(0);


    onMounted(() => {
      console.log('Component mounted');
    });


    onUnmounted(() => {
      console.log('Component unmounted');
    });


    const increment = () => {
      count.value++;
    };


    return {
      count,
      increment
    };
  }
};
</script>

在这个示例中,我们使用了 Vue 3 的 setup 函数来定义组件的逻辑。通过 ref 函数,我们创建了一个响应式的变量 count,并将其初始值设为 0。然后,我们定义了一个名为 increment 的函数来增加 count 的值。

在模板中,我们显示了当前的 count 值,并在按钮上绑定了 increment 函数。当点击按钮时,count 的值会增加,同时视图也会自动更新以反映新的值。  

四、路由风格 (Router)

Vue

采用 Vue-Router (4.X)

npm install vue-router

配置实现(vue 3.0)

router/index.js 创建路由器实例

import { createRouter, createWebHistory } from 'vue-router';


// 创建路由实例
const router = createRouter({
  history: createWebHistory(), // 使用hash模式可以用createWebHashHistory
  routes: [
    { path: '/', component: () => import('../pages/Home/index.vue') },
    { path: '/home', component: () => import('../pages/Home/index.vue') },
    { path: '/about', component: () => import('../pages/About/index.vue') },
    // 更多的路由...
  ],
});
 
export default router;

main.js 路由配置

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index';
import './index.css'


const app = createApp(App);
 
app.use(router);
 
app.mount('#app');

App.vue 使用路由

<div id="app">
  <router-view></router-view>
</div>

 

跳转实现

声明式

Vue中,使用 <router-link> 组件来创建声明式导航链接,通过 to 属性指定目标路由的路径。

<template>
  <div>
    <router-link to="/about">Go to About</router-link>
  </div>
</template>

编程式

Vue 中,可以通过 vue-route中的useRouter方法,执行函数式导航,使用 router.push方法实现跳转。

tips: vue3.X 中的useRouter 相当于 vue2.X 的 this.$router

<template>
  <div>
      <button @click="jump('/home')">home</button>
      <button @click="jump('/about')">About</button>
  </div>
</template>


<script setup>
 import { useRouter } from 'vue-router';


 const router = useRouter()


  const jump=(url = '')=>{
      router.push(url)
  }
</script>

React

采用 React-Router (6.X)

npm install react-router-dom

配置实现(react 18.2)

rouetr/index.js 创建路由器实例和路由配置

import React from 'react'
import { Routes, Route} from 'react-router-dom'
import Home from '../pages/home/index.jsx'


const Router = () => {
    return (
            <Routes>
                <Route path="/home" element={<Home />}></Route>
            </Routes>
    )
}


export default Router

index.js 使用路由

import React from 'react';
import ReactDOM from 'react-dom/client';
import Router from './router/index';
import { BrowserRouter} from 'react-router-dom'


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Router />
    </BrowserRouter>
  </React.StrictMode>
);

跳转实现

声明式

React中,使用 <Link> 组件来创建声明式导航链接,通过 to 属性指定目标路由的路径

import { Link } from 'react-router-dom';


const Navigation = () => {
  return (
    <div>
      <Link to="/about">Go to About</Link>
    </div>
  );
};

编程式

React 中,可以通过 useHistory 钩子来获取路由历史对象,并用 history.push 方法进行函数式导航。

import { useHistory } from 'react-router-dom';


const Navigation = () => {
  const history = useHistory();


  const navigateToAbout = () => {
    history.push('/about');
  };


  return (
    <div>
      <button onClick={navigateToAbout}>Go to About</button>
    </div>
  );
};

五、状态管理 (Store)

这里区别在于,Vue 主推 VuexPinia, React 偏向使用 Redux 和 Mobx。

Vuex 和 Pinia 是专门为 Vue.js 设计的状态管理库,因此它们的语法和API都非常类似。而 Redux 和 Mobx 可以在任何 JavaScript 应用程序中使用,因此他们的语法和API和特定框架没有关系。

Pinia (Vue)

依赖安装

npm install pinia

main.js 创建引入Pinia实例

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
import router from './router/index';
import './index.css'


const app = createApp(App);


const  pinia = createPinia();
 
app.use(router);

app.use(pinia);
 
app.mount('#app');

store/counter.js 创建状态存储模块

import { defineStore } from 'pinia'


export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

Home/index.vue 组件中使用

<template>
    <!-- 直接从 store 中访问 state -->
    <div>{{ counter.count }}</div>
    <button @click="add">点我</button>
  </template>

<script setup>
    import { useCounterStore } from '@/stores/counter'
    const counter = useCounterStore()
    const add = () => {
        counter.increment()
    }
</script>

Mobx (React)

依赖安装

npm install mobx mobx-react --save

store/counter.js 配置数据存储模块

import { makeAutoObservable } from 'mobx';

class CounterStore {
  constructor() {
    makeAutoObservable(this);
  }

  count = 0;

  increment = () => {
    this.count++;
  }

  decrement = () => {
    this.count--;
  }
}

const counterStore = new CounterStore();
export default counterStore;

Home/index.jsx 组件中使用

import React from 'react';
import { observer } from 'mobx-react';
import counterStore from '@/store/counter';

const Counter = observer(() => {
  return (
    <div>
      <h2>Count: {counterStore.count}</h2>
      <button onClick={counterStore.increment}>Increment</button>
      <button onClick={counterStore.decrement}>Decrement</button>
    </div>
  );
});

export default Counter;

六、生命周期 (Life)

根据 创建 挂载 更新 销毁 四个阶段来进行

Vue (3.0)

示意图

你知道 React  和 Vue 的区别?

初始化

1、setup()

在组件实例化时调用,用于设置组件的状态和响应式数据。

挂载

2、 onBeforeMount()

在组件挂载前调用,可以进行一些准备工作。

3、onMounted()

在组件挂载后调用,通常用于执行异步请求或订阅事件。

更新

4、onBeforeUpdate()

在组件更新前调用,可以进行一些准备工作。

5、onUpdated()

在组件更新后调用,通常用于处理更新后的 DOM 操作或执行一些副作用。

卸载

6、onBeforeUnmount()

在组件卸载前调用,用于清理定时器、取消订阅等操作。

7、onUnmounted()

在组件卸载后调用,用于执行一些清理工作。

 

React (18.0)

示意图

你知道 React  和 Vue 的区别?

初始化

1、constructor()

组件实例化时调用,用于初始化状态和绑定方法

2、componentWillMount()

组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。

挂载

3、 render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。

4、componentDidMount()

组件渲染之后调用,只调用一次。

更新

5、componentWillReceiveProps(nextProps)

组件初始化时不调用,组件接受新的props时调用。

6、shouldComponentUpdate(nextProps, nextState)

组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候。需要注意的是,shouldComponentUpdate() 返回true,则组件将会重新渲染在使用 shouldComponentUpdate() 方法时,开发者需要谨慎操作,确保逻辑正确,避免出现意外的渲染结果。

7、componentWillUpdata(nextProps, nextState)

组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state

8、render()

组件渲染

9、componentDidUpdate()

组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。

4、卸载

10、componentWillUnmount()

组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

关于React函数组件

在 React 中,函数组件没有传统的生命周期方法,但是引入了 React Hooks 来管理函数组件的状态和副作用。Hooks 提供了一组函数,可以在函数组件内部使用来实现类组件中的生命周期功能。

以下是一些常用的 React Hooks,可以用来模拟生命周期行为:

  1. useState:用于在函数组件中创建和管理状态。
  2. useEffect:在组件渲染完成后执行副作用操作,相当于类组件中的 componentDidMountcomponentDidUpdate 和 componentWillUnmount 的结合。
  3. useLayoutEffect:在组件渲染完成后,DOM 更新之前执行副作用操作,类似于 useEffect,但在浏览器执行绘制之前同步执行。
  4. useContext:用于访问 React 的上下文(Context)。
  5. useReducer:类似于 Redux 中的 reducer,用于管理复杂的状态逻辑。
  6. useCallback:用于缓存回调函数,以便在依赖项不变时避免重新创建回调函数。
  7. useMemo:用于缓存计算结果,以便在依赖项不变时避免重新计算。
  8. useRef:用于在函数组件的多次渲染之间存储可变值。

使用这些 Hooks,可以在函数组件中实现类组件的生命周期行为。例如,使用 useEffect 可以在组件挂载、更新和卸载时执行相应的副作用操作,使用 useState 可以创建和管理组件的状态。

注意函数组件的 Hooks 必须在函数组件的顶层调用,不能在条件语句、循环或嵌套函数中使用。这是为了确保 Hooks 的调用顺序始终保持一致。虽然函数组件没有传统的生命周期方法,但通过使用 React Hooks,可以在函数组件中模拟生命周期行为并实现相应的功能。

七、怎么选择 (choose)

1、编程风格来看,vue的模板语法贴近于 html,所以在学习初的时候更容易被接受。react的编写方式则是更灵活一些。

2、官方功能实现,Vue的魔改较多。是方便了统一?还是被限制住了?react功能实现除了基本的,都要自己造轮子。是灵活发挥?还是容易造成质量不一?

3、都是广泛被前端使用的主流框架之一, 只为更好更高效的实现前端效果。

合适需求 两个词来形容多者间的选择关系,最好不过了。无非对于这个需求,刚好合适。

对于文章内容有什么指点,欢迎评论留言,也更加欢迎JYM留下更为深层次关于对比的看法。

最后,给JYM两个数据作为参考

下载累计

查询入口:npm-stat.com/

Vue 每月平均下载量 1700w 左右,2023 年累计下载量:199,055,201(2 亿)。

你知道 React  和 Vue 的区别?

 

React 每月平均下载量 8500w 左右,2023 年累计下载量:1,025,630,896(10.2 亿+)

你知道 React  和 Vue 的区别?  

学习难度

vue 前期学习难度前期可能没那么大,后期的进度就要缓慢一点

你知道 React  和 Vue 的区别?

react 前期学习难度可能大一些,后期的难度就越来越小

你知道 React  和 Vue 的区别?

转载自:https://juejin.cn/post/7345821800880160831
评论
请登录