<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      喝杯茶先~

      導(dǎo)航

      (前端)「狀態(tài)」設(shè)計模式在項目開發(fā)中的應(yīng)用

      1. 事件起因

      ??最近在做一個關(guān)于星座的移動端項目,想實現(xiàn)這樣一個需求,每次切換導(dǎo)航欄NavBar item時,都會使下面的頁面級組件TodayView更改背景色樣式(如圖1到圖2,導(dǎo)航欄從雙魚座切換到處女座,下面頁面級組件的背景顏色由黃色切換至粉色)。

       

       

                 圖1                     圖2

       

        如果利用傳統(tǒng)的辦法,在點擊事件的事件處理函數(shù)中進(jìn)行多層條件語句判斷,代碼如下:

      function handleClick(e) {
          if(e.target.innerText === '雙魚座‘) {
              store.state.vnode.style.backgroundColor = 'yellow';   
          }else if(e.target.innerText === '處女座‘){
              store.state.vnode.style.backgroundColor = 'pink';  
          }else if(...){
              ... 
          }
      }

      ??我們大概有12個星座,那就要寫12層條件判斷語句,并且每一層的判斷以及做的事情其實是一樣的,如此代碼會十分冗余。因此考慮「狀態(tài)」設(shè)計模式。

       

      2. 解決方案

      ??利用「狀態(tài)」設(shè)計模式。

      ??大致思路: 每當(dāng)切換NavBar item時,都給關(guān)于NavBar的一個狀態(tài)類添加狀態(tài),例如切換到雙魚座時,就給這個狀態(tài)類添加一個狀態(tài)為“雙魚座”,然后執(zhí)行該狀態(tài)對應(yīng)的動作方法,此方法內(nèi)就是對頁面級組件DOM的背景色修改為特定的顏色。

      ??先封裝狀態(tài)類,代碼如下: 

      ??src/NavBarState/index.ts:

      // CONSTELLATIONS是我定義的枚舉類型, 里面的每個枚舉都對應(yīng)了一個星座, 并且我把該枚舉就作為我要添加的狀態(tài)名,以及該狀態(tài)的對應(yīng)的動作方法的名字
      import { CONSTELLATIONS } from '../typings/index';       
      
      const NavBarState = function(vnode: any) {
        // currentStates里面存儲所有的狀態(tài)(key), 對應(yīng)的值為true(value)則表示可以執(zhí)行該狀態(tài)對應(yīng)的動作方法
        let currentStates = {};     // key為動作方法的函數(shù)名, 也是狀態(tài)
          
        // statesAction中是 狀態(tài)-動作方法 的映射關(guān)系, 狀態(tài)名即為動作方法名, 當(dāng)然也可以寫成 '狀態(tài)名': function 動作方法名(){...}
        const statesAction = {
          // 如果該狀態(tài)為'雙魚座', 就將虛擬DOM的背景色改為黃色
          [CONSTELLATIONS.m1]() {
            vnode.style.backgroundColor = 'yellow';
          },
          [CONSTELLATIONS.m2]() {
            vnode.style.backgroundColor = 'pink';
          },
          [CONSTELLATIONS.m3]() {
            vnode.style.backgroundColor = 'purple';
          },
          [CONSTELLATIONS.m4]() {
            vnode.style.backgroundColor = 'green';
          },
          [CONSTELLATIONS.m5]() {
            vnode.style.backgroundColor = 'red';
          },
          [CONSTELLATIONS.m6]() {
            vnode.style.backgroundColor = 'orange';
          },
          [CONSTELLATIONS.m7]() {
            vnode.style.backgroundColor = 'skyblue';
          },
          [CONSTELLATIONS.m8]() {
            vnode.style.backgroundColor = 'blue';
          },
          [CONSTELLATIONS.m9]() {
            vnode.style.backgroundColor = '#FFBB00';
          },
          [CONSTELLATIONS.m10]() {
            vnode.style.backgroundColor = '#880000';
          },
          [CONSTELLATIONS.m11]() {
            vnode.style.backgroundColor = '#D28EFF';
          },
          [CONSTELLATIONS.m12]() {
            vnode.style.backgroundColor = '#FFC8B4';
          }
        }
        
        // Action中封裝了2個方法, addState用于給狀態(tài)類NavBarState添加進(jìn)狀態(tài), goes用于執(zhí)行狀態(tài)類現(xiàn)有狀態(tài)的動作方法
        const Action = {
          addState(...args: any[]) {
            // eslint-disable-next-line prefer-rest-params
            currentStates = {};
            for(const key in args) {
              currentStates[args[key]] = true;
            }
            // 把調(diào)用者return出去是為了方便后續(xù)的鏈?zhǔn)秸{(diào)用, 例如NavBarState(vnode).addState('雙魚座').goes()
            return this;
          },
      
          goes() {
            for(const key in currentStates) {
              if(currentStates[key] === true) {
                statesAction[key] && statesAction[key]();
              }
            }
            return this;
          }
        }
      
        return {
          addState: Action.addState,
          goes: Action.goes
        }
      }
      
      
      export default NavBarState;

        

      ??我們在組件中試一下:

      ??src/components/NavBar/index.vue:

      /**
      *    當(dāng)切換NavBar item時子組件(NavBar/Item.vue)會給父組件發(fā)布事件, 并帶上自己的index過去
      *    父組件監(jiān)聽這個事件觸發(fā)的回調(diào)就是changeCurNavId, 更新記錄標(biāo)記curIdx
      */
      const changeCurNavId = (idx: number): void => {
          curIdx.value = idx;
      }
      
      /*
      *    當(dāng)監(jiān)聽到curIdx變化時, 說明切換了Item, 立刻給狀態(tài)類NavBarState添加進(jìn)狀態(tài)('雙魚座'), 然后執(zhí)行該狀態(tài)對應(yīng)的動作方法, 進(jìn)而修改虛擬DOM的樣式
      
      *    這里有個問題就是, 如果我同步給NavBarState添加狀態(tài)并執(zhí)行的話, 效果是不會出來的, 必須異步添加狀態(tài)才可以。
      *    我猜想可能是因為在外殼組件App.vue中, NavBar組件是先于頁面級組件TodayView渲染的, 而我將TodayView的虛擬DOM設(shè)置進(jìn)store中
           是在TodayView組件中完成的, 也就是說當(dāng)NavBar組件渲染時store.state.todayDom還沒有值, 為null, 因此賦予其狀態(tài)并修改其樣式
           自然是無效的。
      */
      watch(curIdx, () => {
          store.commit(actionTypes.SET_CONSNAME, navCons[curIdx.value].cons);
      
          // 在today中已經(jīng)改變了todayDomRef, 接下來給這個todayDomRef在切換curIdx時賦予不同樣式; 并延遲更改NavBar的狀態(tài)
          setTimeout(() => {
              NavBarState(store.state.todayDom).addState(navCons[curIdx.value].cons).goes();
          })
      }, { immediate: true });

       

      ??以上,就是我關(guān)于「狀態(tài)」設(shè)計模式在項目開發(fā)中的一些應(yīng)用場景,感謝閱讀!

       

      ??參考書籍: 《JavaScript設(shè)計模式》 張容銘 著

       

      posted on 2022-08-05 00:08  紅果園園長  閱讀(362)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 99re6这里有精品热视频| 国产视频最新| 国产不卡一区二区在线| 资源在线观看视频一区二区| 日韩亚洲精品中文字幕| 国产xxxx做受视频| 国产无遮挡裸体免费久久| 亚洲精品日韩中文字幕| 国产h视频在线观看| 亚洲男人天堂av在线| 一区二区三区精品视频免费播放| 亚洲国产成人无码电影| 中文字幕一区有码视三区| 久久99久国产精品66| 无码国模国产在线观看免费| 久久精品国产99久久美女| av资源在线看免费观看| 蜜臀av久久国产午夜| 日韩高清亚洲日韩精品一区二区 | 日本人妻巨大乳挤奶水免费| 少妇人妻av毛片在线看| 亚洲AV片一区二区三区| 大地资源中文第二页日本| 人人玩人人添人人澡超碰| 天天做日日做天天添天天欢公交车 | 国模一区二区三区私拍视频 | 日韩高清亚洲日韩精品一区二区| 久久综合色之久久综合| 国产成人精品一区二区三区免费| 日韩精品中文字幕一线不卡| 亚洲成A人片在线观看的电影| 荥经县| 九九热在线观看视频精品| 成人亚欧欧美激情在线观看| 久久国产精品-国产精品| 国产无遮挡又黄又爽不要vip软件| 久久亚洲av成人一二三区| 中文字幕乱码亚洲无线三区| 年日韩激情国产自偷亚洲| 香港日本三级亚洲三级| 蜜芽久久人人超碰爱香蕉|