为什么学习前端框架

记得我还是一个小白的时候,在学习了 “三剑客” 之后,我接触的第一个框架是 vue,我清晰的记得当时的手足无措 😭。
我当时之所以学习框架,原因很简单,因为我的学长告诉我接下来学框架就行。
所以为什么学?
好像我当时能想到的唯一答案是,因为他们都在学。或者说是因为企业要用。
其实我当时并没有意识去思考去思考 “为什么学习前端框架” 这个问题,现在看来,也正是因为当初没有花精力想清楚这件事,才让我在学习框架的时候迷茫了好一段时间。
倘若我先思考清楚这件事,再学习框架的话,估计会游刃有余许多。
而这也是我写这篇文章的目的,一方面是总结自己的一些思考,另一方面是希望帮助到有这个需求的朋友。
前端框架
前端框架

脱离了框架的开发模式—过程驱动开发

要搞清楚为什么学习框架,需要先思考没有框架时,开发是怎样的。
刚开始开发一个网页, js, html, css 就足够了。并且没有任何不适感,反而是忽然转到了框架,觉得用起来怎么这么麻烦。
这是因为,以前写的页面,功能很少,数据甚至都是写死在 html 里的,在没有复杂需求的情况下,使用框架反而会增加开发的复杂度。有种用大炮轰蚂蚁的即视感。我们安装好大炮,换好弹药,调整方向,不如直接一脚来的轻松。
直到我们面对的不是蚂蚁,而是一个巨大的怪兽,emm, 这时候必须要扛起大炮了,否则就是被怪兽吃掉。
在框架盛行之前,有一把神兵叫做 Jquery,我几乎没有使用过 Jquery,因为他被淘汰了,现在回过头来看,淘汰他的是因为它依旧保持着传统的开发模式。我们把哪种开发模式称之为 — 过程驱动开发
在我的理解里,如果框架是一个大炮,那么 Jquery 是一把上好的宝剑,冷兵器时代它绝对牛逼。
这里所谓的冷兵器时代,就是我想说的过程驱动开发的时代。
所谓的过程驱动开发,指的是我们需要把完整的过程描述出来才能实现目的,比如我们需要实现这样一个功能:点击按钮,让显示的数字加 1。
这是个简单的功能,可是在冷兵器时代做起来也不容是那么容易
<div id="number">0</div>
<button>加1</button>

<script>
  const number = document.querySelector("#number");
  const button = document.querySelector("button");

  button.addEventListener("click", () => {
    const current = parseInt(number.innerText);
    number.innerText = current + 1;
  });
</script>
这样一个简单的需求,我们至少要经过下面几个步骤
  • 获取 DOM 元素
  • 添加事件监听
  • 修改 DOM 元素的值
而为什么说 Jquery 是一把宝剑呢,因为它可以简化我们上述的操作。
但不过是少写了些代码而已,思考的角度是没有发生变化的。
我们需要思考,要获取哪个 DOM,这个 DOM 可能被什么修改,还要再显示的去设置它里面的内容。
就像我们想喝一杯水,我们得告诉他,右拐,直走,拿起水杯,拿起水壶,倾斜水壶,倒满后放下…
我们需要显示的调用浏览器的 DOM API,来操作 DOM
开发者 ---> 直接调用宿主环境的 API ---> 更新 UI
也许只是这种简单的需求我们还应付的过来。
当项目庞大起来,数据多起来,更改的方式复杂起来,那么我们很容易崩溃掉,先不说代码的可维护性,单单是思考的角度,就已经让人头大了。如果再考虑上性能的话,那将会是一场灾难。
我希望,我想喝水的时候,我只需要来一句,我口渴了,然后就有人给我递上一杯水。倘若我要求高点,他甚至会在内部优化出让我喝到水的最快途径…

状态驱动的开发模式

在不使用框架时,我们使用的开发模式时基于 “过程” 的。
而在框架的帮助下,我们可以使用 “状态” 来驱动开发。从冷兵器时代过渡到了 morden js framework 时代。
所以我们要提到非常关键的一个字眼 状态同步
先来说下什么是状态,不知道你是否听说过这样一句话
“一切的程序本质上是一个状态机”
听着好像很高大上,但是其实很简单,所谓的状态(State), 其实就是程序中的变量,而我们所做的一切事情,就是声明,修改,读取这些变量。
ok, 让我们重新看上面的需求,就是那个点击按钮 +1 的需求。
在这里,这个数字我们就可以看成一个状态
const [number, setNumber] = useState(0);

return (
  <div>
    <button onClick={() => setNumber(number + 1)}>1</button>
  </div>
);

注意,这是一段 React 代码切片,不能直接运行

看到了吗,我们做的事情:
  • 声明一个状态
  • 点击按钮修改这个状态
视图将会自动更新,这就是所谓的 “状态同步”
状态同步是由框架内部为我们做的,不同的框架实现的原理不同,比如 vue 是基于依赖收集的,而 React 基于组件的整体重新渲染。
(这些东西涉及到框架的内部实现原理,这里就不展开了)
可以这样理解,在传统的过程驱动开发的模式下,状态同步这件事是我们手动去做的,我们需要手动的使用宿主环境 API(DOM API) 去更新视图。
而使用了框架后,我们不再需要手动去同步状态,框架会帮我们做这件事。
我们的关注点就从 “如何同步状态” 转变为了 “如何维护状态”,这是一个非常大的转变。
这种开发模式,我们称之为 状态驱动开发模式

实际上, 在框架内部状态同步是非常复杂的事情,但是作为工具的使用者,我们不需要关心这些,但如果你想深度使用某个框架,建议你去了解一下它的内部实现原理。

性能优化与虚拟 DOM

框架所做的事情当然不只是状态同步,它还会帮我们做很多事情,比如性能优化。
框架内部具体做了哪些性能优化?不同的框架是不一样的,这里不展开说。
有一种常见的手段是虚拟 DOM。
所谓的虚拟 DOM 其实是一种数据结构,他是内存中的一个轻量对象,用来描述真实 DOM,框架内部操作这些虚拟 DOM 会比操作真实 DOM 要快很多。更多的细节就不展开了。毕竟这篇文章不是讲解某个框架的原理。
这里之所以要提到虚拟 DOM,是想引出 JSX模板语法 这两种个词。
首先,JSX 和 模版语法 是两种不同声明虚拟 DOM 的风格。
JSX 是由 React 提出的,语法类似于在 JS 中直接把 HTML 当成一个字面量来使用。
而模板语法则在 Vue 中使用的比较多,它是一种声明式的模板语法,类似于 HTML。
但他俩的本质实际上都是声明虚拟 DOM,只是开发的风格不同。相对而言,模板语法更适合新手,这也是 Vue 更容易上手的原因。
但 JSX 更加灵活,更加接近于原生的 JS 语法,这也是 React 非常受欢迎的原因之一。

组件化的落地

框架的另一个非常重要的功能就是提供了前端组件化的开发模式,这点就不展开说了,因为这个东西,你有开发经验,不用说也懂,你没开发经验,说了也收获甚微。

生态带来的优势

喜欢某个框架的开发者们共同努力开发一系列简化我们开发的工具,我们把些东西称之为 框架的生态
一个前端框架的生态大概有哪些东西组成呢?
  • 组件库
  • 集成方案
  • 一些工具
  • 路由
  • 状态管理

一个好的前端框架意味着什么

  • 优秀的开发体验 (the most important thing for me
  • 优秀的性能
  • 庞大的生态 (方便我偷懒 😊
  • 优秀的文档(这很重要!叉腰

使用框架一定好吗?

我小学的开始,我的老师就告诉我一个做判断题的套路,只要看到 “一定” 这个关键字,那么大概率就是错的。
就像我前面提到的场景一样,之所以使用框架,核心目的是应对复杂的业务场景,处理大量的状态更新。
如果你的需求只是踩死一只苍蝇,没有必要费那么大周折抬起一颗大炮,小心炸到自己。
所以是否使用框架?这个问题并不重要,也没什么意义,思考这个问题,我更建议你思考下面两个问题:
  • 项目的需求是什么
  • 框架为我们带来什么
想明白这俩问题,你就知道该怎么做了。

参考资料:

End.