为什么要使用前端框架

一、框架为何会存在?

我们已经讨论了因为什么契机而创造了框架,但我们仍不知道为什么开发者认为有必要创造它。要知道这个问题的答案,我们首先需要来看一看软件开发中的各种挑战。

设想一个很常见的软件:一个待办事项清单创建器,在接下来的章节中我们会使用各种框架来实现它。这个应用应让用户可以完成诸如呈现任务列表、添加和删除任务等操作,且在完成这些操作的同时能可靠地跟踪和更新应用程序的底层数据。在软件开发中,这种底层数据被称为状态(state)。

上述每个目标理论上都很简单。我们可以遍历数据来列出清单,添加一个对象来创建新任务,使用标识符来查找、编辑和删除任务。需要注意的是,用户都是在浏览器中使用应用的这些功能,然而这就引出了一些问题: 每当我们修改应用的数据时,我们都需要更新用户界面以使其匹配。

我们可以通过待办事项清单应用的一个功能来展现这个问题的难点:呈现任务清单。

二、冗长的 DOM 操作

构建 HTML 元素并适时在浏览器中呈现它们需要大量的 JavaScript 代码。假设我们的状态——底层数据,是一个结构如下的对象数组:

const state = [
  {
    id: 'todo-0',
    name: 'Learn some frameworks!'
  }
]

如何向用户展示其中一个任务?我们想将每个任务表示为一个列表项——无序列表元素(<ul>)中的一个 HTML<li> 元素。我们该如何实现?可以像下面这样:

function buildTodoItemEl(id, name) {
  const item = document.createElement('li');
  const span = document.createElement('span');
  const textContent = document.createTextNode(name);

  span.appendChild(textContent)

  item.id = id;
  item.appendChild(span);
  item.appendChild(buildDeleteButtonEl(id));

  return item;
}

在这里,我们使用 document.createElement() 方法来创建我们的 <li> 元素,以及另外几行代码来创建它需要的属性和子元素。

该代码片段的第十行引用了另一个构建函数:buildDeleteButtonEl()。它遵循与我们用来构建列表项元素时类似的模式:

function buildDeleteButtonEl(id) {
  const button = document.createElement('button');
  const textContent = document.createTextNode('Delete');

  button.setAttribute('type', 'button');
  button.appendChild(textContent);

  return button;
}

这个按钮只有当我们决定实现删除功能时,才会生效。要在页面上渲染我们的列表项,代码看起来可能是这样的:

function renderTodoList() {
  const frag = document.createDocumentFragment();
  state.tasks.forEach(task => {
    const item = buildTodoItemEl(task.id, task.name);
    frag.appendChild(item);
  });

  while (todoListEl.firstChild) {
    todoListEl.removeChild(todoListEl.firstChild);
  }
  todoListEl.appendChild(frag);
}

我们现在已经有超过 30 行服务于用户界面的代码——作用于在 DOM 中渲染某些内容的步骤——并且我们还没有为列表添加样式呢!

如本例所示,直接使用 DOM,我们需要了解有关 DOM 工作原理的许多内容:如何创建元素;如何改变它们的属性;如何将元素放在一起;如何让它们出现在页面上。这些代码实际上都没有处理用户交互,或添加删除之类任务。如果我们添加这些功能,我们必须记得在正确的时间以正确的方式更新我们的用户界面。

JavaScript 框架的出现是为了使这些工作变得更容易——它们的存在是为了提供更好的开发体验。它们没有给 JavaScript 带来新的功能;但它们使你可以更轻松地使用 JavaScript 来构建现代的 web。

三、另一种打造用户界面的方式

JavaScript 框架都提供了一种更具以声明性的方式地编写用户界面的方法。也就是说,它们允许你编写描述用户界面的代码,然后框架将你编写的描述用户界面的代码通过在幕后的 DOM 显现出来。

原生 JavaScript 使用循环来构建新 DOM 元素的方法乍一看很难理解。相对地,让我们看一看使用 Vue 来呈现任务清单的方式:

<ul>
  <li v-for="task in tasks" v-bind:key="task.id">
    <span>{{task.name}}</span>
    <button type="button">Delete</button>
  </li>
</ul>

你没看错。以上用了 JavaScript 框架的代码用了 6 行就实现了刚刚需要 32 行代码才能实现的功能。如果你对这里的大括号和 v- 属性不熟悉,没关系;你会在后面的模块中学习到 Vue 特有的语法。这里要指出的是,这段 Vue 代码看起来很像它所代表的用户界面,而原生 JavaScript 代码则不然。

幸亏有了 Vue,让我们不必编写自己的函数来构建用户界面;我们仅仅需要向 Vue 描述每个项目应该是什么样子,然后 Vue 会以很好的、高效的方式帮我们处理好。因此熟悉 Vue 的开发者可以轻松的加入我们的项目,快速地搞清楚项目是如何运作的。不仅仅是 Vue:使用其它框架也可以提高团队和个人的效率。

其实在原生 JavaScript 中也可以做与此类似的事情。模板字符串使得编写表示最终元素外观的 HTML 字符串变得容易起来。对于像创建上文示例的待办事项清单那样简单的应用来说,这可能是一种有用的方法,但它对于管理数千条数据记录,且可以在用户界面上渲染许多独特元素的大型应用程序来说,是难以维护的。

四、框架提供给我们的其他功能

让我们看看使用框架还有哪些好处。正如我们之前提到的,虽然框架的优秀特性在原生 JavaScript 中也可以类似地实现,但是使用框架可以消除必须自己解决这些问题的认知负担。

1、工具

由于此模块中的每个框架都有一个庞大而活跃的社区,因此每个框架的体系都提供了工具来改善开发体验。这些工具让诸如添加测试(确保你的应用表现应有的行为)和 linting(确保你的代码没有错误且排版统一)变得更加容易。

2、组件化

大多数框架都鼓励开发者将其用户界面的不同部分抽象为组件(components)——可维护、可重用且可以相互通信的代码块。与给定组件相关的所有代码都可以存在于一个文件(或几个特定文件)中,因此身为开发者的你就可以轻松地知道去哪里修改目标组件。在原生 JavaScript 中,你就必须花时间创建自己的一套高效、可扩展的编码约定来实现这一点。如果让许多 JavaScript 开发者使用他们自己的设备,最终可能会导致与用户界面某个部分相关的所有代码分布在一个文件中——或者完全分布在另一个文件中。

3、路由

Web 最重要的特点是它允许用户从一个页面导航到另一个页面——毕竟,它是一个相互链接的文档网络。当你点击网站上的链接时,你的浏览器会与目标服务器通信,获取新内容后将其显示给你。当浏览器这样做时,地址栏中的 URL 会发生变化。你可以记下来这个新 URL 并稍后返回该页面——或者把这个 URL 分享给其他人,以便他们轻松找到相同的页面。你的浏览器会记住你的导航历史记录,并允许你来回导航(译者注:其实就是浏览器的前进后退功能)。这被称作服务端路由

现代 Web 应用程序通常不会获取和渲染新的 HTML 文件——它们加载单个 HTML shell,并不断更新其中的 DOM 而无需将用户导航到 Web 上的新地址。(这被称为单页应用程序(single page app) 或 SPA)。每个新的伪网页通常称为一个 view,且在默认情况下,不会做任何路由。

当 SPA 足够复杂并呈现足够多的独特视图时,将路由功能引入你的应用程序非常重要。人们习惯于能够链接到应用程序中的特定页面,在他们的浏览器中前进和后退等等,当这些标准的 Web 功能被破坏时,他们的体验会受到影响。当客户端应用程序以这种方式处理路由时,它被恰当地称为客户端路由

可以使用 JavaScript 和浏览器的原生功能来实现路由功能,但是流行的、活跃开发的框架具有配套库,使路由功能在开发过程中更直观。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

种麦南山下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值