0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Web框架的替代方案分享(下)

jf_78858299 来源: 前端之巅 作者:Noam Rosenthal 2023-03-20 14:51 次阅读

此 HTML 包括以下内容:

  • 我们有一个 main 表单,其中有所有的全局输入和按钮,还有一个新的表单用于创建一个新任务。请注意,我们使用 form 属性将元素与表单联系起来,以避免表单中的元素嵌套。
  • template 元素代表一个列表项,它的根元素是另一个表单,代表与特定任务相关的互动数据。当任务被添加时,这个表单将通过克隆模板的内容而被重复。
  • 隐藏的输入表示不直接显示的数据,但用于样式设计和选择。

注意这个 DOM 是如何简洁的。它没有在其元素中散布类。它包括应用程序所需的所有元素,以合理的层次结构排列。多亏了隐藏的输入元素,你已经可以很好地感觉到以后文档中可能会有什么变化。

这个 HTML 不知道它将如何被样式化,也不知道它到底与什么数据绑定。让 CSS 和 JavaScript 为你的 HTML 工作,而不是让你的 HTML 为某个特定的造型机制工作。这将使你在改变设计时变得更加容易。

最小控制器 JavaScrip

现在我们在 CSS 中已经有了大部分的反应性,在模型中也有了列表处理,剩下的就是控制器的代码了,也就是把所有的东西固定在一起的“胶带”。在这个小程序中,控制器的 JavaScript 大约是 40 行。

下面是一个版本,每个部分都有解释:

import TaskListModel from './model.js';


const model = new TaskListModel(new class {

上面,我们创建了一个新模型。

onAdd(key, value) {
   const newItem = document.querySelector('.todo-list template').content.cloneNode(true).firstElementChild;
   newItem.name = `task-${key}`;
   const save = () => model.updateTask(key,  Object.fromEntries(new FormData(newItem)));
   newItem.elements.completed.addEventListener('change', save);
   newItem.addEventListener('submit', save);
   newItem.elements.title.addEventListener('dblclick', ({target}) => target.removeAttribute('readonly'));
   newItem.elements.title.addEventListener('blur', ({target}) => target.setAttribute('readonly', ''));
   newItem.elements.destroy.addEventListener('click', () => model.deleteTask(key));
   this.onUpdate(key, value, newItem);
   document.querySelector('.todo-list').appendChild(newItem);
}

当一个项目被添加到模型中,我们在用 UI 中创建其相应的列表项。

在上面的代码段中,我们克隆了项目 template 的内容,为一个特定的项目分配了事件监听器,并将新的项目添加到列表中。

注意,这个函数,以及 onUpdate、onRemove 和 onCountChange,都是要从模型中调用的回调。

onUpdate(key, {title, completed}, form = document.forms[`task-${key}`]) {
   form.elements.completed.checked = !!completed;
   form.elements.title.value = title;
   form.elements.title.blur();
}

当一个项目被更新时,我们设置它的 completed 和 title 值,然后 blur(退出编辑模式)。

onRemove(key) { document.forms[`task-${key}`].remove(); }

当从模型中移除一个项时,我们将从视图中移除其对应的列表项。

onCountChange({active, completed}) {
   document.forms.main.elements.completedCount.value = completed;
   document.forms.main.elements.toggleAll.checked = active === 0;
   document.forms.main.elements.totalCount.value = active + completed;
   document.forms.main.elements.activeCount.innerHTML = `${active} item${active === 1 ? '' : 's'} left`;
}

在上面的代码中,当完成的或活动的项目数量发生变化时,我们设置适当的输入来触发 CSS 反应,并格式化显示计数的输出。

const updateFilter = () => filter.value = location.hash.substr(2);
window.addEventListener('hashchange', updateFilter);
window.addEventListener('load', updateFilter);

而我们从 hash 片段中更新过滤器(以及在启动时)。我们在上面所做的只是设置一个表单元素的值:CSS 处理其余部分。

document.querySelector('.todoapp').addEventListener('submit', e => e.preventDefault(), {capture: true});

在这里,我们确保当表单被提交时我们不会重新加载页面。这一行代码把这个应用程序变成了一个 SPA。

document.forms.newTask.addEventListener('submit', ({target: {elements: {title}}}) =>   
    model.createTask({title: title.value}));
document.forms.main.elements.toggleAll.addEventListener('change', ({target: {checked}})=>
    model.markAll(checked));
document.forms.main.elements.clearCompleted.addEventListener('click', () =>
    model.clearCompleted());

而这就处理了主要的操作(创建、标记所有、清除完成)。

与 CSS 的反应性

完整的 CSS 文件可以供你查看。

CSS 处理了规范中的很多要求(做了一些有利于无障碍的修正)。我们来看看一些示例。

根据规范,“X”(destroy)按钮只在悬停时显示。我还添加了一个辅助位,使它在任务被聚焦时可见。

.task:not(:hover, :focus-within) button[name="destroy"] { opacity: 0 }

当 filter 链接是当前链接时,它会得到一个红色边框:

.todoapp input[name="filter"][value=""] ~ footer a[href$="#/"]nav a:target {
   border-color: #CE4646;
}

注意,我们可以使用链接元素的 href 作为部分属性选择器 -- 不需要 JavaScript 来检查当前的过滤器,并在适当的元素上设置一个 selected 类。

我们还使用了 :target 选择器,这让我们不必担心是否要添加过滤器。

title 输入的视图和编辑样式根据其只读模式而改变:

.task input[name="title"]:read-only {
…
}


.task input[name="title"]:not(:read-only) {
…
}

过滤(即只显示活动的和已完成的任务)是用选择器完成的:

input[name="filter"][value="active"] ~ * .task
      :is(input[name="completed"]:checked, input[name="completed"]:checked ~ *),
input[name="filter"][value="completed"] ~ * .task
     :is(input[name="completed"]:not(:checked), input[name="completed"]:not(:checked) ~ *) {
   display: none;
}

上面的代码可能看起来有点冗长,用 Sass 这样的 CSS 预处理程序可能更容易阅读。但它所做的事情很简单:如果过滤器处于 active 状态,而 completed 的复选框被选中,或者相反,那么我们就会隐藏复选框及其同级。

我选择在 CSS 中实现这个简单的过滤器,以显示它能走多远,但如果它开始变得棘手,那么把它移到模型中是完全有意义的。

总结及要点

我相信,框架为实现复杂的任务提供了方便的方法,而且它们有超越技术的好处,比如使一组开发人员向特定的风格和模式看齐。Web 平台提供了许多选择,而采用一个框架可以让每个人至少部分地在这些选择上达成一致,这是有价值的。另外,声明式编程的优雅性也是值得称道的,而且组件化的大特点也不是我在这篇文章中所处理的。

但请记住,替代模式是存在的,通常成本较低,而且不一定需要较少的开发者经验。允许自己对这些模式感到好奇,即使你决定在使用框架时从它们中挑选。

模式概述

  • 保持 DOM 树的稳定。它启动了一个连锁反应,使事情变得简单。
  • 如果可以的话,依靠 CSS 的反应性而不是 JavaScript。
  • 使用表单元素作为表示互动数据的主要方式。
  • 使用 HTML template 元素而不是 JavaScript 生成的模板。
  • 使用双向的变化流作为模型的接口

作者简介:

Noam Rosenthal,Web 平台顾问,WebKit 和 Chromium 的贡献者,标准编辑,也是经验丰富的 Web 开发者。他的工作主要是在 Web 开发和浏览器 / 标准开发之间架起桥梁。

原文链接:

https://www.smashingmagazine.com/2022/02/web-frameworks-guide-part2/

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Web
    Web
    +关注

    关注

    2

    文章

    1262

    浏览量

    69446
  • 框架
    +关注

    关注

    0

    文章

    403

    浏览量

    17477
  • 编程
    +关注

    关注

    88

    文章

    3614

    浏览量

    93698
收藏 人收藏

    评论

    相关推荐

    五大Python Web框架详解

    进行了扩展应用,提升了重用性且将功能分割到独立的模块中,而且提供了在线调试器,易于错误跟踪!以上是2018年主流Python框架Web开发人员可能更感兴趣一些,可以了解学习一
    发表于 02-06 17:17

    Web框架使用哪些编程语言?

    如果你是做Web开发的,Web框架一定会很熟悉,框架Web架构开发中必不可少的工具,不仅可以提高开发效率,还能让开发项目更成熟,并且可以提
    发表于 03-28 16:53

    主流web前端技术框架

    、强大的组件、单向响应的数据流,具有高效、灵活的性能,且代码逻辑简单,受到越来越多的人的关注和使用!以上目前Web开发常用的框架,每个框架都有其不同的特点,且功能都很强大,想从事Web
    发表于 03-28 16:56

    基于工作流技术的复合语义Web服务框架

    随着Internet和Web应用的快速发展,Web应用模式及Web服务的异构和分散问题日益突出,如何复合繁复而庞大的Web服务群成了一项繁杂的工作。该文描述了一个复合语义
    发表于 03-31 10:01 16次下载

    基于Struts框架和Procedure的Web开发模式

    介绍基于MVC设计模式的Struts框架的组成和实现原理,总结该开发框架的应用特点和开发步骤。在分析和比较其他基于Struts开发模式特点的基础上,提出基于Struts和存储过程结合的Web
    发表于 04-23 10:16 79次下载

    基于Struts和Hibernate框架Web应用的设计与

    基于J2EE 平台的框架技术是目前开发Web 应用的主流技术。其中,Struts 框架基于MVC 设计模式,清晰地划分了控制部分、业务逻辑和视图,实现了各层之间的解耦;而Hibernate 对JDBC 提供
    发表于 09-14 16:21 32次下载

    基于Web的自动化测试框架的研究

    根据web系统测试的特点,为提高软件测试自动化脚本的可重用性,结合在实际项目中软件自动化测试的实践,提出基于Web的自动化测试框架(ACRAT)。分析了软件自动化测试框架的优点
    发表于 11-07 15:58 0次下载
    基于<b class='flag-5'>Web</b>的自动化测试<b class='flag-5'>框架</b>的研究

    SSM框架Web应用开发中的设计与实现 pdf下载

    Web 应用的开发过程中,开发框架的选择非常重要。一个好的开发框架能够加速 Web 应用的开发速度,降低 开发成本,减少开发人员的工作量,同时能够使
    发表于 01-29 09:47 2次下载

    Web服务组合匹配框架研究

    在现有服务发现方法中,单一考虑原子服务或服务组合的方式难以满足用户日益增长的需求。针对该问题,设计一个基于模型转换的Web服务匹配框架。在服务发现过程中综合考虑组合Web服务的执行过程信息和服务
    发表于 03-05 13:35 0次下载
    <b class='flag-5'>Web</b>服务组合匹配<b class='flag-5'>框架</b>研究

    现在流行的Web APP开发框架有哪些

    Web APP框架的开发旨在支持开发人员使用单一编程语言构建交互式应用程序。市场上推出了一系列框架,其框架结构各不相同。开发人员可以通过学习Web
    的头像 发表于 12-29 09:50 1.2w次阅读

    安利5个流畅自如的Python Web框架

    如今,可供选择的Python web框架有不少,能帮助你更快更轻松地创建web应用。本文就将为大家介绍一些更现代、使用更广泛的web框架
    的头像 发表于 07-02 17:15 2365次阅读

    在micropython上搭建web框架web服务——新生代web框架:mpy-urouter

    大家好!之前我给 micropython 开发过一个名为 micro-route 的web框架,在使用的过程中发现这个框架在设计上有很多的缺陷,而且是经过一个星期的时间赶工出来的,代码质量不太
    发表于 12-29 18:56 5次下载
    在micropython上搭建<b class='flag-5'>web</b><b class='flag-5'>框架</b>和<b class='flag-5'>web</b>服务——新生代<b class='flag-5'>web</b><b class='flag-5'>框架</b>:mpy-urouter

    聊聊PHP的web应用程序开发框架存在的漏洞有哪些

    简单说下Yii 是一个高性能PHP的web 应用程序开发框架。通过一个简单的命令行工具 yiic 可以快速创建一个 web 应用程序的代码框架,开发者可以在生成的代码
    的头像 发表于 11-16 10:37 1763次阅读

    Web框架替代方案分享(上)

    上周,我们从框架试图解决哪些核心问题的角度出发,考察了使用框架的不同好处和代价,重点放在声明性编程、数据绑定、反应性、列表和条件。今天,我们来看看能否在 Web 平台上找到替代
    的头像 发表于 03-20 14:51 488次阅读

    Web框架替代方案分享(中)

    上周,我们从框架试图解决哪些核心问题的角度出发,考察了使用框架的不同好处和代价,重点放在声明性编程、数据绑定、反应性、列表和条件。今天,我们来看看能否在 Web 平台上找到替代
    的头像 发表于 03-20 14:51 546次阅读