愈发纯熟的业务代码——开始作菜
原文地址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 就不存在了,不管是那种管理系统,这个实现若是配合到后台,可能就更好玩了
感谢阅读,代码很烂,请轻喷