Implementation of Tag Function in Management System

More sophisticated business code - start cooking

Original address

1. Background & Demand Analysis

1.1 Background

One day, I was held in the background with a good management system implemented by a single person and said that the need to achieve better than a framework.

Address: pig4cloud

1.2 Demand Analysis

Requirements: Implementing Tag tag in browser in management system

Analysis:

  1. Switching Tag does not actively update the page (emphasis)
  2. Switch off Tag in the activity to the latter
  3. If you close Tag for the last one, switch to the previous one

2. Implementation logic

Technology stack: react + react-router + react-redux + react-saga

Focus: Component updates, page unchanged

Upper demo:

2.1 Memory Logic

Idea: But divided into active memory and open memory, two memory colleagues update, switch Tag to fetch data from an open array, use the data, and initiate requests without data.

  • Tag array clicked on the tagList sidebar
  • Tag of active Tag activity state

The operation is also in Reduce, which facilitates the internal and external interaction of subsequent Tag s.

/*.
Directory: / 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
    }
  },
  // ...
}

All memory initial states are operated in App. JS - > component DidUpdate lifecycle memory

/*
Directory: / 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 : '/'
    })
  }
}

2.2 External Interaction Logic

  1. Side Bar Logic, Added
  2. Click Logic to Switch Tag
  3. Close Tag

class App extends Component {
  // Click on the sidebar
  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: {}
    }

    //Judging whether it is a new addition
    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}`)
  }
  // Click 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)
  }
  // Close logic
  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 : '/')
  }

  // ...
}

2.3 Internal Interaction Logic

  • Judging whether there is a new addition
  • Operation update onChange, onClear, onSubmit

Use markup symbols, or directly determine whether a key value exists, to send requests. Data Source is used in demo to determine whether requests need to be sent.


componentDidMount() {
  const { tabListStatus, musicList_query_param, musicList } = this.props
  const { dataSource } = tabListStatus.activeTab

  if (!Object.keys(dataSource).length) {
    musicList(musicList_query_param)
  }
}

Operations update onChange, onClear, onSubmit in addition to these there will be different operations, demo roughly divided these operations, using reducer operations, App.js to monitor operations, change memory, module does not participate in memory changes.


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)
}

3. Contrast

Implementation of 3.1 Vue

  • Technology stack: vue + vue-router + vuex
  • UI Framework: ant-design

Key: keep-alive

3.2 Realization of React

  • Technology stack: react + react-router + redux
  • UI Framework: ant-design

Key: redux and memory processing

4. Summary

It's certainly faster for Vue to implement the above, but it's also a very interesting thing to control the use of React memory. If the project is large, it's even more interesting.

In fact, this implementation is a bit of a chicken rib, because users do not pay attention to one, closed the page, these Tag s do not exist, no matter what kind of management system, this implementation may be more interesting if cooperated with the background.

Thank @ White Thank you [@colleagues](), they all provide good ideas.

Thank you for reading. The code is rotten. Please spray it lightly.

Keywords: Javascript React Vue JSON

Added by dkphp2 on Thu, 08 Aug 2019 10:13:58 +0300