愈發純熟的業務代碼——開始作菜
原文地址vue
某日,被後臺拿着一個別人實現好的管理系統說道了一頓,說須要實現得比某框架更好react
地址:pig4cloudgit
需求:管理系統內實現瀏覽器 Tag 標籤的功能github
分析:vue-router
切換 Tag 不主動更新頁面(重點)
技術棧:react + react-router + react-redux + react-sagavuex
重點:組件更新,頁面不變
redux
思路:卻分活動狀態內的存,和在打開過的內存,兩個內存同事更新,切換 Tag 從打開過的數組內調取數據,有數據使用該數據,無數據則發起請求瀏覽器
操做同歸在 Reduce
內,方便後續 Tag 內外部交互session
/*. 目錄:/src/store/index.js */ const appReducer ={ tabListStatus: (state = { tabList: [], activeTab: null }, action) => { switch (action.type) { case 'tabListChange': // case 'tabListAdd': // case 'tabListRemove': // case 'tabListClear': // default: return state } }, // ... }
全部內存初始狀態,都在 App.js
->componentDidUpdate
生命週期內存操做
/* 目錄:/src/App.js */ componentDidUpdate(prevProps, prevState) { if (this.props.tabListStatus !== prevProps.tabListStatus) { const { tabList, activeTab } = this.props.tabListStatus sessionStorage.setItem('tabList', JSON.stringify(tabList)) sessionStorage.setItem('activeTab', JSON.stringify(activeTab)) this.setState({ tabList, activeTab: activeTab !== null ? activeTab.key : '/' }) } }
class App extends Component { // 點擊側欄 handleOnMenuItem = param => { const { tabListAdd, tabListStatus } = this.props const { tabList } = tabListStatus const userMenu = menuDataSource const menu = this.menuItemFilter(userMenu, `/nav_${param.key}`) let paramTab = { title: menu.name, key: menu.path, queryParam: {}, dataSource: {} } //判斷是否爲新增 let pushBol = true tabList.map(tab => { if (tab.key === paramTab.key) { pushBol = false paramTab = Object.assign({},paramTab,tab) } return tab }) if (pushBol) { tabList.push(paramTab) } tabListAdd({ tabList, activeTab: paramTab }) this.toPath(`nav_${param.key}`) } // 點擊 Tag onChange = activeKey => { // console.log('....', activeKey) const { tabListStatus, tabListAdd } = this.props const { tabList } = tabListStatus const userMenu = tabList const menu = this.menuChangeFilter(userMenu, activeKey) const paramTab = { ...menu } tabListAdd({ tabList, activeTab: paramTab }) this.toPath(activeKey) } // 關閉邏輯 remove = targetKey => { let activeKey = this.state.activeTab let panes = this.state.tabList let lastIndex panes.forEach((pane, i) => { if (pane.key === targetKey) { lastIndex = panes.length - 1 === i ? i - 1 : i } }) const panesFilter = panes.filter(pane => pane.key !== targetKey) if (panesFilter.length && activeKey === targetKey) { if (lastIndex >= 0) { activeKey = panesFilter[lastIndex] } else { activeKey = panesFilter[0] } } else { activeKey = null } this.props.tabListAdd({ tabList: panesFilter, activeTab: activeKey }) this.toPath(activeKey !== null ? activeKey.key : '/') } // ... }
onChange
, onClear
, onSubmit
使用標記符號,或者直接判斷一個 key 值是否存在值,來發送請求,demo 內使用 dataSource 是否存在爲空來判斷是否須要發送請求
componentDidMount() { const { tabListStatus, musicList_query_param, musicList } = this.props const { dataSource } = tabListStatus.activeTab if (!Object.keys(dataSource).length) { musicList(musicList_query_param) } }
操做更新 onChange
, onClear
, onSubmit
除了這一些之外還會存在不一樣的操做,demo 大體分了這幾個操做,均使用 reducer 操做,App.js 內監聽操做,更改內存,模塊內不參與內存更改
onChange = (tabList, e) => { e.persist() if (!e || !e.target) { return } const { target } = e const operateParam = operateQuery(tabList, { [target.id]: target.type === 'checkbox' ? target.checked : target.value }) this.props.tabListChange(operateParam) }
關鍵:keep-alive
關鍵:redux 與內存處理
實現上面確定是 Vue 更快實現的,但對使用 React 內存的控制也是一件很是好玩的事情,若是項目大了,就更好玩了
實際上這種實現有點雞肋,由於用戶一個不留意,關了頁面,這些 Tag 就不存在了,不管是那種管理系統,這個實現若是配合到後臺,可能就更好玩了
感謝閱讀,代碼很爛,請輕噴