资讯专栏INFORMATION COLUMN

管理系统内 Tag 功能的实现

Tikitoo / 3364人阅读

摘要:愈发纯熟的业务代码开始做菜原文地址背景需求分析背景某日,被后台拿着一个别人实现好的管理系统说道了一顿,说需要实现得比某框架更好地址需求分析需求管理系统内实现浏览器标签的功能分析切换不主动更新页面重点关闭活动中的切换至后一个若关闭为最后一个,

愈发纯熟的业务代码——开始做菜

原文地址

1.背景 && 需求分析 1.1 背景

某日,被后台拿着一个别人实现好的管理系统说道了一顿,说需要实现得比某框架更好

地址:pig4cloud

1.2 需求分析

需求:管理系统内实现浏览器 Tag 标签的功能

分析:

切换 Tag 不主动更新页面(重点)

关闭活动中的 Tag 切换至后一个

若关闭 Tag 为最后一个,切换至前一个

2. 实现逻辑

技术栈:react + react-router + react-redux + react-saga

重点:组件更新,页面不变

上 demo :

2.1 内存逻辑

思路:却分活动状态内的存,和在打开过的内存,两个内存同事更新,切换 Tag 从打开过的数组内调取数据,有数据使用该数据,无数据则发起请求

tagList 侧栏点击过的 Tag 数组

activeTag 活动状态的 Tag

操作同归在 Reduce 内,方便后续 Tag 内外部交互

/*.
目录:/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 : "/"
    })
  }
}
2.2 外部交互逻辑

侧栏逻辑,新增

点击逻辑,切换 Tag

关闭 Tag

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 : "/")
  }

  // ...
}
2.3 内部交互逻辑

判断是否新增

操作更新 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)
}
3. 对比 3.1 Vue 的实现

技术栈:vue + vue-router + vuex

UI 框架:ant-design

关键:keep-alive

3.2 React 的实现

技术栈:react + react-router + redux

UI 框架:ant-design

关键:redux 与内存处理

4. 总结

实现上面肯定是 Vue 更快实现的,但对使用 React 内存的控制也是一件非常好玩的事情,如果项目大了,就更好玩了

实际上这种实现有点鸡肋,因为用户一个不留意,关了页面,这些 Tag 就不存在了,无论是那种管理系统,这个实现如果配合到后台,可能就更好玩了

感谢 @白白,感谢 @同事,都提供了很不错的思路

感谢阅读,代码很烂,请轻喷

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106544.html

相关文章

  • FastD 最佳实践四: 构建系统可视化监控

    摘要:的展示非常炫酷,绝对是运维提升逼格的一大利器。另外的可视化功能比强得多,而且以上版本将集成报警功能。它由写成,着力于高性能地查询与存储时序型数据。被广泛应用于存储系统的监控数据,行业的实时数据等场景。 原有监控系统 showImg(https://segmentfault.com/img/remote/1460000011082384); 整个系统以 Graphite (carbon ...

    khlbat 评论0 收藏0
  • 数据聚合 & 分组:新一代系统监控核心功能

    摘要:而今,我们就已经实现了这样的功能使用标签来实现数据的聚合和分组。数据聚合和分组在中,我们实现了数据的聚合和分组。指所需聚合的的查询条件。所以,与会聚合为一条曲线,而和的关系是分组的关系。 遥想 2015 年 8 月 17 日,Cloud Insight 还在梳理功能原型,畅想 Cloud Insight 存在的意义:为什么阿里云用户需要使用 Cloud Insight 来加强管理。 而...

    lijinke666 评论0 收藏0
  • 开源一个监控数据采集Agent:OpenFalcon-SuitAgent

    摘要:目前此系统仅支持类系统下使用,不支持系统什么是这是一个获取各种系统的监控数据的。监控数据上报公有的跟官方社区的思想一致采集的系统监控信息如内存等等一百多种没有任何信息其他的业务系统的监控都会打上。 OpenFalcon-SuitAgent 项目地址:github 版本说明 本系统版本划分如下 alpha:内部测试版(不建议使用于生产环境) beta:公开测试版(不建议使用于生产环境)...

    linkin 评论0 收藏0
  • 开源一个监控数据采集Agent:OpenFalcon-SuitAgent

    摘要:目前此系统仅支持类系统下使用,不支持系统什么是这是一个获取各种系统的监控数据的。监控数据上报公有的跟官方社区的思想一致采集的系统监控信息如内存等等一百多种没有任何信息其他的业务系统的监控都会打上。 OpenFalcon-SuitAgent 项目地址:github 版本说明 本系统版本划分如下 alpha:内部测试版(不建议使用于生产环境) beta:公开测试版(不建议使用于生产环境)...

    王晗 评论0 收藏0

发表评论

0条评论

Tikitoo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<