xdm, Vue 和 React

377 阅读19分钟

简单对比一下 Vue 和 React 两种技术栈,会结合自己的实践经历,也会参考官网文档以及大佬博客

怎么说呢!写之前感觉心血来潮,觉得自己能写好多巴拉巴拉,写完之后发现自己还有好多不懂不会的,有一些东西感觉知道点什么,但又说不清楚,哎!

1.初识React

可以简单了解一下原生 JS 到现在主流的框架,听说以前的前端开发人员就是小小切图仔,在以后端为主的 MVC 时代,前端页面都是在服务端进行渲染的,像 JSP (Java Serve Page,课设的时候了解过一点点) 就是在 HTML文件里面嵌入 JAVA 代码得到相对应的 HTML 页面。

而后 Ajax 的出现给前端,给 Javascript 带来了新生。前后端围绕 Ajax 接口进行协作,一些复杂的操作交给了浏览器,由 JavaScript 处理,浏览器也能渲染页面。前后端逐渐分离,前端开发人员的任务变得多了起来,开启了以前端为主的 MVC 时代。这里也不是说前端在开发中的地位一下子无敌了,但起码重要了起来嘛!因为前端也能处理路由,MVC 三个字,Model 是后端的,View 是前端的,Controller(主要是路由)都能挨上。hahaha

然后为了降低开发难度,涌现了一批的框架,现在比较流行的,我也刚好学过一点的就是 Vue 和 React 了。

在 Vue 的官方文档上开头由这么一句

image-20210817023812916.png

对于 MVVM 的理解可以参考阮一峰老师的博客,按照老师的话,比较好理解

而对于 MVVM 这种架构的分层的话,VM (ViewModel) 视图层绝对是其中的亮点,View 只展示页面 ,Model 只提供数据,视图层 对从 Model 层获取到的数据进行封装,并且提供操纵数据的方法。

而且由于数据和操纵的方法都封装在视图层,我们开发者不再需要去手动操纵 DOM,最繁琐最无聊的部分都交给我们的框架,改变 VM 里面的数据,View 层的内容会实时变动。这就是响应式。

以上介绍了 Vue 和 React 在软件架构设计模式中扮演的角色,后面我们的比较都是基于脚手架,所以先看一下两个技术栈的主流工具链

2 脚手架

2.1 目录

Vue 就是 Vue CLI 了 ,用 CLI3+ 创建项目不仅可以通过在终端执行 vue create my-project 还可以使用 vue ui,使用可视化的方式创建项目。

React 就是 create-react-app 了,在终端执行 create-react-app my-project 创建项目

上边这两种技术栈的脚手架,都是能够让用户快速启动一个项目,减少繁琐的配置,将项目中使用到的 Webpack,Babel 等配置封装了起来

可能是因为都是基于 Webpack 打包的缘故,使用它们创建项目的目录其实都大差不差,如果你有过实践就会有体会

  • 有一个 index.html文件,里面有一个没有内容的(一般都是)div,
  • 然后有一个 main.js/index.js作为项目的入口,通过元素选择器,将要展示的内容注入到 index.html
  • 最后都有一个 App.js/App.vue,作为被注入的内容,其他的内容都通过组件模块的形式被添加到 App.js/App.vue

2.2 组件

Vue 和 React 都是以组件的形式进行开发,这样项目的结构一目了然,也能更加方便项目后续的拓展和维护,但是有一点不同的就是组件的形式。

Vue 中一个组件就是一个 .vue 文件, HTML CSS JS 都在这个文件里面,模块化的思想一目了然

<template>
</template><script>
export default {
}
</script><style>
</style>

React 使用的是 JSX 语法,有一点 all in js 的意味

import React from 'react'export default function index() {//函数式组件
    return (
        <div>
            
        </div>
    )
}
import React, { Component } from 'react'
​
export default class index extends Component {//类式组件
    render() {
        return (
            <div>
                
            </div>
        )
    }
}

2.3 模块导入导出

在 React Vue 中使用的都是 ES6 中的 Es Module import Home from './home';

这里可以稍微拓展一下模块化的知识,在另一篇文章中写过一点 Node.js 采用了 CommonJs 语法规范,并且是同步加载,这更加适合服务端,因为加载时间就等于硬盘的读取时间嘛!而浏览器端加载模块是通过网络请求,可能要通过很长的时间加载,这样功能就不能实现,浏览器处于“假死状态”,用户体验不良好。还听说过 AMD——异步模块规范。但是见的比较多的就是 ES6 的 ES module 了

有一个很重要的区别就是 CommonJs 是运行时加载的,像

let { readFile } = require('fs');

上边的代码。虽然我们只用到了 fs 模块上边的 readFile 但却是把整个 fs 模块都加载了

ES6 模块化是编译时加载的,就可以在编译时做一些优化

import { readFile } from 'fs';

上边的代码只会加载 readFile 方法

CommonJS 是对模块的浅拷贝,ES6 Module 是对模块的引用。 具体比较可以参考零一大佬的这篇文章,就不 CV 了

3.数据/状态

3.1 数据

Vue中就是 data 了

var vm = new Vue({
  data: { a: 1 }
})

因为组件复用导致了共享数据,所以我们的 data,推荐函数形式,有函数作用域嘛!

var vm = new Vue({
  data(){
     return { a: 1 }
  }
})

React 中就是 state对象了

state = { a: 1 }

当然 hook 出现,函数式编程再次称霸 React了,useState 也是一种状态管理

const [count, setCount] = useState(1);

3.2 操纵数据

就是函数嘛!函数就进去一些数据,处理,然后出来另一些数据。

在 Vue 中都是放在 methods 中的,许多人都说 React 更加贴近 Javascript 从这里就可以看出一点点东西,因为 Vue 中一个组件(包括HTML,CSS)就可以理解为一个 Vue 的对象,它的方法数据啥的,都是以对象属性存放着的

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  methods:{
  click(){
    console.log(this.message)
  }
  }
})

在 React 中,如果是类式组件,函数可以在类中直接定义,但是要解决 this 指向问题,也可以通过给类属性赋值函数定义,可以稍微看一下我之前弄过的一篇博客,hooks 火起来后,听说现在都是函数组件居多,在函数中就直接定义函数就好了嘛!就像 Javascript 语法一样。

3.3 组件通信

3.3.1 父传子

Vue 和 React 中父子组件通信都离不开 props.

在 Vue 中,通过 v-bind ,动态给组件绑定属性,子组件通过 props 接收

<body>
    <div  id="app">
       <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
    </div>
    <template id="cpn">
        <div>
            <p>你好{{cmovies}}</p>
            <p v-for="items in cmovies">{{items}}</p>
         </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const cpn = {
            template:'#cpn',
            props:['cmovies','cmessage'],
        }
        const app = new Vue({
            el: '#app',
            data: {
                message: "我是一个小小的默认值",
                movies:['复仇者联盟','紧急救援','除暴','我的家乡'],                                      
            },
            components:{
                cpn//这里是字面量增强的写法,属性和值同名就写一个就行
            }        
        })
    </script>
</body>

React 中就是给自定义属性赋值了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="test"></div>
    <!-- 省略一些需要引入的cdn -->
    <script type="text/babel">
    //1.创建类式组件
    class Demo extends React.Component {
        render(){//从实例的props属性上面取得传来的值
            const {name,age,height,speack} = this.props
            return (<ul>
                <li @click="speack">{name}</li>
                <li>{age}</li>
                <li>{height}</li>
                </ul>)
        }
​
    }
    const p = {name:"小林别闹",age:20 ,height:"175"}
    function speak(){
        p.name = "瓦达西瓦小林"
    }
    //2.渲染组件到页面,利用扩展扩展运算符,在组件标签里面写的数据,会放到实例的props属性上
    ReactDOM.render(<Demo {...p} fun={speak}/>,document.getElementById('test'))
    </script>
</body>
</html>

3.3.2 子传父

在 Vue 中就是子组件抛出自定义事件,父组件监听的形式来处理,this.$emit() 来抛出事件 v-on 监听

<body>
    <div  id="app">
       <cpn @itemclick = "cpnclick"></cpn>
        <!-- 点击按钮后传出了一个自定义的事件,在父组件里面给该事件绑定函数,该函数是定义在父组件的methods里面的, -->
    </div>
    <template id="cpn">
        <div>
            <button v-for="items in categories" @click="btnclick(items)">{{items.name}}</button>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const cpn = {
            template:'#cpn',
            data() {
                return {
                    categories:[
                        {id:"aaa",name:"热门搜索"},
                    ]
                };
            },
            methods:{
                btnclick(items){
                    //发射事件,第一个参数自定义的事件名,第二个参数就是要传的一些信息
                    this.$emit('itemclick',items);
                }
            }
        }
        const app = new Vue({
            el: '#app',
            data: {                                         
            },
            methods: {
                //定义的事件触发函数,上面没给函数传参,会默认把关于事件的信息作为参数传过来,这里就是定义发送事件时传的第二个参数
                cpnclick(a){
                    console.log(a);
                }
            }, 
            components:{
                cpn              
            }        
        })
    </script>
</body>

React 中比较有意思了,给子组件传递一个父组件定义的函数,通过这个函数来改变父组件的状态,因为不管是类还是函数都是存在作用域一说的嘛!上边写父传子例子的适合,speak 函数就是例证。

3.3.3 插槽

Vue 中的插槽可好理解了,就动态的给组件结构预留一个位置嘛!有一点像路由中的占位符呢!

    <div  id="app">
        <cpn><p>在使用组件时写插槽里面的内容</p></cpn>
        <cpn><span>如果不写就显示默认值</span></cpn>
        <cpn></cpn>
    </div>
    <template id="cpn">
        <div>
            <p>我是组件</p>
            <slot><button>我是slot插槽里面的默认值</button></slot>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const cpn = {
            template:'#cpn'
        }
        const app = new Vue({
            el: '#app',
            components:{
                cpn              
            },
        })
    </script>

React 中就还得靠 props 了,比如下面,<Test> 是自定义组件,父组件塞在组件里面的内容可以通过 props.children 拿到,有一点像原生 JS 里面的子节点,这样也就可以实现插槽效果了

          <Test>
            <div>1</div>
            <div>2</div>
          </Test>

3.4状态管理器 Vuex, Redux

3.4.1 简介

前面我们写了在 Vue 和 React 中,每个组件都能够拥有自己的状态/数据,组件之间还能通信,并且能够根据情况改变数据从而改变视图。但还是会存在一些问题,祖孙组件,兄弟组件之间的频繁通信也是需要考虑的。

并且 Vue 中 的 EventBus(事件总线),React 中的 Context 都存在一定的鸡肋。这个时候状态管理器就站出来了,以前是每个组件都弄自己的状态,现在,每一个组件都能获取处理一个共享的状态,组件直接可以理解为一个树状图,组件之间通信可以逐级甚至越级,而状态管理器中的状态,就像一双上帝之手,我有,你又想要,你就能得到。

image-20210819020754208.png

3.4.2 Redux

可以先写一下 Redux 的核心思想,这玩意要说难确实难,要说简单,肯定不是我说的。

image-20210819022144277.png

我觉得好兄弟们包括我自己看这篇博客的时候,一定都是有一定的基础了,所以就不用那种新手比喻来写原理了

理解以及用法总结下来就是:黄色块块 ActionCreators 是函数,返回对象 Action ,橙色块块 Store 是 Redux 这个库的核心,轮不到我们写,配置好就行,紫色块块 Reducers 也是函数,并且推荐是纯函数,用于处理 Store 中的数据

围绕数据就两点嘛,获取以及处理,获取很简单,在组件内通过 getState() 就可以,改变数据就有些麻烦了,毕竟你想,这个数据不是你一个人的,麻烦点正常。params

你可以在组件内看到这样的代码:dispatch(fristAction(params)),fristAction() 是我们自己定义的,返回一个 action 对象,type 属性告诉 Reducer 你想干嘛,data 属性提供参数。 然后来到了 Store 它会将刚刚的 action 对象以及 Store 里面的状态 给 Reducer ,Reducer 处理完后把状态返回给 Store

纯函数是啥呢!其实就是一个函数,但是它执行完后不会产生任何副作用,输出什么完全看你输入什么,函数外边作用域里面的变量啊啥的,都不会去动他。所以我们一般会对 Store 给的状态做一层深拷贝,或者也可以直接使用 immutable.js这个库。原理应该也是深拷贝了,只是是封装过的,用起来比较舒服。

但是有一个需要注意的是,Redux 只负责管理状态,Store 里面的状态的改变却是不会驱动页面,往往我们需要使用 store.subscribe 来监测然后更新整个 <APP/>,其实这里也不会全部更新啦,因为有 diff 算法嘛!

3.4.3 react-redux

因为 Redux 在 React 中用的比较多,所以有了 React-redux 这个库,不得不说 React 的生态确实好。

react-redux模型图.png

上边的图也说了,主要就三点吧

第一点就是多了一个容器组件的概念,我们使用 connect 来连接容器组件和 UI 组件,在容器组件中获取 state,定义方法,传递给 UI 组件

第二点就是,react-redux 能够监听状态变化并驱动页面展示了

第三就是提供了 <Provider></Provider> 标签,能够高效的让每个组件使用到 Store

3.4.4 Vuex

如果对 Redux 有过学习,那么上手 Vuex 是很快的,Vuex官方文档上也提到有借鉴 Redux

image-20210819163838243.png

安装使用步骤可以参考官网,介绍起来就那么几点

const store = new Vuex.Store({//新建的Store对象
  state: {//Vuex里面保存的状态
    count: 0
  },
  mutations: {//修改状态的方法
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})
  1. 数据访问:

    1. 在组件中使用 this.$store.state.数据名 访问
    2. computed:{
      ...mapState(['count'])//三个点是拓展运算符,然后就可以像使用计算属性那样使用count了
      }
      
  2. 修改数据:我们不能在组件内直接修改 state,还是那句话,state 是大家的,你得用 Store 里面得方法来修改 state,两种方式,下面是伪代码啦

    1. methods:{//在组件的methods通过commit调用
          handle(){
             this.$store.commit('increment',3)//这种调用同样是可以携带参数的
          }
      }
      
    2. import {mapMutations} from 'vuex'
      methods:{
          ...mapMutations(['add'])
      }//这样就将add方法映射到methods里面了,可以像使用其他方法那样使用
      
  3. 异步操作

matations 里面不能放一些异步操作,异步操作放到 actions 里面,不过在 actions 里面还是得通过 matations 里面得方法来改变 state ,规矩不能乱,定义在最上边得代码上有。调用就和调用 matations 差不多了,只不过关键字变成了 dispatchmapActions

  1. getter

    const store = new Vuex.Store({
      state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
      },
      getters: {
        doneTodos: state => {
          return state.todos.filter(todo => todo.done)
        }
      }
    })
    

    其实就和 Vue 中得计算属性差不多,对 state 进行一层包装,todos 变化 doneTodos 也会变化,访问的话关键字就是 store.gettersmapGetters

  2. 模块化

    当你的项目变的复杂的时候,数据也会很多很多,而一些数据只是其中一些组件用得到,这时候就可以将 Srore 模块化,分成几个小 Store,其实 Redux 也是可以这样子弄的。

    4 事件处理

想要与用户进行交互,与事件打交道是必不可少的。在原生 Javascript 我们一般会获取 DOM 元素,再通过 addEventListener ,对事件监听并处理。当然也可以直接在 HTML 标签里面绑定

<button onclick="displayDate()">点我</button>

前面应该说过,不管是 Vue 还是 React 都基本不会让我们再自己操纵 DOM ,所以绑定事件的形式都在标签里面

4.1 React

先写 React 吧,React 事件的命名采用小驼峰式,而不是纯小写,因为是 JSX 语法的缘故,需要将函数名写中括号里面

<button onClick={displayDate}>点我</button>

当然因为类的缘故,还要纠正 this 指向,方法之前也提过,携带参数这里就还有点东西的,你会发现,写在中括号里面的是一个函数名,没有加括号,加了括号就会在渲染时直接调用。

我知道两种方法

  • <button onClick={(e) => this.deleteRow(id, e)}>回调函数</button>
    
  •     saveFormData = (dataType) => {
            return (event) => {//随着输入维护状态,就是受控组件,用state来实现,现用现取就是非受控组件,通过ref来实现
                this.setState({[dataType]:event.target.value})
            }//函数柯里化,通过函数继续调用函数的方式,实现多次接收参数最后统一处理
        }
        
        <input onChange={this.saveFormData('username')} type="text" placeholder="请输入用户名"/>
    

4.2 Vue

Vue 中好像要简单一些!使用 v-on 或者是 @ 绑定 要传递参数的话,直接传就好了,还可以使用修饰符修饰

<button v-on:click="greet">Greet</button>
<button v-on:click="say('hi')">Say hi</button>
<a v-on:click.stop="doThis"></a>

5.样式

在 Vue 中三剑客都在一个文件里面,我称之为 “三位一体”,hahaha,组件的样式自然就是写在 <style> 里面了,React 中的话就是引入一个 .css 文件啦,可以记录一下的点就是动态样式的写法

Vue 本身就是支持这种写法的,通过 v-bind (语法糖:),来动态绑定属性。下面伪代码

<div
  class="static"
  :class="{ 'class1': bool1, 'class2': bool2 }"
></div>
data(){
  return {
    bool1:true,
    bool2:false
  }
}

在 React 中就要借助其他的工具了,虽然我自己不行,耐不住我生态好啊!

import classnames from 'classnames'
<div className={classnames({'todoCentent':type === 'false','doneCentent':type === 'true'})}>内容</div>

6.生命周期

生命周期,哈哈哈,就用过其中的一两个,可能没有接触比较复杂的需求啥的,就很少难接触到吧。组件也就像人的一生,从被创造出来,到落叶归根。 说的挺玄的,我其实就是到了某个事件/阶段了就触发对应的函数,我们可以在这些个里面写我们想要它去做的代码。这些函数也被称为 “钩子函数”

6.1 Vue

我还真不好怎么写,在我的记忆中,Vue 好像就用过 mounted,和 created 如果大堆概念,那还不如去看大佬的博客,我写在这,自己也记不住, CV 的话,还有可能弄错去!就放一张图吧(也是从大佬博客腾过来的)

方便记忆的话就几组:

创建前/后, 挂载前/后,更新前/后,销毁前/后

Vue生命周期图

6.2 React

我没能在 React 官网找到流程图,倒是b站尚硅谷的课程上有两图,就拿(偷) 过来了

这张是 React 16 的

image-20210823192914668.png

这张是 React 16+ 的

image-20210823211002337.png

就去掉了三个不常用的,新增了两个不常用的,哈哈哈,众所周知,React 有两种组件形式,类和函数,看到生命周期里面的 consturctor 咱们就知道,函数组件是没有生命周期的,这就导致在函数组件中无法进行一些细节的操作,像发送 Ajax 请求,取消监听等操作,但是也是因为没有生命周期这么多钩子,所以函数组件渲染 UI 会高效很多。

然后现在不是 hooks 很火嘛!一个小小的 useEffect 就能让函数组件也能 “拥有” 生命周期,之前学习的时候也写过一点都 hooks 用法的博客!

7. 渲染

按说渲染应该上一节生命周期写的,但是生命周期的记录的比较潦草,觉得渲染还是挺重要的。

像浏览器渲染和服务端渲染

diff 算法

重新渲染

留个坑在这,过段时间来补

8. 路由

8.1 前端路由

路由也蛮有意思的,写“初识”的时候提到过,前端也是可以处理路由的,Vue 和 React 中的路由也都是基于前端路由封装的。

从后端路由记起吧!每次浏览器向服务器发送 HTTP 请求,服务器就会根据相应的 URL 执行对应的函数,并将返回值发送给前端。特别是前期只有服务端渲染的时候,服务器的压力可想而知!而后就有了前端路由,改变了浏览器地址栏中的 URL 而不向服务器发送请求,拦下来自己处理,有两种形式

8.1.1 Hash

这个最开始其实是 HTML 种 <a> 标签的锚点功能,,通过 id 获取 DOM 元素,再赋值给 <a> 标签的 href 属性,这样点击该 <a> 标签就可知直接跳到哪个元素那里去,有些长屏滚动就可以用这个回调底部或者顶部哦!

<a href="#srtian">srtian</a>

这样子的超链接不会导致浏览器发送请求,它的 URL 一般是这样的,# 号后面的就叫哈希值

http://www.xxx.com/#/srtian

8.1.2 HTML5 history

HTML5 新增了两个比较重要的 API

history.pushState(data[,title][,url]);//向历史记录中追加一条记录
history.replaceState(data[,title][,url]);//替换当前页在历史记录中的信息。

这个就有点像那个骗术hahaha,浏览器管理地址是通过栈结构,浏览器访问一个页面的时候,当前地址的状态信息就会被压入栈中,调用上边的方法后,浏览器就会理解为自己修改了 URL 并跳转了页面,这就实现了我们想要的结果——修改 URL 而不发送请求

image-20210820205642537.png

push是将记录放到栈顶,replace是将栈顶元素替换,默认是push,加入我们给message下的消息123开启按照截图所示:先点击about,再点news,再点message,再点消息1,这个时候点回退,会发现回到了news,而不是message,因为message被替换后就消失了,找不到了

8.2 Vue Router

其实基础的使用起来是很快的,使用 <router-view> 标签占位,然后通过 <router-link to="/foo"> 标签跳转路由

当然使用之前,必须对路由进行配置,将导出的对象,再新建 Vue 对象的时候,放进去就好了

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
​
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/record',
      name: 'Record',
      component: Record
    },
  ]
})

vue-router 默认 hash 模式,如果你觉得它导致 URL 变得丑丑的话,可以配置使用 history

const router = new VueRouter({
  mode: 'history',
  routes//上边定义的对象
})

8.3 React Router

React Router 基本的思想和上边也是差不多的,通过 <Route> 占位,但是他的配置都是写在标签里面的,URL匹配到了哪个,就显示哪个组件,component 就是组件内容,然后通过 <Link to="/"> 进行路由跳转,exact 是精准匹配的意思

      <BrowserRouter>
        <Route path="/" exact component={Home}/>
        <Route path="/login" exact component={Login}/>
      </BrowserRouter>

想要使用哈希路由 将上边的 <BrowserRouter> 改成 <HashRouter> 就好了

路由还有很多高级用法,可以去看看官方文档哦!

8.4 路由传参

这篇文章我是打算写在掘金上边的,就拿掘金举例好了,仔细观察就会发现,一篇博客的地址栏如下

https://juejin.cn/post/6983868344222875656

每篇博客的 URL都只有后面这串数字不同,每篇博客很显然是使用的同一个模板,同一种组件,未展开时也是同一种组件,实现点击同一种组件,但是各个跳转都是不同的,将那串数字传递过去,就可以使用路由传参的方式。

分别写几种之前有学过一些的吧

8.4.1 React

:下面的几种都是使用了 props

params 参数

  1. 路由连接(携带参数):<Link to='demo/test/tom/18'>详情</Link>
  2. 注册路由(声明参数):<Route path='/demo/test/:name/:age' component={Test}/>
  3. 在 Test 组件内接收参数:const {id,title} = this.props.match.params

seacrch 参数

  1. 路由连接(携带参数):<Link to='demo/test/?name=tom&age=18'>详情</Link>

  2. 注册路由(无需声明参数):<Route path='/demo/test' component={Test}/>

  3. 在 Test 组件内接收参数:`const {search} = this.props.loaction

    备注:获取到的search是urlencoded编码字符串,需要借助querystring(react脚手架自带了,引入使用就好)解析

state 参数

  1. 路由连接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:'18'}}}}>详情</Link>
  2. 注册路由(无需声明参数):<Route path='/demo/test' component={Test}/>
  3. 在 Test 组件内接收参数:`const {id,title} = this.props.location.state

这个可以有一个拓展:

使用 state 传参的话,传递的参数不会在 URL 显示出来,如果你是用的是 BrowserRoute 刷新页面数据也不会丢失,因为调用浏览器的 history 对象嘛! locationhistory 的一个属性。但是使用 <HashRouter> 的话,刷新页面就会丢失哦!

8.4.2 Vue

Vue 中使用 <router-link> 的话,也差不多,就写 Vue 就用编程式导航来写吧!编程式导航其实就用 DOM API 来操纵路由,前面有提到过的 history.pushStatehistory.replaceState

Vue 和 React 都对其进行了封装

 metheds: {//Vue
    toDetails() {
      // 字符串路径
      this.$router.push('/details/001')
  }
his.props.history.push()//React默认路由跳转
his.props.history.replace()//替代式路由跳转

params: (伪代码,正式用的时候,要写在不同的文件里面的)

//注册
const routes = [
  // 动态段以冒号开始
  { path: 'details/:id', name: "details", component: Details },
]
//2连接
this.$router.push('/details/001')
//3获取
//const {id} = this.$route.params

query:

//注册
const routes = [
  // 动态段以冒号开始
  { path: 'details/', name: "details", component: Details },
]
//连接
this.$router.push('/details/001?kind=car')
//3获取
//const {id} = this.$route.query

hash

//注册
const routes = [
  // 动态段以冒号开始
  { path: 'details/', name: "details", component: Details },
]
//连接
this.$router.push('/details/001#car')
//3获取,这个还得自己裁剪一下呢哈哈哈
//const id = this.$route.hash.slice(1)

props

//1注册
const routes = [{ path: '/user/:id', component: User, props: true }]
//2连接
this.$router.push('/details/001')
//获取,从props获取
props: ['id']

好像使用状态管理器也可以哦!两个组件共享一个 id 嘛。

以上的内容不是针对面试写的,可以看到写的都是一些基础的,也没有很多概念的东西,感觉完全就是想到哪写到哪,但写完基本也把我在 Vue 和 React 对比上知道的掏空了,应该更加适合的是我自己以及学过一些 Vue 和 React 的好兄弟!

参考:

如何认识前后端分离开发中的 MVVM 模式

聊聊 CommonJS 与 ES6 Module 的区别和使用

关于Vue和React的一些对比及个人思考(上)