<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          業(yè)務(wù)前端的本質(zhì)--數(shù)據(jù)維護(hù)

          共 4795字,需瀏覽 10分鐘

           ·

          2024-07-26 09:10

          Vue/React 將前端開發(fā)從 jQuery 命令式的編程風(fēng)格帶到了聲明式的編程風(fēng)格,開發(fā)者只需要描述界面應(yīng)該是什么樣子,Vue/React 就會根據(jù)數(shù)據(jù)的變化自動更新界面。

          因此對于業(yè)務(wù)頁面只需要關(guān)心數(shù)據(jù)有什么以及引起數(shù)據(jù)的變化有什么。

          數(shù)據(jù)

          數(shù)據(jù)主要有兩大類,ui 相關(guān)非 ui 相關(guān)

          ui 相關(guān)

          前端本質(zhì)上就是將數(shù)據(jù)可視化,因此定義的變量中一部分就是供頁面展示使用的,在 Vue 中會把這些數(shù)據(jù)定義在 data 中變?yōu)轫憫?yīng)式,在 React 中會調(diào)用 SetState  來更新這些變量以便更新視圖。

          前端自閉環(huán)

          一些變量僅在前端記錄進(jìn)行 ui 的更新,后端不會感知到。

          比如頁面的 loading 態(tài):

          點擊態(tài),是否打開展示更多:

          來自后端

          頁面數(shù)據(jù)是存在數(shù)據(jù)庫中,后端會把這些數(shù)據(jù)給前端,供前端展示,這類數(shù)據(jù)又分為兩種:

          • 將數(shù)據(jù)直接賦值給某個前端變量進(jìn)行展示,比如昵稱、標(biāo)題等。
          • 將數(shù)據(jù)轉(zhuǎn)換后再進(jìn)行展示,比如錢相關(guān)字段因為精度問題,后端存儲的是分,給到前端以后需要轉(zhuǎn)換成元進(jìn)行展示。

          來自底層

          設(shè)備信息:通過屏幕寬高來設(shè)置彈窗的寬高。

          localStorage:一些模塊可能一天只需要展示一次,前端將標(biāo)志存到 localStorage 中自行進(jìn)行判斷。

          非 ui 相關(guān)

          這些變量和 ui 無關(guān)也不會和頁面后端交互,舉幾個例子:

          前端自閉環(huán)

          請求鎖:一些提交請求,為了防止用戶多次提交,可以在接口請求前設(shè)置一個標(biāo)志位,類似于下邊這樣。

          // 用于保存請求狀態(tài)的標(biāo)志位
          let isSubmitting = false;

          // 模擬一個異步請求
          function sendRequest({
              return new Promise((resolve, reject) => {
                  setTimeout(() => {
                      resolve("請求成功");
                  }, 2000); // 模擬2秒的請求時間
              });
          }

          // 處理按鈕點擊事件
          function handleSubmit({
              // 檢查標(biāo)志位
              if (isSubmitting) {
                  console.log("請求正在進(jìn)行中,請稍后...");
                  return;
              }

              // 設(shè)置標(biāo)志位
              isSubmitting = true;
              console.log("開始請求...");

              // 發(fā)送請求
              sendRequest().then(response => {
                  console.log(response);
              }).catch(error => {
                  console.error(error);
              }).finally(() => {
                  // 請求完成后重置標(biāo)志位
                  isSubmitting = false;
                  console.log("請求完成,可以再次提交");
              });
          }

          埋點數(shù)據(jù):模塊曝光或者用戶點擊的時候進(jìn)行埋點,相關(guān)數(shù)據(jù)會提前存到一個對象中。

          定時器引用:頁面中創(chuàng)建定時器后用一個變量保存定時器實例,用戶可能離開頁面的時候還未執(zhí)行到定時器,因此需要在離開頁面的時候進(jìn)行清除。

          Page({
            data: {
              // 其他數(shù)據(jù)
            },
            
            // 用于保存定時器實例的變量
            timernull,

            // 頁面加載時創(chuàng)建定時器
            onLoadfunction({
              this.createTimer();
            },

            // 創(chuàng)建定時器的方法
            createTimerfunction({
              this.timer = setTimeout(() => {
                console.log('定時器執(zhí)行中...');
              }, 5000); // 5秒后執(zhí)行
            },

            // 頁面卸載時清除定時器
            onUnloadfunction({
              this.clearTimer();
            },

            // 清除定時器的方法
            clearTimerfunction({
              if (this.timer) {
                clearTimeout(this.timer);
                console.log('頁面即將卸載,定時器已清除');
              }
            },

            // 其他頁面方法和事件處理函數(shù)
          });

          來自后端

          埋點數(shù)據(jù):模塊曝光或者用戶點擊的時候進(jìn)行埋點,一些數(shù)據(jù)會由后端給到。

          來自底層

          localStorage:比如存儲用戶的點擊次數(shù),進(jìn)行相應(yīng)的限頻。

          引起數(shù)據(jù)的變化

          數(shù)據(jù)變化的根源就是用戶操作,用戶的操作可能直接引起數(shù)據(jù)變化,也可能觸發(fā)某些全局事件或者定時器,又觸發(fā)新一輪的頁面數(shù)據(jù)變化。

          用戶操作

          大部分的數(shù)據(jù)變化都是由于用戶的操作,比如點擊、滑動。

          根據(jù)點擊的位置不同,可能觸發(fā)不同的動作。比如去請求后端接口拿數(shù)據(jù)、進(jìn)入新頁面、離開當(dāng)前頁面,在小程序中會觸發(fā) onHideonShow  生命周期,在這些周期中會做一些動作更新數(shù)據(jù)。

          還有經(jīng)常遇到的表單逆向操作,當(dāng)用戶依次填了 A 項、B 項、C 項,由于 B、C  依賴于 A 項的選擇,當(dāng)用戶再修改 A 項的時候需要清空 B、C 之前的選擇。

          監(jiān)聽數(shù)據(jù)變化

          Vue 中通過 watch 監(jiān)聽變量,在 React 中通過 useEffect 監(jiān)聽變量。一般情況監(jiān)聽的是組件的 prop,當(dāng)父組件變化時,子組件進(jìn)行相應(yīng)的更新。

          定時器

          定時器時間結(jié)束后,會觸發(fā)定時器注冊的回調(diào)函數(shù)。

          常用于頁面上的倒計時的更新。也用于解決 ui 更新的時序問題,直接給 setTimeout 事件設(shè)置為 0,讓回調(diào)函數(shù)到下一個宏任務(wù)周期去執(zhí)行。

          全局事件

          主要用于跨模塊之間的通信,常用的比如 eventbus、vuex、redux 等。

          常見的比如全局的登錄事件,各個頁面需要監(jiān)聽登錄成功才去觸發(fā)后續(xù)的業(yè)務(wù)邏輯。

          關(guān)聯(lián)

          理想狀態(tài),用戶動作 => 更新數(shù)據(jù) => 頁面自動更新。

          但實際上,當(dāng)數(shù)據(jù)變化的時候,由于全局事件、定時器的存在,還會繼續(xù)觸發(fā)新一輪的數(shù)據(jù)更新。

          此外,數(shù)據(jù)變化每次也不止變更一個數(shù)據(jù),數(shù)據(jù)之間又會有相應(yīng)的聯(lián)動關(guān)系。

          這也是為什么框架都在倡導(dǎo)單一數(shù)據(jù)流的原因,全局事件第一個人用起來會很方便,但在一個上百人的前端項目中,后續(xù)頁面繼續(xù)迭代或者重構(gòu)的時候,漏改或者影響面評估錯誤的風(fēng)險也會增高。

          當(dāng)增加一個數(shù)據(jù)變量的時候也要考慮清楚,是否有必要新增,因為每增一個都會增加頁面的內(nèi)部復(fù)雜度。當(dāng)然有時候也不是變量越少越好,當(dāng)各個地方共用一個變量,也意味著這個變量賦予了多重含義,有悖「單一職責(zé)」。

          業(yè)務(wù)前端看起來簡單,就是維護(hù)一些數(shù)據(jù)。但當(dāng)頁面數(shù)據(jù)變量越來越多,交互越來越多,數(shù)據(jù)更新會變得錯綜復(fù)雜,后續(xù)迭代的心智負(fù)擔(dān)會越來越重。

          此時能做的就是明確當(dāng)前數(shù)據(jù)(ui/非 ui 數(shù)據(jù))有什么,引起數(shù)據(jù)的變化有什么(用戶動作、數(shù)據(jù)之間的關(guān)聯(lián)等),這些理清之后出現(xiàn) bug 的概率也會極大降低。

          最根本的還是降低函數(shù)和函數(shù)之間、模塊與模塊之間的依賴關(guān)系,也就是常說的高內(nèi)聚、低耦合,保證后續(xù)改動的影響面足夠小且明確。

          最終看到的頁面不再是頁面,而是數(shù)據(jù)的變化和流動。


          瀏覽 322
          2點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          2點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费操屄片 | 先锋影音俺去也 | 女人18毛片A级毛片 | 婬乱丰满熟妇XXXXX性91 | 日本黄色免费视频网站 |