关于react与vue的一些对比

17 篇文章 0 订阅
7 篇文章 0 订阅

前言

我最早接触的是vue,后来到新环境接手了个react的项目(16.4之前的版本),就慢慢学起来了。今年刚好有两个新项目由我一人全权负责。我就分别使用了vue3react hooks进行开发。因为都是首次尝试,途中也碰到不少问题,还好接触互联网的帮助都解决了,最后也顺利上线了。 现在回过头来总结一下vue和react在开发使用上的差异

一、style与class

1.style

vue

不得不说vue的scoped真是太方便了,加上之后就不用考虑样式会被覆盖的问题,省了很多事

<template>
	<h1 class="title">
        react VS vue
    </h1>
</template>
<style scoped>
    .title {}
</style>

最终编译后,会给h1加上个data-前缀的属性,然后使用css的属性选择器:title[data-xxxx]

react

而react就有很多方式可选了,css-in-css, css-in js,函数式css等各种方式,可以单独写篇文章了

我在项目中使用的是css Modules,这里就简单介绍下

  • 引入css
  • 类名使用引入的变量名
  • 最终style.title会被编译成一个独一无二的哈希字符串
import style from './index.module.less'

const Index = props => (
	<h1 className={style.title}>react VS vue</h1>
)

2.class

vue

基于v-bind指令,vue提供了丰富方式来绑定class,对象,数组都可,还可以使用多个class

<template>
	<h1 class="title" :class="{ active: isActive}">react VS vue</h1>
	<h1 class="title" :class="[activeClass, errorClass]">react VS vue</h1>
	<h1 :class="['title', { active: isActive }]">react VS vue</h1>
</template>

也可以直接使用style绑定内联样式

<template>
	<h1 :style="{fontSize: '14px'}">react VS vue</h1>
	<h1 :style="styleObject">react VS vue</h1>
</template

<script setup>
const styleObject = reactive({
  fontSize: '14px'
})
 </script>

vue3中还可以在css中使用v-bind绑定变量,真的很方便

<script setup>
const opacity = ref(0.3)
 </script>
<style scoped>
    .title {
        opacity:v-bind('opacity')
    }
</style>
react

react这里使用的是className,只能使用字符串,如果想动态传class,可以使用es6的模板字符串

const Index = props => {
    const activeClass = 'active'
	return (
	<h1 className={`title ${activeClass}`}>react VS vue</h1>
    )
}

同样的,使用style内联样式也是差不多,这就不多写了,反正react中,万物皆js(狗头.jpg)

二、路由

vue router文档:https://router.vuejs.org/zh/

react router文档 https://reactrouter.com/

这次react 使用的是react router v6版本的,vue router则是4.x,两者有相似的地方也有不同的地方。

配置上差不多,像动态路由,嵌套路由等都相似,调用路由的方式也类似,只是api不一样

这里挑几个项目遇到的实际问题说下

1.路由拦截

vue

beforeEach,beforeResolve ,afterEach三个路由钩子

可以放在全局,组件内,路由配置中,很方便

这里举个项目中最常用的例子,判断token

//main.js
router.beforeEach((to, from, next) => {
    if(token) {
        next()
    } else {
        // todo...
    }
    
})
react

无现成api,我在项目中通过包装一层组件,在组件里处理逻辑

// 包装一层路由组件,在里面处理token逻辑
const PrivateRoute = (props) => {
  const token = Cookies.get('TOKEN') || ''
  const Elment = props.element
  useEffect(() => {
    if (!token) {
      // todo...
    }
  })
  return token ? <Elment {...props} /> : null
}

// 如果是白名单的则直接跳过
const AuthRoute = ({ auth = true, ...props }) => {
  const WitchRoute = auth ? PrivateRoute : props.element
  return <WitchRoute {...props} />
}

const router = [
  {
    path: '/index',
    element: <AuthRoute element={Index} />
  }
]

const renderRouter = () => {
  const element = useRoutes(router)
  return element
}
export default renderRouter

2.路由api

vue
import { useRouter } from 'vue-router'

const router = useRouter()

router.push('url')
router.push({path:'url', params: {...})
router.push({name:'mine', params: {...})
router.push({path:'url', query: {...})
router.replace({...})
router.go(1)
router.back()
react
import { useNavigate } from "react-router-dom";
const App = () => {
    let navigate = useNavigate();
    
    navigate('path')
    navigate('path', {replace: true, state: ''})
    navigate(-1)
    
    return (...)
}

3.baseurl,mode等构建选项

vue

一开始我以为像是在3.x的版本一样,在配置对象中使用直接配置mode,base就可以了,然后发现不生效,翻完文档之后才发现换了,4.x采用全新apicreateWebHistory, RouteRecordRaw

// 3.x
const router = new VueRouter({
  mode: 'history', // hash
  base: '/pc/',
  routes: [...]
})

4.x直接使用history属性就可搞定

// 4.x
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory('/pc/'), // createWebHashHistory('/pc/')
  routes: [...],
})
react

react router采用组件形式,根据需求选择嵌套对应的组件即可

import { BrowserRouter, HashRouter} from 'react-router-dom'
import Routers from './router'

const App = () => (
    <BrowserRouter basename="/pc">
    	<Routers />
    </BrowserRouter>
)

三、组件

1.组件注册

vue
  • 全局注册

使用app.components方法

import { createApp } from 'vue'
import Header from '/components/Header.vue'

const app = createApp({})

app.component('Header', Header)
  • 局部注册

1)如果使用<script setup>,那就无需注册,直接导入就可以用

2)如果未使用<script setup>,那需要把导入的组件放在components

<script>
import Header from '/components/Header.vue'

export default {
  components: {
    Header
  },
  setup() {
    // ...
  }
}
</script>
react

react组件无需注册,直接引入即可使用,注意必须要以大写字母开头

2.父子组件通信

父子组件通信有很多,算是常见的面试题了,这里不过多阐述,只挑最常用的props来对比

vue

使用props和$emit

要注意的是,在vue3中除了在<template>中,其他地方不能直接使用emit,需要用到defineEmits来声明

// parent.vue
<Children age="18" @myEvent="changeName"></Children>

// children.vue
<button @click="changeName">change</button>
<script setup>
    const emit = defineEmits(['changeName'])
    const changeName = name => {
        emit('changeName')
      };
</script>
react

父组件使用props数据和回调函数给子组件,子组件通过回调函数传给父组件去接受

// parent.js
<Children onChangeName={changeName}></Children>

// children.js
const Children = (props) => {
    const { age, onChangeName } = props
    
    return <button onClick={() =>onChangeName('xxx')}>change</button>
}

3.多层组件传值

vue

使用Provide/Inject

import { createApp } from 'vue'

const app = createApp({})

app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
<script setup>
import { inject } from 'vue'

const message = inject('message','这是默认值')
</script>
react

使用Context

const MyContext = React.createContext(defaultValue);

const App = () => (
    <MyContext.Provider value={}>
        <Index/> 
    </MyContext.Provider>
)

const Index = () =>{
   const value = useContext(MyContext)
   //...
}

4.插槽

vue

使用<slot>

<!-- SubmitButton.vue -->
<button type="submit">
  <slot>
    Submit <!-- 默认内容 -->
  </slot>
</button
    
<!-- index.vue  -->
 <SubmitButton>Save</SubmitButton>  
react

使用props.children

const SubmitButton = (props) => (
    <button type="submit"> {props.children} </button>
)

const App = () => (
	<SubmitButton>Save</SubmitButton>
)

四、状态管理

vue

一直以来,vuex都是vue全家桶成员之一,直到vue3出现之后,pinia才渐渐火了起来

react

react那可真是百花齐放啊,各种各样的都有(每次都要纠结好久选哪种

这次项目选了Recoil,真的是非常简单,就几个api,几分钟就上手了,推荐大家试试

五、国际化

两个项目都是国际化的,都需要用到多语言和镜像页面,刚好之前也写过对应的文章,直接看吧

vue

vue3实现国际化

react

react(Hooks)实现国际化

总结

框架本身没有优劣之分,只有适合与否,根据自己的业务场景,团队技术栈来选择。

就业务来说,可能我这两项目不够大,还无法体现出优劣度

团队的话,哈哈这两项目都是我自己一人开发

但是从开发体验上来讲,vue确实方便很多,直接按照全家桶的配置来加,生态的文档也基本都有官方的中文版,照着文档基本都没啥大坑

react的话,非常灵活,生态太丰富了,选个状态管理都挑了好久哈哈,但是好多文档都只有英文版的,特别是这次还用了react router v6,各种新的api,踩了不少坑。

引用网上看到的一句话:当 react 同学还在技术选型,做项目配置,写前置代码的时候,写 vue 的同学已经下班回家了

虽然react麻烦点,但是我个人还是比较喜欢react,觉得react写起来比较有感觉

(之后会持续补充更新)

完事~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值