• 关于react与vue的一些对比


    前言

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

    一、style与class

    1.style

    vue

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

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    最终编译后,会给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 => (
    	

    react VS vue

    )
    • 1
    • 2
    • 3
    • 4
    • 5

    2.class

    vue

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

    
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    
    const styleObject = reactive({
      fontSize: '14px'
    })
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    react

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

    const Index = props => {
        const activeClass = 'active'
    	return (
    	

    react VS vue

    ) }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    同样的,使用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...
        }
        
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    react

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

    // 包装一层路由组件,在里面处理token逻辑
    const PrivateRoute = (props) => {
      const token = Cookies.get('TOKEN') || ''
      const Elment = props.element
      useEffect(() => {
        if (!token) {
          // todo...
        }
      })
      return token ?  : null
    }
    
    // 如果是白名单的则直接跳过
    const AuthRoute = ({ auth = true, ...props }) => {
      const WitchRoute = auth ? PrivateRoute : props.element
      return 
    }
    
    const router = [
      {
        path: '/index',
        element: 
      }
    ]
    
    const renderRouter = () => {
      const element = useRoutes(router)
      return element
    }
    export default renderRouter
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    react

    import { useNavigate } from "react-router-dom";
    const App = () => {
        let navigate = useNavigate();
        
        navigate('path')
        navigate('path', {replace: true, state: ''})
        navigate(-1)
        
        return (...)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.baseurl,mode等构建选项

    vue

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

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

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

    // 4.x
    import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
    
    const router = createRouter({
      history: createWebHistory('/pc/'), // createWebHashHistory('/pc/')
      routes: [...],
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    react

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

    import { BrowserRouter, HashRouter} from 'react-router-dom'
    import Routers from './router'
    
    const App = () => (
        
        	
        
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    三、组件

    1.组件注册

    vue

    • 全局注册

    使用app.components方法

    import { createApp } from 'vue'
    import Header from '/components/Header.vue'
    
    const app = createApp({})
    
    app.component('Header', Header)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 局部注册

    1)如果使用

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    react

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

    2.父子组件通信

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

    vue

    使用props和$emit

    要注意的是,在vue3中除了在