Header組件熱門搜索欄的實現示例

1. 基本佈局

本次任務是實現熱門搜索模塊的佈局和展示控制功能。

1.1 熱門搜索框

在佈局過程中,我們發現熱門搜索框並沒有出現。這可能是由於外部組件存在 overflow: hidden 屬性導致的,因此我們需要給一個高度解決這個問題:

cssCopy code
export const SearchInfo = styled.div`
  position: absolute;
  left: 0;
  top: 56px;
  width: 240px;
  height: 100px;
  padding: 0 20px;
  background: green;
`;

接下來,我們通過簡書官網調試的方法補全其他屬性。

1.2 熱門搜索Title和換一換圖標

接下來,我們需要添加熱門搜索Title和換一換圖標。

cssCopy code
export const SearchInfoTitle = styled.div`
  margin-top: 20px;
  margin-bottom: 15px;
  line-height: 20px;
  font-size: 14px;
  color: #969696;
`;

然後需要實現換一換的功能。

1.3 熱門Tag

我們還需要添加熱門Tag的樣式:

cssCopy code
export const SearchInfoItem = styled.a`
  display: block;
  float: left;
  line-height: 20px;
  padding: 0 5px;
  font-size: 12px;
  border: 1px solid #ddd;
  color: #969696;
  border-radius: 2px;
  margin-right: 10px;
  margin-bottom: 15px;
`;

但是此時發現高度出瞭問題瞭,因此我們需要在外層佈局進行修改:

cssCopy code
export const SearchWrapper = styled.div`
  position: relative;
  float: left;
  .iconfont {
    position: absolute;
    right: 5px;
    bottom: 5px;
    width: 30px;
    height: 30px;
    line-height: 30px;
    border-radius: 15px;
    text-align: center;
    &.focused {
      background: #777;
      color: #fff;
    }
  }
  .slide-enter {
    transition: all 0.2s ease-out;
  }
  .slide-enter-active {
    width: 240px;
  }
  .slide-exit {
    transition: all 0.2s ease-out;
  }
  .slide-exit-active {
    width: 160px;
  }
`;
export const SearchInfo = styled.div`
  position: absolute;
  left: 0;
  top: 56px;
  width: 240px;
  padding: 0 20px;
  background: green;
`;

同時,我們將上面 SearchInfo 寫死的高度去掉。

2. 控制展示

官方文檔描述瞭 SearchInfo 區域應該在鼠標聚焦時顯示,失去焦點時隱藏。我們可以通過控制 SearchInfo 區域來實現這個邏輯,而且這個控制邏輯與之前用於控制動畫的控制參數非常相似。

3. 使用 Ajax 請求獲取 Tag 數據

實際上,熱門 Tag 的數據是從服務器獲取的。我們希望通過 Ajax 來獲取這些數據,就像簡書網站一樣。而且我們隻需要在第一次聚焦時獲取數據,然後進行本地緩存。

此時,我們需要將 header 中的列表內容進行存儲,以便後續進行狀態管理。初始時,它是一個空數組。

3.1 使用 redux-thunk 返回函數

當 Nav 聚焦時,我們需要獲取 Ajax 數據。由於這是一個異步操作,所以需要使用第三方庫。我們統一使用 redux-thunk 進行操作,將異步操作放在 action 中處理。

應該在創建 store 時使用 redux-thunk:

接下來,我們需要派發異步 action:

然後創建這個 Action:

如果需要使用 Ajax,則需要使用第三方庫 axios 來實現異步請求:

import axios from 'axios';
export const getList = () => { return (dispatch) => { // 異步請求 axios.get('/api/headerList.json').then(()=>{
    }).catch(()=>{
        console.log('error');
    });
}
};

當後端數據還未開發完成時,我們可以使用前端制作的假數據。我們可以使用 create-react-app 的特性,在 public 和 src 目錄下創建一個對應的 JSON 文件,然後就可以訪問瞭。在此期間,路由也需要進行修改,以便實現假數據。

然後,我們需要修改 state。我們需要在回調中派發一個新的 action:

const changeList = (data) => ({ type: constants.CHANGE_LIST, data });
export const getList = () => { return (dispatch) => { // 異步請求 axios.get('/api/headerList.json').then((res) => { const data = res.data; dispatch(changeList(data.data)) }).catch(()=>{ console.log('error'); }); } };

3.2 使用 Immutable 的數組進行 state 統一更新

接下來,我們需要在 reducer 中根據獲取的 data 更新 list。但是有一點需要註意:我們使用 fromJS() 方法將 list 變成瞭一個 Immutable 數組。但是,當我們調用 state.set() 方法去改變 list 時,action.data 本身是一個普通的數組,這兩種數據類型不同會出現錯誤。因此,我們需要將 data 轉換為 Immutable:

然後,我們可以按如下方式編寫 reducer:

3.3 使用 map 方法循環展示內容

最後,需要將數據展示出來。可以使用 map 方法來遍歷數組,並渲染列表項:

javascriptCopy code
getListArea(show) {
  if (show) {
    return (
      <SearchInfo>
        <SearchInfoTitle>
          熱門搜索
          <SearchInfoSwitch>
            換一批
          </SearchInfoSwitch>
        </SearchInfoTitle>
        <SearchInfoList>
          {this.props.list.map((item) => {
            return <SearchInfoItem key={item}>{item}</SearchInfoItem>;
          })}
        </SearchInfoList>
      </SearchInfo>
    );
  } else {
    return null;
  }
}

即使是使用 immutable 數組,也可以使用 map 方法進行遍歷。

4. 優化 reducer

之前的 reducer 大量使用 if 語句,可以通過使用 switch-case 進行優化:

cCopy code
export default (state = defaultState, action) => {
  switch (action.type) {
    case constants.SEARCH_FOCUS:
      return state.set('focused', true);
    case constants.SEARCH_BLUR:
      return state.set('focused', false);
    case constants.CHANGE_LIST:
      return state.set('list', action.data);
    default:
      return state;
  }
};

使用 switch-case 可以讓 reducer 代碼更加清晰易懂。

以上就是Header組件熱門搜索欄的實現示例的詳細內容,更多關於Header組件熱門搜索欄的資料請關註WalkonNet其它相關文章!

推薦閱讀: