vlambda博客
学习文章列表

前端小白该怎么选择 Web 框架 React ?Vue?

前端小白该怎么选择 Web 框架 React ?Vue?

全文目录为:

  • 三大前端框架 React Vue Angular
  • SPA 单页应用
  • VirtualDom
  • React?Vue?
  • 通过例子看到底谁好
  • 总结
  • 小建议


老板们可以选择想看的直接往下拉

在那远古时期,人们对于前端的认识一直停留在三大件上(HTML JavaScript CSS)。
前端小白该怎么选择 Web 框架 React ?Vue?
在那个时候,流传着一句家喻户晓的童谣:
得 DreamWeaver 者得天下。
前端小白该怎么选择 Web 框架 React ?Vue?
好的上面那段是我瞎编的 噗
对前端发展感兴趣的童鞋,可以 🙋‍♂️
有机会可以专门讲一下整个前端的发展历史


三大前端框架 React Vue Angular

前端小白该怎么选择 Web 框架 React ?Vue?
应该没有人没听过 React 和 Vue 吧?(没听过的拖出去毒打)
有人弱弱的问那 Angular 呢?
好的,我没用过,下一个。
前端小白该怎么选择 Web 框架 React ?Vue?
在讲这两个很火的前端框架前,我们还是要巩固一下基础知识的,毕竟(编不下去了)

「由于是小白向 下文的一些概念我会用通俗易懂的方式去解释 大佬别喷」
前端小白该怎么选择 Web 框架 React ?Vue?

SPA 单页面应用

SPA (Single Page Application)即单页面应用。这里很多童鞋就问了,啥是单页面应用啊?网页不是很多很多个的吗?就一个页面不是会很复杂吗?一个页面那么多代码....
前端小白该怎么选择 Web 框架 React ?Vue?
小朋友们稍安勿躁!
前端小白该怎么选择 Web 框架 React ?Vue?

这就要从远古时期说起了,
以前我们写 Web 都是离不开 html 的(不知道是什么拖出去),
无非就是 html 里面写标签、CSS、JavaScript

当然可以把样式和 js 抽象成一个个文件然后在 html 里面引入也是 ok 的。
这种方式当我们要切换页面的时候自然而然的就需要跳转不同的 HTML, 因为不同的 HTML 文件负责不一样的视图。

当引入了 SPA 之后,它将所有的活动局限于一个 Web 页面中,仅在该 Web 页面初始化时加载相应的 HTML、JavaScript、CSS。

简单来说就是 SPA 只有一个 HTML 文件,这个 HTML 文件里面会引用若干个 JS 文件,这些 JS 文件会根据我们编写的逻辑去帮我们去操作 DOM,从而实现一系列的页面展示、交互操作。

在这里有人就问了,那本质不还是操作 DOM 吗,和自己去操作有什么区别?这里的 DOM 是 SPA 框架实现的 VirtualDom,他不是真实的 DOM。当然这里的 Js 文件也不是由我们直接去编写的,而是我们通过框架或者自己去写完相应的逻辑后,通过 webpack 打包生成的 JS 文件,在体积和内容上和我们自己写的都是有区别的。

可能大部分童鞋看完后还是感觉难以理解 噗 我举个 🌰
前端小白该怎么选择 Web 框架 React ?Vue?

  • 当我们访问非 SPA 模式的网页的时候
  • SPA 模式网页


VirtualDom

刚刚上面提到了 VirtualDom(下文简称 VD),那到底什么是 VD 呢?
大家都知道操作 DOM 是很慢的,这里涉及到浏览器的渲染和 JS 执行是会相互阻塞的,具体原因大家可以去查阅下  **浏览器的渲染原理  **相关的知识。
但是操作 JS 却是很快的,所以就出现了用 JS 去模拟 DOM

const domTree = {
 tag'div',
  props: {
   class'demo'
  },
  children: [
    {
      tag'span',
      props: {},
      children: ["1"]
    },
    {
      tag'span',
      props: {},
      children: ["2"]
    },
  ]
}

对应的 DOM 就是

<div class="demo">
  <span>1</span>
 <span>2</span>
</div>

所以 VD 的初步思路就出来了,能不能通过类似这样子拥有 DOM 结构的 JS 对象来渲染 DOM 呢?
显然是可以的,但是这样子貌似也没什么特色呀。
难点就是「怎么去判断两个新旧 JS 对象的最小差异并且实现更新局部 DOM。」

平时写网页的时候我们就会发现,标签总是可以不停的嵌套的,没有数量的限制,除了特定的标签外,其他标签想怎么放就怎么放,所以 DOM 结构可以看成是一个多叉树的结构,如果要对比两颗树的不同的话,时间复杂度会是 O(n^3),这个是肯定不能接受的。

这时候,就出现了大名鼎鼎的 Diff 算法,在 React 里面,实现了一个 O(n)的复杂度算法来对比不同。


DIFF 算法

「算法的具体思想:」

  • 只对比同层的节点,不去跨层对比。
  • 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构
  • 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分

「具体步骤:」

  • TreeDiff
  • ComponentDiff
  • ElementDiff


当通过 DIFF 比较后得出需要更新的部分的时候就可以去应用到真实的 Dom 了


React?Vue?

前端小白该怎么选择 Web 框架 React ?Vue?

因为切图仔的技术栈是以 React 为主的,对于 Vue 只是停留在 Demo 阶段,所以下面是我的我个人感觉,真的只是个人感觉(说得不对的不要打我)


React


函数式

React 整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入去改变组件的数据,同时数据的流向是单向的。

JSX 语法

React 通过 js 来生成 html,所以出现了 JSX,

import React from 'react';
import "../account.css";

const AccountView = props => (
 <div className="demo">
   <div>用户</div>
   <button>登录</button>
  </div>

);

export default AccountView;


类式的写法

在 React 里面所有东西都是组件所以就出现了一种类的概念(但现在随着 hooks 的推出,更多的推崇函数式组件),

import React from 'react';
import ProptTypes from 'prop-types';

class Account extends React.Component {
 static propsTypes = {
  text: PropTypes.string,
 }
 static defaultProps = {
   text'用户',
  }
 state = {
  text: props.text
 }

 handleInputChange = (e) => {
  this.setState({
   text: event.target.value,
  })
 }
 render() {
  return (
   <div>
        <input
         onChange={this.handleInputChange}
          value={this.state.text}
        />

   </div>
  )
 }
}


Vue

听说学校的项目组很多都是 Vue,唉 切图仔却没有接触过,瑟瑟发抖。

响应式

Vue 的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立 Watcher 来监听,当属性变化的时候,响应式的更新对应的虚拟 dom。

模版语法

<template>
  <div class="demo">
    <div>{{name}}</div>
    <button>登录</button>
  </div>
</template>

<script>
  module.exports = {
   datafunction ({
      return {
       name'用户'
      }
    }
  }
</script>

<style>
  .demo {
   font-size20px;
  }
</style>


声明式写法

Vue 采用的是声明式的写法,通过传入各种的 options,api 和参数很多。

var todoItem = Vue.extend({
 template: `<div> {{name}} </div>`,
 props: {
  text: {
   type: String,
   default: ''
  }
 }
})


到底谁好???

其实 React 和 Vue 并没有说谁好谁坏,更重要的是你用哪个更顺手,或者说根据你的业务需求去进行正确的技术选型。

那对于小白来说去选择哪个呢?

下面用两种框架创建同一个 APP
你看一下下面两种风格你比较喜欢哪一种 你就知道你应该选什么了。

创建 APP

「默认左边是 Vue 右边是 React」
前端小白该怎么选择 Web 框架 React ?Vue?
两个应用程序的 CSS 代码几乎一样,但这些代码的位置存在差异。考虑到这一点,我们来看看这两个应用程序的文件结构: 
前端小白该怎么选择 Web 框架 React ?Vue?
你会发现它们的结构几乎完全相同。

唯一的区别在于 React App 拥有三个 CSS 文件,而 Vue App 中没有 CSS 文件。这是因为 React 的 create-react-app 组件需要一个附带文件来保存其样式,而 Vue CLI 采用全包方法,其样式在实际组件文件中声明。

两种不同的策略得到的结果是一样的,相信开发者很快能够掌握这两种不同的策略。开发者可以根据自己的偏好做出选择,你会听到开发社区关于如何构建 CSS 的大量讨论。以上,我们遵循两个 CLI 列出了代码结构。

在我们进一步讨论之前,先快速看一下典型的 Vue 和 React 组件的外观:
前端小白该怎么选择 Web 框架 React ?Vue?

修改数据

首先,我们需要明白“修改数据”的意思是什么。
它听起来有些学术,但实际上很简单,就是把我们已经存储好的数据进行更改。
比如,如果我们想把一个人的名字变量从“Jhon”改为“Mark”,我们就需要执行“修改数据”的操作。
在这一点上,React 和 Vue 的处理方式有所区别。

  • Vue 本质上会创建一个数据对象,其中的数据可以自由更改
  • React 则创建一个状态对象,更改数据需要一些额外的操作。React 之所以需要额外的操作有着自己的理由,稍后我会深入介绍。


在此之前,我们先看看 Vue 中的数据对象和 React 中的状态对象: 

Vue 数据对象
前端小白该怎么选择 Web 框架 React ?Vue?

React 数据对象
前端小白该怎么选择 Web 框架 React ?Vue?

从图中可以看出,我们传入了相同的数据,但它们的标记方法不同。
因此,将初始数据传递到组件的方式非常相似。
但正如我们提到的那样,在两个框架中更改数据的方式有所不同。
假设我们有一个名为 name: ‘Sunil’ 的数据元素。

在 Vue 中,我们通过调用 this.name 来引用它。
我们也可以通过调用 this.name ='John' 来更新它。这样一来,名字就被成功改为了 “Jhon”。

在 React 中,我们通过调用 this.state.name 来引用同一段数据。
现在关键的区别在于,我们不能简单地写成 this.state.name ='John',因为 React 有限制机制,它会阻止这种简单的修改方式。在 React 中,我们需要这样写:this.setState({name:'John'})。

虽然这基本上与我们在 Vue 中实现的结果一样,但是 React 的操作更为繁琐,那是因为 Vue 在每次更新数据时默认组合了自己的 setState 版本。
「简单来说就是,React 需要 setState,然后更新其内部数据,而对于 Vue 来说,当你更新数据对象的值时它就默认了你的更改意图。」


添加代办


React 实现

createNewToDoItem = () => {
    this.setState( ({ list, todo }) => ({
      list: [
          ...list,
        {
          todo
        }
      ],
      todo''
    })
  );
};

在 React 中,我们的输入字段有一个名为  value  的属性。
这个 value 通过使用几个函数自动更新,这些函数绑定在一起以创建双向绑定。
我们通过在输入字段上附加一个  onChange 事件监听器来创建这种形式的双向绑定。看看代码,一探究竟:

<input type="text"
  value={this.state.todo}
  onChange={this.handleInput}
/>

只要输入字段的值发生更改,handleInput 函数就会运行。
它通过将状态对象设置为输入字段中的任何内容来更新状态对象内的 todo。

handleInput 函数如下:

handleInput = e => {
  this.setState({
    todo: e.target.value
  });
};

现在,只要用户按下页面上的 + 按钮添加新项目,createNewToDoItem 函数就会运行 this.setState 并向其传递一个函数。
该函数有两个参数,第一个是来自状态对象的整个列表数组,第二个是由 handleInput 函数更新的 todo。
然后该函数返回一个新对象,该对象包含之前的整个列表,并在其末尾添加 todo。
整个列表是通过使用扩展运算符添加的。
最后,我们将 todo 设置为空字符串,它会自动更新输入字段中的 value。

Vue 实现

createNewToDoItem() {
    this.list.push(
        {
            'todo'this.todo
        }
    );
    this.todo = '';
}

在 Vue 中,我们的输入字段中有一个名为  v-model  的句柄。
这实现了**双向绑定。

输入字段代码如下:

<input type="text" v-model="todo"/>

V-Model 将输入字段的内容绑定到名为 toDoItem 的数据对象的键(key)上。
当页面加载时,我们将 toDoItem 设置为空字符串,比如:todo:' '。
如果已经存在数据,例如 todo:'添加文本处',输入字段将加载添加文本处的输入内容。

无论如何,将其作为空字符串,我们在输入字段中键入的任何文本都会绑定到  todo。
这实际上是双向绑定(输入字段可以更新数据对象,数据对象可以更新输入字段)。

因此,回顾前面的  createNewToDoItem()  代码块,我们将 todo 的内容存放到列表数组中 ,然后将 todo 改为空字符串。


传递数据到子组件


React 实现

在 React 中,我们将 props 传递到子组件的创建处。比如:

<ToDoItem key={key} item={todo} />

此处我们向 ToDoItem  组件传递了两个 prop。
之后,我们可以在子组件中通过 this.props 引用它们。
因此,想要访问 item.todo prop,我们只需调用 this.props.item 。


Vue 实现

在 Vue 中,我们将 props 传递到子组件创建处的方式如下:

<ToDoItem
 v-for="todo in list"
  :todo="todo"
  :key="todo.id"
 @delete="onDeleteItem"
/>


我们将它们传递给子组件中的 props 数组,如:props:['id','todo']。
然后可以在子组件中通过名字引用它们。

看完了这么多 应该能做出选择了吧!
小孩子才做选择 我全都要
前端小白该怎么选择 Web 框架 React ?Vue?

当然可以全都要,最好是两种都是试试体验下然后才去选择

路人甲:Angular 呢?? 
前端小白该怎么选择 Web 框架 React ?Vue?
对不起 抬走 下一个


总结

  • 在生态上来说,两者其实没多大的差距,但是使用 React 的用户是远多于 Vue 的。
  • Vue 的定位就是尽可能的降低前端开发的门槛,即使你是从 HTML 转来的,使用 Vue 也能很快的上手,
  • React 更多的时候需要用户去接受它的概念和思想,了解 React 的组件思想和数据更新方式,如果你是从 HTML 模式转向 React 的话,投入的学习成本要比 Vue 高。
  • 「直接尝试 React 准没错」


小建议