Vue和React对比学习之路由(Vue-Router、React-Router)

简介: Router

简介

今天我们再来对比学习下Vue-RouterReact-Router

如果你已经熟练使用Vue-RouterReact-Router,并且也知道Vue-Router4新特性和React-Router6新特性可以直接阅读本文。如果还不清的话可以先看看笔者前面写的Vue-Router3和Vue-Router4的对比,以及React-Router4/5和React-Router6的对比

希望通过这种对比方式的学习能让我们学习的时候印象更深刻,希望能够帮助到大家。

路由模式

路由模式这块Vue-RouterReact-Router都支持原生浏览器行为的history、hash模式和使用数据结构实现的abstract/memory模式。

但是使用方式上稍有区别。

Vue-Router支持 history、hash、abstract

Vue-Router的路由模式是在创建时指定的。

const router = createRouter({
  mode: "history",
  routes
})

React-Router支持 history、hash、memory

React-Router是在具体使用的时候指定的。

<BrowserRouter>
  <App />
</BrowserRouter>

路由跳转

Vue-RouterReact-Router都支持链接式导航和编程式导航,并且都支持自定义设置激活链接的样式。

Vue-Router使用<router-link />实现链接式导航

<router-link to="/home">Home</router-link>

Vue-Router使用this.$routeruseRouter实现编程式导航

// Vue-Router3
this.$router.push("/home")
this.$router.replace("/home")

// Vue-Router4
const router = useRouter()
router.push("/home")
router.replace("/home")

React-Router使用<Link />、<NavLink />实现链接式导航

<Link to="/home">Home</Link>

// 可以定义激活时的class或者style,也就是多了样式设置。
<NavLink to="/home">Home</NavLink>

React-Router使用historynavigate实现编程式导航

// React-Router4/5 类组件
this.props.history.push("/home")
this.props.history.replace("/home")

// React-Router6 函数组件
const navigate = useNavigate()
navigate("/home")

路由渲染

Vue-Router中,使用 <router-view /> 组件就能把匹配到组件渲染出来,而React-Router需要使用定义路由的<Route />组件或<Outlet />

Vue-Router 使用 <router-view />就能把匹配到的组件渲染出来。

Vue 中我们传递路由配置创建好路由后,只需要使用<router-view />就能把匹配到的组件渲染出来。

// App.vue

<template>
  <router-view />
</template>

React-Router 使用 <Route /><Outlet />

React中,不用提前通过配置文件创建路由,而是在使用的时候才定义路由,所以定义路由和路由渲染是在一起的,都是使用 <Route /> 组件。

<Switch>
  <Route path="/home" component={Home}></Route>
</Switch>

React-Router6中子组件支持<Outlet />的写法,具体可以看React-Router4/5和React-Router6的对比

// User.jsx 子组件 

<Outlet />

路由参数

Vue-RouterReact-Router都支持路由参数的传递和获取,并且都支持显示传参和隐式传参。

Vue-Router 使用router传递参数

Vue-Router支持传递queryparams两种参数,使用时需要注意以下两点。

  1. query传参会在浏览器路径看到,并且刷新页面参数不会丢失。
  2. params传参会在浏览器路径看不到,并且刷新页面参数会丢失。并且可以用在普通路由或动态参数路由上。但是需要注意,当应用到动态参数路由上时我们就不能通过params传参了,只能通过params动态传参。
// vue-Router3

// params传参
this.$router.push({ name: 'user', params: { name: 'randy' } })

// query传参
this.$router.push({ path: '/register', query: { name: 'randy' } })

// Vue-Router4

const router = useRouter()
// params传参
router.push({ name: 'user', params: { name: 'randy' } })
// query传参
router.push({ path: '/register', query: { name: 'randy' } })

Vue-Router 使用query和params接收参数

// Vue-Router3
this.$route.query.xxx
this.$route.params.xxx

// Vue-Router4
const route = useRoute()
route.query.xxx
route.params.xxx

React-Router使用history或navigate传参

React-Router支持传递searchparamsstate三种参数,使用时需要注意以下三点。

  1. search传参会在浏览器路径看到,并且刷新页面参数不会丢失。但是参数需要自己获取并处理,一般我们使用URLSearchParams处理。
  2. params传参只能应用在动态路由上,普通路由传参不能使用。
  3. state传参不会在浏览器路径看到,在history模式下刷新页面参数不会丢失,但是在hash模式下刷新页面参数会丢失。
// React-Router4/5
this.props.history.push({
  pathname: "route3",
  search: "?sort=name",
  hash: "#the-hash",
  state: { fromDashboard: 1 },
});

// React-Router6
navigate(
  { pathname: "../route3/78", search: "name=demi", hash: "hash3" },
  {
    state: { fromDashboard: "navigate state" },
    replace: false,
  }
);

React-Router使用searchparamsstate接收参数

// React-Router4/5类组件
this.props.location.state
this.props.location.search
this.props.match.params
// React-Router4/5函数式组件
const params = useParams()
const location = useLocation()
location.state
location.search //search字符串参数 '?name=randy'

// React-Router6
const params = useParams()
const location = useLocation()
location.state
location.search //search字符串参数 '?name=randy'

const [searchParams, setSearchParams] = useSearchParams(); // search参数,已经使用URLSearchParams封装好了

监听动态路由参数变化

Vue-RouterReact-Router都支持动态路由,都能通过params获取到动态路由参数。

动态路由在VueReact中都做了优化,也就是动态参数的变化并不会让组件重新创建和销毁。也就不会触发组件创建、绑定和销毁相关的钩子函数。所以经常会遇到我们写在mounted或者unmounted中的代码不会被重新触发的问题。

比如我们写在mounted生命周期函数中的逻辑,通过获取动态参数然后去后台请求获取数据,参数改变需要重新获取数据的逻辑就行不通了,那应该怎么修改呢?

Vue-Router监听参数变化的五种方式

Vue中我们可以通过beforeUpdate、updated、beforeRouteUpdate、watch、watchEffect五种方式来监听动态路由参数的变化。

动态路由参数的变化会触发beforeUpdate、updated生命周期函数以及beforeRouteUpdate路由组件内钩子函数。所以上面的例子,通过动态参数获取后台数据的逻辑可以在这些钩子中任选一个加上就可以。推荐使用updated

onBeforeUpdated(() => {
  console.log("route2 onUpdated",route.params.id);
});

onUpdated(() => {
  console.log("route2 onUpdated",route.params.id);
});
    
onBeforeRouteUpdate((to, from) => {
  console.log("route2 onBeforeRouteUpdate", to, from);
});

或者使用watch、watchEffect监听路由的方式来监听参数的变化也是可以的。

watch(
  () => route.params.id,
  (newVal, oldVal) => {
    console.log("watch route: ", newVal, oldVal);
  }
);

watchEffect(() => {
  console.log("watchEffect route: ", route.params.id);
});

如果配置了props模式的话我们还可以监听props

watch(
  () => props.id,
  (newVal, oldVal) => {
    console.log("watch props: ", newVal, oldVal);
  }
);

watchEffect(() => {
  console.log("watchEffect props: ", props.id);
});

React-Router监听参数变化的四种方式

React中我们可以通过老版本生命周期函数componentWillReceiveProps、componentWillUpdate、componentDidUpdate或新版本生命周期函数getDerivedStateFromProps、getSnapshotBeforeUpdate、componentDidUpdate以及watchEffect四种方式来监听动态路由参数的变化。

动态路由参数的变化会触发老版本生命周期函数componentWillReceiveProps、componentWillUpdate、componentDidUpdate或新版本生命周期函数getDerivedStateFromProps、getSnapshotBeforeUpdate、componentDidUpdate生命周期函数所以上面的例子,通过动态参数获取后台数据的逻辑可以在这些钩子中任选一个加上就可以。推荐使用componentDidUpdate

如果是函数组件还可以使用useEffect监听路由的方式来监听参数的变化。

const params = useParams()

useEffect(() => {
  console.log(params);
}, [params]);

路由匹配规则

Vue-RouterReact-Router中,不配置任何规则相关参数的话默认是不用区分大小写和尾部/的。

比如我们配置了一个路由/user/info,在VueReact中下面这些路径都是可以匹配上的。

/user/info
/user/info/
/USER/INFO
/USER/INFO/
...

Vue-Router支持strict、sensitive

Vue-Router3只支持配置canSensitive来控制是否忽略大小写。在Vue-Router4支持strict、sensitive来控制是否忽略尾部/和是否忽略大小写。

{
  path: "/home",
  component: Home,
  strict,
  sensitive
}

React-Router支持strict、sensitive

React-Router中一直支持strict、sensitive来控制是否忽略尾部/和是否忽略大小写。

<Route path="/home" element={<Home />} strict sensitive>

路由获取

Vue任何组件都能获取

Vue中,只要使用了路由,不管是不是路由组件都可以获取到路由(也就是能方便的使用routerroute)。

React非路由组件默认获取不到

但是在React中,非路由组件是不会自动在props中注入路由相关参数的(也就是在props中没有history、location、match),这就需要用到withRouter高阶组件了。使用了withRouter后才能在非路由使用history、location、match

当然如果是函数组件我们还可以使用路由相关hooks获取的。

滚动行为

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 Vue-Router 能方便的做到,它让你可以自定义路由切换时页面如何滚动。

但是React-Router并没有封装这一块的东西,需要自己实现。

Vue-Router定义scrollBehavior即可

const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
})

React-Router需要自己实现

window.scroll(00, 0)

路由嵌套

Vue-Router通过配置方式创建路由,路由嵌套一直都很方便使用。

但是React-Router就没那么容易了,需要继续在子组件定义路由。

Vue路由嵌套可直接配置

Vue-Router只需要在routes里面配置好就可以了。

{
  path: "/home",
  component: Home,
  children: [
    {
      path: "/child1",
      component: Child1,
    }
  ]
}

父组件只需要使用<router-view />就能渲染出子组件。

// Home
<template>
  <router-view />
</template>

React路由嵌套需要在子组件定义

React-Router4/5中,子组件需要继续定义它的孙子组件。

// App.jsx 父组件
<Switch>
  <Route path="/home" component={<Home/>} />
  <Route path="/user" component={<User/>} />
</Switch>

// User.jsx 子组件
<Switch>
  <Route path="/user/info" component={<UserInfo/>} />
  <Route path="/user/detail" component={<UserDetail/>} />
</Switch>

当然React-Router6得到了改进,可以在根组件直接一次性配置。

// App.jsx 父组件
<Routes>
  <Route path="/home" element={<Home/>} />
  <Route path="/user" element={<User/>}>
    <Route path="info" element={<UserInfo/>} />
    <Route path="detail" element={<UserDetail/>} />
  </Route>
</Routes>

// User.jsx 子组件
<Outlet />

配置式路由

Vue-Router一直使用的是配置式路由,配置渲染相分离很方便。但是React-Router如果想要使用配置式路由的话,需要我们自己使用map或者借助react-router-config插件来完成。好消息是React-Router6有了很大的改进。

Vue-Router直接使用配置式路由

Vue-Router一直使用的是配置式路由,这个就不细说了。

{
  path: "/home",
  component: Home,
  children: [
    {
      path: "/child1",
      component: Child1,
    }
  ]
}

React-Router4/5 使用 map 或 react-router-config

首先我们需要定义routes

// routerConfig/routes.js

import Parent from "./Parent";
import Child1 from "./Child1";
import Child2 from "./Child2";

const routes = [
  {
    component: Parent,
    path: "/parent",
    routes: [
      {
        path: "/parent/child1",
        exact: true,
        component: Child1,
      },
      {
        path: "/parent/child2",
        component: Child2,
      },
    ],
  },
];

export default routes;

在根组件,我们需要自己使用map遍历渲染,并把子路由通过routes传递下去。

import routes from "./routerConfig/routes";

<BrowserRouter>
  <Switch>
    {routes.map((route) => {
      return (
        <Route
          path={route.path}
          key={route.path}
          render={(props) => {
            return (
              <route.component
                {...props}
                routes={route.routes}
              ></route.component>
            );
          }}
        ></Route>
      );
    })}
  </Switch>
</BrowserRouter>

在子组件我们还需要继续使用map遍历渲染。

// Parent.js

<Switch>
  {this.props.routes.map((route) => {
    return (
      <Route
        path={route.path}
        key={route.path}
        render={(props) => {
          return (
            <route.component
              {...props}
              routes={route.routes}
            ></route.component>
          );
        }}
      ></Route>
    );
  })}
</Switch>

是不是很复杂,但是我们可以使用react-router-config插件进行简化。

首先安装react-router-config

npm i react-router-config

在根组件,我们只需要使用renderRoutes方法就可以了。

import { renderRoutes } from "react-router-config";
import routes from "./routerConfig/routes";

{renderRoutes(routes)}

在子组件我们继续使用renderRoutes

// Parent.js

{renderRoutes(this.props.routes)}

相对自己写遍历是不是方便了很多呢?其实react-router-config插件内部实现跟笔者上面写的差不多。

React-Router6 使用 useRoutes

React-Router6能更方便的实现。只需要使用useRoutes方法。

首先定义routes

// routerConfig/routes.js

import Parent from "./Parent";
import Child1 from "./Child1";
import Child2 from "./Child2";

const routes = [
  {
    element: <Parent></Parent>,
    path: "/parent",
    children: [
      {
        path: "child1",
        element: <Child1></Child1>,
      },
      {
        path: "child2",
        element: <Child2></Child2>,
      },
    ],
  },
];

在根组件,我们只需要使用useRoutes方法就可以了。

这里需要注意useRouteshook,所以只能在函数组件或自定义组件使用。

import { useRoutes } from "react-router-dom";
import routes from "./routerConfig/routes";

function App() {
 return {useRoutes(routes)}
}

在子组件我们继续使用Outlet渲染子组件就可以了。

// Parent.js
import { Outlet } from "react-router-dom";

<Outlet />

路由钩子

Vue-Router实现了7个钩子函数

Vue-Router实现了7个钩子函数,可以清除的知道从哪个路由来并去哪个路由。还可以通过next方法我们可以很方便的对路由跳转进行控制。

beforeEach(to, from, next)
beforeResolve(to, from, next)
beforeEnter(to, from, next)
beforeRouteEnter(to, from, next)
beforeRouteUpdate(to, from, next)
beforeRouteLeave(to, from, next)
afterEach(to, from)

比如我们取消跳转,只需要给next()方法传递false就可以了,非常方便。

beforeEach(to, from, next) {
  console.log(to, from)
  // 阻止跳转
  next(false)
}

React-Router没有钩子函数

React-Router中并没有实现钩子函数,只在history上提供了listen、block两个函数。

listen用来监听路由的变化,路由变了就会被触发。但是需要注意,点击相同路由也会被触发。

componentDidMount() {
  // 路由监听,统一路由重复点击也会重复触发
  this.unlisten = this.props.history.listen((location, action) => {
    console.log(location, action);
  });

// 组件卸载时,解除监听
componentWillUnmount() {
  this.unlisten();
}

block用来阻止路由跳转,可以实现Vue-Router中类似next(false)的功能。

componentDidMount() {
  this.unblock = this.props.history.block((location, action) => {
    console.log(location, action);
    return "离开?";
  });
}

// 组件卸载时,解除监听
componentWillUnmount() {
  this.unblock();
}

上面的例子当我们点击路由跳转后会弹出

image.png

由于React-Router6已经移除了history,所以上面的例子只针对React-Router4/5

路由鉴权

路由鉴权这块可以说是每个系统中必备的。

Vue-Router中我们通过钩子函数就能很好实现。但是React-Router相对来说就没那么方便。

Vue-Router中通过钩子函数

比如我们常用的登录权限判断就可以写在beforeEach(to, from, next)中。

beforeEach(to, from, next) {
  const token = localStorage.getItem("token")
  if(token) {
    next()
  } else {
    if(to.paht==="/login") {
      next()
    } else {
      next("/login")
    }
  }
}

React-Router中通过 listen 或高阶组件

我们可以在根组件,使用listen来实现登录权限判断。

componentDidMount() {
  this.unlisten = this.props.history.listen((location, action) => {
    const { pathname } = location;
    const token = localStorage.getItem("token")
    if(!token && pathname !== "/login") {
      this.props.history.replace('/login')
    }
  });

// 组件卸载时,解除监听
componentWillUnmount() {
  this.unlisten();
}

或者使用HOC

假设我们的路由配置如下

const routes = [
  {
    component: Parent,
    path: "/parent",
    auth: false,
    routes: [
      {
        path: "/parent/child1",
        component: Child1,
        auth: false,
      },
      {
        path: "/parent/child2",
        component: Child2,
        auth: true,
      },
    ],
  },
  {
    path: "/login",
    component: Login,
    auth: false,
  },
];

export default routes;

然后我们定义一个Auth高阶组件,用来判断用户是否登录。

import React from "react";
import { Route, Redirect } from "react-router-dom";

function Auth(props) {
  const { component: Component, path, auth, routes } = props;

  const token = localStorage.getItem("token");

  if (!auth) {
    return (
      <Route
        path={path}
        render={(props) => <Component {...props} routes={routes} />}
      ></Route>
    );
  }

  // 如果用户有权限,就渲染对应的路由
  if (auth && token) {
    return (
      <Route
        path={path}
        render={(props) => <Component {...props} routes={routes} />}
      ></Route>
    );
  } else {
    // 如果没有权限,返回配置的默认路由
    return <Redirect to="/login" />;
  }
}

export default Auth;

根组件我们渲染的时候使用我们的Auth组件包裹。

// index.js

import routes from "./routerConfig/routes";

<BrowserRouter>
<Switch>
  {routes.map((route) => {
    return (
      // 路由鉴权
      <Auth key={route.path} {...route}></Auth>
    );
  })}
</Switch>
</BrowserRouter>

子组件我们也使用Auth组件包裹。

// Parent.js

<Switch>
  {this.props.routes.map((route) => {
    return (
      // 路由鉴权
      <Auth key={route.path} {...route}></Auth>
    );
  })}
</Switch>

这样就达到了路由鉴权的效果,当我们本地没token的时候,进入/parent/child2是会重定向到/login页面的。

路由原信息

Vue-Router中路由元信息已经封装好。但是在React-Router中是需要我们通过HOC来实现。

Vue-Router使用meta定义原数据

Vue-Router我们只需要使用meta存放好信息后面通过this.$route.meta就能获取。

// 定义
{
  path: "/home",
  component: Home,
  meta: {title: "home"}
}

// 获取
this.$route.meta.title

React-Router使用HOC

类似上面的鉴权,首先在路由配置里面定义好元数据。

const routes = [
  {
    component: Parent,
    path: "/parent",
    auth: false,
    meta: { title: "Parent" },
    routes: [
      {
        path: "/parent/child1",
        component: Child1,
        auth: false,
        meta: { title: "Child1" },
      },
      {
        path: "/parent/child2",
        component: Child2,
        auth: true,
        meta: { title: "Child2" },
      },
    ],
  },
  {
    path: "/login",
    component: Login,
    auth: false,
    meta: { title: "Login" },
  },
];

export default routes;

然后我们需要定义一个HOC高阶组件。最后最重要的就是我们传递给子组件的属性不再具体的传递routes而是otherProps。这样子组件通过props.meta就能获取到元数据啦。

import React from "react";
import { Route, Redirect } from "react-router-dom";

function Auth(props) {
  const { component: Component, path, auth, ...otherProps } = props;

  const token = localStorage.getItem("token");

  if (!auth) {
    return (
      <Route
        path={path}
        render={(props) => <Component {...props} {...otherProps} />}
      ></Route>
    );
  }

  // 如果用户有权限,就渲染对应的路由
  if (auth && token) {
    return (
      <Route
        path={path}
        render={(props) => <Component {...props} {...otherProps} />}
      ></Route>
    );
  } else {
    // 如果没有权限,返回配置的默认路由
    return <Redirect to="/login" />;
  }
}

export default Auth;

在子组件通过props获取

props.meta.title

image.png

动态路由

Vue-Router需要使用addRoute、addRoute方法

由于Vue-Router在创建路由的时候就需要传递路由配置routes,所以导致在动态添加路由这块不够灵活,需要使用addRouteaddRoutes方法。

React-Router直接渲染即可

由于React-Router不需要提前创建路由,所以可以很轻松的实现路由的动态添加,只需要拿到新路由渲染出来即可。

对比总总结

总体感觉Vue-Router封装的更完善,React-Router更灵活。并且它们相互借鉴,分别引用各自的优点,不断更新达到完善。

相同点

  1. 都支持三种路由模式。
  2. 都支持链接式和编程式导航。
  3. 都支持显示和隐式传参。
  4. 都支持动态路由参数,并且都做了优化,动态参数的改变不会导致组件的重新创建和销毁,并通过各自的方法检测到参数的变化。
  5. 都支持路由匹配规则的设置,可以设置大小写和尾/
  6. 都支持路由嵌套。
  7. 都支持配置式路由。
  8. 都支持动态路由。

不同点

  1. Vue-Router需要先通过路由配置创建后再使用,而React-Router是一边定义一边使用。
  2. 由于Vue-Router需要先创建再使用,所以在动态添加路由这方面比React-Router复杂,需要使用特定的方法。
  3. Vue-Router路由传参这块封装的更好,特别是query参数这块,以对象的形式使用非常方便。但是React-Router需要自己使用URLSearchParams处理。
  4. 在路由嵌套这块Vue-Router支持的更好,只需要在routes定义好就可以了。而React-Router需要在组件里面层层定义,但是React-Router6已经有了很大的改动,支持在根组件通过嵌套的方式一次性定义好。
  5. Vue-Router封装了7个钩子函数,我们可以很方便对路由实行鉴权以及路由原信息的定义。React-Router没有提供路由钩子函数,需要使用HOC
  6. 在设置链接激活时的样式时,Vue-Router<router-link />是自带被激活时的类名的,并且支持自定义。但是React-Router需要单独使用<NavLink>组件才会有被激活时的类名。
  7. 滚动行为Vue-Router已经封装好了,直接使用。但是React-Router需要自己实现。
  8. 配置式路由Vue-Router原生支持。但是React-Router需要使用map或者react-router-config插件来实现。当然React-Router6已经有了很大的优化,可以直接使用useRoutes来渲染配置路由。
  9. Vue中,每个组件都能获取到路由信息。但是在React中,只有路由组件才能获取到路由信息,非路由组件需要使用withRouter或者路由相关hooks

系列文章

Vue和React对比学习之生命周期函数(Vue2、Vue3、老版React、新版React)

Vue和React对比学习之组件传值(Vue2 12种、Vue3 9种、React 7种)

Vue和React对比学习之Style样式

Vue和React对比学习之Ref和Slot

Vue和React对比学习之Hooks

Vue和React对比学习之路由(Vue-Router、React-Router)

Vue和React对比学习之状态管理 (Vuex和Redux)

Vue和React对比学习之条件判断、循环、计算属性、属性监听

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

相关文章
|
5天前
|
前端开发 API UED
React 路由守卫 Guarded Routes
【10月更文挑战第26天】本文介绍了 React 中的路由守卫(Guarded Routes),使用 `react-router-dom` 实现权限验证、登录验证和数据预加载等场景。通过创建 `AuthContext` 管理认证状态,实现 `PrivateRoute` 组件进行路由保护,并在 `App.js` 中使用。文章还讨论了常见问题和易错点,提供了处理异步操作的示例,帮助开发者提升应用的安全性和用户体验。
16 1
|
7天前
|
前端开发 安全 网络安全
React——路由Route
React——路由Route
17 2
React——路由Route
|
7天前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
22 2
|
8天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略
|
8天前
|
前端开发 JavaScript 数据管理
React与Vue:两大前端框架的较量与选择策略
【10月更文挑战第23天】React与Vue:两大前端框架的较量与选择策略
|
8天前
|
JavaScript 前端开发 算法
在性能上,React和Vue有什么区别
【10月更文挑战第23天】在性能上,React和Vue有什么区别
9 1
|
8天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】 React与Vue:前端框架的巅峰对决与选择策略
|
8天前
|
JavaScript 前端开发 数据管理
React和Vue的优缺点
【10月更文挑战第23天】React和Vue的优缺点
6 0
|
8天前
|
开发框架 JavaScript 前端开发
React和Vue之间的区别是什么
【10月更文挑战第23天】React和Vue之间的区别是什么
9 0
|
8天前
|
JavaScript 前端开发 Android开发
React和Vue之间的区别是什么
【10月更文挑战第23天】React和Vue之间的区别是什么
7 0