0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

jf_78858299 ? 來源: 前端之巔 ? 作者:Noam Rosenthal ? 2023-03-20 14:51 ? 次閱讀

此 HTML 包括以下內(nèi)容:

  • 我們有一個 main 表單,其中有所有的全局輸入和按鈕,還有一個新的表單用于創(chuàng)建一個新任務(wù)。請注意,我們使用 form 屬性將元素與表單聯(lián)系起來,以避免表單中的元素嵌套。
  • template 元素代表一個列表項(xiàng),它的根元素是另一個表單,代表與特定任務(wù)相關(guān)的互動數(shù)據(jù)。當(dāng)任務(wù)被添加時,這個表單將通過克隆模板的內(nèi)容而被重復(fù)。
  • 隱藏的輸入表示不直接顯示的數(shù)據(jù),但用于樣式設(shè)計(jì)和選擇。

注意這個 DOM 是如何簡潔的。它沒有在其元素中散布類。它包括應(yīng)用程序所需的所有元素,以合理的層次結(jié)構(gòu)排列。多虧了隱藏的輸入元素,你已經(jīng)可以很好地感覺到以后文檔中可能會有什么變化。

這個 HTML 不知道它將如何被樣式化,也不知道它到底與什么數(shù)據(jù)綁定。讓 CSS 和 JavaScript 為你的 HTML 工作,而不是讓你的 HTML 為某個特定的造型機(jī)制工作。這將使你在改變設(shè)計(jì)時變得更加容易。

最小控制器 JavaScrip

現(xiàn)在我們在 CSS 中已經(jīng)有了大部分的反應(yīng)性,在模型中也有了列表處理,剩下的就是控制器的代碼了,也就是把所有的東西固定在一起的“膠帶”。在這個小程序中,控制器的 JavaScript 大約是 40 行。

下面是一個版本,每個部分都有解釋:

import TaskListModel from './model.js';


const model = new TaskListModel(new class {

上面,我們創(chuàng)建了一個新模型。

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);
}

當(dāng)一個項(xiàng)目被添加到模型中,我們在用 UI 中創(chuàng)建其相應(yīng)的列表項(xiàng)。

在上面的代碼段中,我們克隆了項(xiàng)目 template 的內(nèi)容,為一個特定的項(xiàng)目分配了事件監(jiān)聽器,并將新的項(xiàng)目添加到列表中。

注意,這個函數(shù),以及 onUpdate、onRemove 和 onCountChange,都是要從模型中調(diào)用的回調(diào)。

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

當(dāng)一個項(xiàng)目被更新時,我們設(shè)置它的 completed 和 title 值,然后 blur(退出編輯模式)。

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

當(dāng)從模型中移除一個項(xiàng)時,我們將從視圖中移除其對應(yīng)的列表項(xiàng)。

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`;
}

在上面的代碼中,當(dāng)完成的或活動的項(xiàng)目數(shù)量發(fā)生變化時,我們設(shè)置適當(dāng)?shù)妮斎雭碛|發(fā) CSS 反應(yīng),并格式化顯示計(jì)數(shù)的輸出。

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

而我們從 hash 片段中更新過濾器(以及在啟動時)。我們在上面所做的只是設(shè)置一個表單元素的值:CSS 處理其余部分。

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

在這里,我們確保當(dāng)表單被提交時我們不會重新加載頁面。這一行代碼把這個應(yīng)用程序變成了一個 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());

而這就處理了主要的操作(創(chuàng)建、標(biāo)記所有、清除完成)。

與 CSS 的反應(yīng)性

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

CSS 處理了規(guī)范中的很多要求(做了一些有利于無障礙的修正)。我們來看看一些示例。

根據(jù)規(guī)范,“X”(destroy)按鈕只在懸停時顯示。我還添加了一個輔助位,使它在任務(wù)被聚焦時可見。

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

當(dāng) filter 鏈接是當(dāng)前鏈接時,它會得到一個紅色邊框:

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

注意,我們可以使用鏈接元素的 href 作為部分屬性選擇器 -- 不需要 JavaScript 來檢查當(dāng)前的過濾器,并在適當(dāng)?shù)脑厣显O(shè)置一個 selected 類。

我們還使用了 :target 選擇器,這讓我們不必?fù)?dān)心是否要添加過濾器。

title 輸入的視圖和編輯樣式根據(jù)其只讀模式而改變:

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


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

過濾(即只顯示活動的和已完成的任務(wù))是用選擇器完成的:

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;
}

上面的代碼可能看起來有點(diǎn)冗長,用 Sass 這樣的 CSS 預(yù)處理程序可能更容易閱讀。但它所做的事情很簡單:如果過濾器處于 active 狀態(tài),而 completed 的復(fù)選框被選中,或者相反,那么我們就會隱藏復(fù)選框及其同級。

我選擇在 CSS 中實(shí)現(xiàn)這個簡單的過濾器,以顯示它能走多遠(yuǎn),但如果它開始變得棘手,那么把它移到模型中是完全有意義的。

總結(jié)及要點(diǎn)

我相信,框架為實(shí)現(xiàn)復(fù)雜的任務(wù)提供了方便的方法,而且它們有超越技術(shù)的好處,比如使一組開發(fā)人員向特定的風(fēng)格和模式看齊。Web 平臺提供了許多選擇,而采用一個框架可以讓每個人至少部分地在這些選擇上達(dá)成一致,這是有價(jià)值的。另外,聲明式編程的優(yōu)雅性也是值得稱道的,而且組件化的大特點(diǎn)也不是我在這篇文章中所處理的。

但請記住,替代模式是存在的,通常成本較低,而且不一定需要較少的開發(fā)者經(jīng)驗(yàn)。允許自己對這些模式感到好奇,即使你決定在使用框架時從它們中挑選。

模式概述

  • 保持 DOM 樹的穩(wěn)定。它啟動了一個連鎖反應(yīng),使事情變得簡單。
  • 如果可以的話,依靠 CSS 的反應(yīng)性而不是 JavaScript。
  • 使用表單元素作為表示互動數(shù)據(jù)的主要方式。
  • 使用 HTML template 元素而不是 JavaScript 生成的模板。
  • 使用雙向的變化流作為模型的接口。

作者簡介:

Noam Rosenthal,Web 平臺顧問,WebKit 和 Chromium 的貢獻(xiàn)者,標(biāo)準(zhǔn)編輯,也是經(jīng)驗(yàn)豐富的 Web 開發(fā)者。他的工作主要是在 Web 開發(fā)和瀏覽器 / 標(biāo)準(zhǔn)開發(fā)之間架起橋梁。

原文鏈接:

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Web
    Web
    +關(guān)注

    關(guān)注

    2

    文章

    1254

    瀏覽量

    69209
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    397

    瀏覽量

    17363
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3544

    瀏覽量

    93482
收藏 人收藏

    評論

    相關(guān)推薦

    五大Python Web框架詳解

    進(jìn)行了擴(kuò)展應(yīng)用,提升了重用性且將功能分割到獨(dú)立的模塊中,而且提供了在線調(diào)試器,易于錯誤跟蹤!以上是2018年主流Python框架,Web開發(fā)人員可能更感興趣一些,可以了解學(xué)習(xí)一!
    發(fā)表于 02-06 17:17

    Web框架使用哪些編程語言?

    如果你是做Web開發(fā)的,Web框架一定會很熟悉,框架Web架構(gòu)開發(fā)中必不可少的工具,不僅可以提高開發(fā)效率,還能讓開發(fā)項(xiàng)目更成熟,并且可以提
    發(fā)表于 03-28 16:53

    主流web前端技術(shù)框架

    、強(qiáng)大的組件、單向響應(yīng)的數(shù)據(jù)流,具有高效、靈活的性能,且代碼邏輯簡單,受到越來越多的人的關(guān)注和使用!以上目前Web開發(fā)常用的框架,每個框架都有其不同的特點(diǎn),且功能都很強(qiáng)大,想從事Web
    發(fā)表于 03-28 16:56

    基于工作流技術(shù)的復(fù)合語義Web服務(wù)框架

    隨著Internet和Web應(yīng)用的快速發(fā)展,Web應(yīng)用模式及Web服務(wù)的異構(gòu)和分散問題日益突出,如何復(fù)合繁復(fù)而龐大的Web服務(wù)群成了一項(xiàng)繁雜的工作。該文描述了一個復(fù)合語義
    發(fā)表于 03-31 10:01 ?16次下載

    基于Struts框架和Procedure的Web開發(fā)模式

    介紹基于MVC設(shè)計(jì)模式的Struts框架的組成和實(shí)現(xiàn)原理,總結(jié)該開發(fā)框架的應(yīng)用特點(diǎn)和開發(fā)步驟。在分析和比較其他基于Struts開發(fā)模式特點(diǎn)的基礎(chǔ)上,提出基于Struts和存儲過程結(jié)合的Web
    發(fā)表于 04-23 10:16 ?79次下載

    基于Struts和Hibernate框架Web應(yīng)用的設(shè)計(jì)與

    基于J2EE 平臺的框架技術(shù)是目前開發(fā)Web 應(yīng)用的主流技術(shù)。其中,Struts 框架基于MVC 設(shè)計(jì)模式,清晰地劃分了控制部分、業(yè)務(wù)邏輯和視圖,實(shí)現(xiàn)了各層之間的解耦;而Hibernate 對JDBC 提供
    發(fā)表于 09-14 16:21 ?32次下載

    基于Web的自動化測試框架的研究

    根據(jù)web系統(tǒng)測試的特點(diǎn),為提高軟件測試自動化腳本的可重用性,結(jié)合在實(shí)際項(xiàng)目中軟件自動化測試的實(shí)踐,提出基于Web的自動化測試框架(ACRAT)。分析了軟件自動化測試框架的優(yōu)點(diǎn)
    發(fā)表于 11-07 15:58 ?0次下載
    基于<b class='flag-5'>Web</b>的自動化測試<b class='flag-5'>框架</b>的研究

    SSM框架Web應(yīng)用開發(fā)中的設(shè)計(jì)與實(shí)現(xiàn) pdf下載

    Web 應(yīng)用的開發(fā)過程中,開發(fā)框架的選擇非常重要。一個好的開發(fā)框架能夠加速 Web 應(yīng)用的開發(fā)速度,降低 開發(fā)成本,減少開發(fā)人員的工作量,同時能夠使
    發(fā)表于 01-29 09:47 ?2次下載

    Web服務(wù)組合匹配框架研究

    在現(xiàn)有服務(wù)發(fā)現(xiàn)方法中,單一考慮原子服務(wù)或服務(wù)組合的方式難以滿足用戶日益增長的需求。針對該問題,設(shè)計(jì)一個基于模型轉(zhuǎn)換的Web服務(wù)匹配框架。在服務(wù)發(fā)現(xiàn)過程中綜合考慮組合Web服務(wù)的執(zhí)行過程信息和服務(wù)
    發(fā)表于 03-05 13:35 ?0次下載
    <b class='flag-5'>Web</b>服務(wù)組合匹配<b class='flag-5'>框架</b>研究

    現(xiàn)在流行的Web APP開發(fā)框架有哪些

    Web APP框架的開發(fā)旨在支持開發(fā)人員使用單一編程語言構(gòu)建交互式應(yīng)用程序。市場上推出了一系列框架,其框架結(jié)構(gòu)各不相同。開發(fā)人員可以通過學(xué)習(xí)Web
    的頭像 發(fā)表于 12-29 09:50 ?1.2w次閱讀

    安利5個流暢自如的Python Web框架

    如今,可供選擇的Python web框架有不少,能幫助你更快更輕松地創(chuàng)建web應(yīng)用。本文就將為大家介紹一些更現(xiàn)代、使用更廣泛的web框架。
    的頭像 發(fā)表于 07-02 17:15 ?2306次閱讀

    在micropython上搭建web框架web服務(wù)——新生代web框架:mpy-urouter

    大家好!之前我給 micropython 開發(fā)過一個名為 micro-route 的web框架,在使用的過程中發(fā)現(xiàn)這個框架在設(shè)計(jì)上有很多的缺陷,而且是經(jīng)過一個星期的時間趕工出來的,代碼質(zhì)量不太
    發(fā)表于 12-29 18:56 ?5次下載
    在micropython上搭建<b class='flag-5'>web</b><b class='flag-5'>框架</b>和<b class='flag-5'>web</b>服務(wù)——新生代<b class='flag-5'>web</b><b class='flag-5'>框架</b>:mpy-urouter

    聊聊PHP的web應(yīng)用程序開發(fā)框架存在的漏洞有哪些

    簡單說下Yii 是一個高性能PHP的web 應(yīng)用程序開發(fā)框架。通過一個簡單的命令行工具 yiic 可以快速創(chuàng)建一個 web 應(yīng)用程序的代碼框架,開發(fā)者可以在生成的代碼
    的頭像 發(fā)表于 11-16 10:37 ?1656次閱讀

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

    上周,我們從框架試圖解決哪些核心問題的角度出發(fā),考察了使用框架的不同好處和代價(jià),重點(diǎn)放在聲明性編程、數(shù)據(jù)綁定、反應(yīng)性、列表和條件。今天,我們來看看能否在 Web 平臺上找到替代
    的頭像 發(fā)表于 03-20 14:51 ?459次閱讀

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

    上周,我們從框架試圖解決哪些核心問題的角度出發(fā),考察了使用框架的不同好處和代價(jià),重點(diǎn)放在聲明性編程、數(shù)據(jù)綁定、反應(yīng)性、列表和條件。今天,我們來看看能否在 Web 平臺上找到替代
    的頭像 發(fā)表于 03-20 14:51 ?503次閱讀