0


前端数据字典最优方案讨论

简介:大家好,我是程序员枫哥,🌟一线互联网的IT民工、📝资深面试官、🌹Java跳槽网创始人。拥有多年一线研发经验,曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队,目前业余时间专注Java技术分享,春招/秋招/社招/跳槽,一对一学习辅助,项目接活开发。
🌈更多学习内容, 欢迎👏关注👀【文末】微信公众号:IT枫斗者
🌟🌟程序员找工作,就上Java跳槽网:www.javatiaocao.com

前端🦒数据字典🦒最优方案讨论

什么是数据字典

  • 数据字典是项目中常用的数据维护方式之一,其优势在于用户可以自行配置数据类型,并且在不需要更新系统的情况下,将数据下发到客户端
  • 字典是一种数据结构,它由键值对组成,其主要特点是键与值之间是一一对应的关系。在字典中,键是唯一且无序的,而值可以重复。键通常用于在前后端之间进行数据传输或在代码中进行逻辑判断,而值则用于向用户展示相关信息。因此,字典提供了一种便捷的方式来存储和管理数据,同时确保了数据的唯一性和关联性。
  • 一种常见的实现方式是在后台管理系统中设置一个数据字典模块,服务端提供一套用于对数据字典进行增删查改的维护接口。客户端可以通过服务端提供的通用数据字典查询接口,提供数据字典码,从而获取数据列表,以便用户在下拉选择中使用。这种方法使得数据的管理和更新变得更加灵活和高效,同时也为用户提供了更好的定制化和选择性。
  • 如果系统中,包含大量的单选或者多选下拉框,建议使用数据字典方案。
  • 举个最简单的例子,表单有个字段是单选选择是否的。那它对应的数据字典对应:
  • [ { key: "1", value: "是" }, { key: "2", value: "否" },];

实现方案

维护在客户端

  • 将数据字典维护在客户端(即前端)与将其维护在服务器端相比,有一些优缺点和适用场景。
  • **优点**1. 减少网络请求:如果数据字典包含了前端应用所需的大量静态数据,将其维护在客户端可以减少对服务器的请求,提高应用性能和响应速度。2. 离线访问:客户端数据字典可以使应用在离线状态下仍然能够访问和展示数据,提高了应用的稳定性和用户体验。3. 减轻服务器负担:将数据字典放在客户端可以减轻服务器的负担,特别是对于大量用户同时访问的应用。
  • **缺点**1. 安全性:将数据字典维护在客户端可能会面临安全风险,特别是对于敏感数据或需要保密的数据。因为客户端数据可以被用户直接访问和修改,存在被篡改或窃取的风险。2. 维护难度高:字典表必须与后端保持一致,维护难度较高,稍有疏忽就可能导致前后端数据不匹配。尽管字典不经常被修改,但这并不意味着永远不会发生变更。一旦字典发生修改,前端就需要进行代码更新、打包和部署等操作,无形中增加了维护难度。3. 占用客户端资源:大规模的数据字典可能会占用较多的客户端资源,尤其是对于移动端设备来说可能会影响应用的性能和用户体验。4. 前端背锅:出现1或者2的问题,肯定领导会找你,唉,锅都是前端背的。
  • **适用场景**1. 静态数据:如果数据字典中的数据相对静态,不经常变化,并且对安全性要求不高,那么将其维护在客户端是一个不错的选择。2. 离线应用:对于需要在离线状态下也能正常访问数据的应用,客户端数据字典可以发挥作用。总的来说,将数据字典维护在客户端适用于静态数据、离线应用和需要减轻服务器压力的情况。然而需要注意的是,对于涉及安全性、数据同步和资源占用等方面的考量,需要综合权衡才能确定是否将数据字典维护在客户端。

登陆一次性返回所有数据字典

  • 这种方案是将数据字典维护在服务端,可以在客户端页面进行数据字典进行配置。用户在登录成功后,或者在已经登录状态时,刷新页面,会调用一次数据字典接口获取所用的数据字典,并进行缓存。当使用的时候,直接从缓存中获取即可。
  • 这种方案也是比较常用的,可以一次性返回所有数据字典,减少后台接口的请求,也不用考虑接口重复的问题。但这种方案一般适用于数据字典数据量不大的情况。如果数据字典数据量过大,增加加载和处理数据的时间和成本,也会出现很多字典不使用,造成浪费的问题。
  • 同时针对数据字典实时修改的问题,可以通过刷新进行数据字典同步

使用哪个请求哪个

  • 这种方案是只有在要使用的时候,才会通过后台接口,请求对应的数据字典,并进行缓存。例如:表单下拉选择框,表格字段的转义。
  • 这种方案适用于有很多数据字典的情况。用什么请求什么,如果有缓存,直接使用缓存结果即可。这种方案也是比较常见的,也是我们项目正在使用的方案。
  • 但这种方案也存在两个问题: - 要处理重复请求的问题,因为在表单中可能存在不同的表单字段使用相同的数据字典,而且可能相同的接口不少。所以要处理重复请求的问题。- 字典更新问题:字典一般是由业务进行维护,一般不进行修改。如果有修改,也只能通过本地刷新来更新数据字典。字典更新问题是数据字典,很难解决的问题,因为前端不知道什么时候字典会进行更新。
  • 我看有的方案是在存储的数据字典中加一个调用的次数,如果次数很多,说明经常使用,当使用次数达到一个值时,就会重新进行请求。个人感觉这种方案治标不治本,甚至不必要,例如是否这个字典,一般是经常使用的,但这种一般不会更新。

缓存位置方案

  • 在前端将数据字典存储在本地(即客户端)有一些优点和缺点,以下是一些可能的优缺点:
  • 优点:1. 快速访问: 将数据字典存储在本地可以减少对服务器的请求次数,提高数据的访问速度。2. 离线访问: 当用户处于离线状态时,本地存储的数据字典仍然可以被访问,提高了应用程序的可用性。3. 减轻服务器压力: 将数据字典存储在本地可以减少服务器的负载,降低服务器的压力。4. 减少网络流量: 不需要每次都从服务器获取数据字典,可以减少网络流量和数据传输成本。
  • 缺点:1. 安全风险: 存储在客户端的数据可能受到篡改或窃取的风险,尤其对于敏感数据或需要保密的数据,安全性不如服务器端存储。2. 数据同步: 如果数据字典发生变化,需要确保所有客户端都及时更新,否则可能导致数据不一致的问题。3. 存储限制: 不同的浏览器和存储机制都有各自的存储限制,可能会受到容量限制或性能影响。4. 客户端资源占用: 大规模的数据字典可能会占用较多的客户端资源,特别是对于移动端设备来说可能会影响应用的性能和用户体验。
  • 综上所述,将数据字典存储在本地可以提高应用程序的性能和可用性,但也需要考虑数据同步、安全性、存储限制和数据一致性等方面的问题。在具体应用场景中,需要综合考虑这些因素,权衡利弊,选择合适的存储方式。
  • 但是将数据字典存储在本地是利大于弊的,我们只能通过合适的本地存储方案,降低它的缺点出现的可能性
  • 将数据字典存储在哪里,一般主要有两种方案进行选择,分别是: - 本地存储:localStarge/sessionStrage- 框架自带的状态管理库:例如Vue的Vuex/Pinia,React的Redux/Mobx

localStorage

  • 将数据字典存储在localStorage的优缺点如下:
  • 优点:1. 持久性存储: localStorage中存储的数据在浏览器关闭后仍然保留,可以实现持久性存储,适合长期保存数据。但是对于数据字典而言,持久性存储可能会导致数据字典无法更新同步的问题。2. 容量大: localStorage的存储容量相对较大,一般在5MB左右,适合存储较大量的数据字典。3. 简单易用: 使用localStorage进行数据存储非常简单,只需使用JavaScript的localStorage API即可实现数据的读写操作。
  • 缺点:1. 安全性: localStorage中存储的数据对用户可见,存在被篡改或窃取的风险,不适合存储敏感数据。2. 同步问题: 当数据字典需要频繁更新时,需要考虑如何与服务器端数据保持同步。3. 单线程: localStorage的读写是单线程的,可能会影响性能,特别是在大量数据读写时。
  • 综上所述,将数据字典存储在localStorage的优点是数据永久存储、跨页面访问、容量较大和简单易用,但缺点是安全性不足、同步问题和存储限制。在使用localStorage存储数据字典时,需要注意数据安全性和同步更新的问题,并合理利用localStorage提供的功能。
  • 将数据字典存储在sessionStorage的优缺点如下:
  • 优点:1. 临时存储: 数据存储在sessionStorage中是临时性的,仅在当前会话期间有效,当用户关闭浏览器标签或窗口时数据会被清除。2. 跨页面访问: 存储在sessionStorage中的数据可以在同一浏览器窗口或标签页中共享和访问。3. 简单易用: sessionStorage提供了简单的API,方便存储和获取数据。
  • 缺点:1. 数据丢失: 数据存储在sessionStorage中会在用户关闭浏览器标签或窗口时被清除,可能导致数据丢失。2. 安全性: 与localStorage一样,存储在sessionStorage中的数据也存在安全性问题,容易受到XSS攻击。
  • 总结而言,将数据字典存储在localStarge中的最大的缺点是对用户可见,可能被篡改;以及数据同步的问题,因为这两种方案都不能设置过期时间,只能另外设置:例如监听刷新页面时,将本地缓存进行清空和重新存储。

状态管理库

  • 将数据字典存储在前端框架的状态管理库中,它有什么优缺点呢。这里以Vue的Vuex进行举例。
  • 将数据字典存储在Vuex的优缺点如下:
  • 优点:1. 集中管理: Vuex可以帮助前端集中管理数据字典,统一存储和更新数据,方便数据的管理和维护。2. 响应式: 存储在Vuex中的数据会响应式地更新,当数据发生变化时,相关组件会自动更新。3. 数据共享: 存储在Vuex中的数据可以在整个应用程序中共享和访问,不受页面或组件的限制。4. 状态管理: Vuex提供了一套完整的状态管理机制,可以帮助前端更好地管理应用程序的状态。
  • 缺点:1. 复杂性: 使用Vuex需要学习和理解其概念和机制,对于小型项目可能会增加开发成本。2. 适用范围: 对于简单的数据字典存储需求,引入Vuex可能显得过于复杂,不够轻量级。3. 性能: 在存储大量数据时,Vuex可能会影响应用程序的性能,需要谨慎使用。
  • 我们可以看到,将数据存储在前端框架的状态管理库中, - 可以避免对用户可见,避免用户篡改。- 时如果不对数据字典进行持久性存储,当页面刷新的时候,会重新存钱数据字典,缓解数据字典不同步的问题

数据字典Store方法封装

Vuex数据字典Store方法封装

  • 这里我们也以Vue框架的Vuex进行示例,其他状态管理库也是相类似的。
  • 我们在上文中也讲到了,数据字典可能存在重复请求的问题。这里我们按照以下流程进行封装:
  • 在这里插入图片描述
  • 首先判断它对应的数据字典是否已经存在,若存在,则直接使用缓存数据
  • 如果不存在,说明要进行网络请求,得到对应的数据字典数据。首先判断它是否是重复请求,如果是,则返回相同字典的请求数据。(这里我们是使用dicCode字段判断是重复请求的,其中dicCode是字典对应的唯一编码值)
  • 如果不是,首先加入请求集合,便于后面判断是否是重复请求。请求成功后,将数据进行存储,并删除请求集合里的自身对应的数据。
  • 完整代码如下:
  • import { getDicts as getDicDataList } from '@/api/system/dict/data'const state = { dictDataList: {}, requestDictList: new Set()}const getters = { getDictLabel: (state) => (dicType, dictValue) => { const dictList = state.dictDataList[dicType] || [] if(dictValue && dictValue.includes(",")){ const arr = val.split(","); return arr.map(item => dictList.find(o => String(o.dicItemCode) === String(item))).join(","); } const dictItem = dictList.find(item => String(item.dicItemCode) === String(dictValue)) || {} return dictItem.dicItemName || dictValue }}const mutations = { setDictDataList (state, dictDataList) { state.dictDataList = { ...state.dictDataList, ...dictDataList } }, pushRequestDictList (state, dictType) { state.requestDictList.add(dictType) }, spliceRequestDictList (state, dictType) { state.requestDictList.delete(dictType) }}const actions = { async getDictData ({ commit, state }, dictType) { if (Array.isArray(dictType)) { // 多个数据字典请求 const dicTypesRequest = dictType.filter(dictType => !state.dictDataList[dictType]) if (dicTypesRequest.length === 0) { return state.dictDataList } const { data } = await getDicDataList(dicTypesRequest) commit('setDictDataList', data) return state.dictDataList } else if (typeof dictType === 'string') { if (!state.dictDataList[dictType]) { if (!state.requestDictList.has(dictType)) { commit('pushRequestDictList', dictType) const { data } = await getDicDataList(dictType) commit('setDictDataList', { [dictType]: data || [] }) commit('spliceRequestDictList', dictType) return data } } else { return state.dictDataList[dictType] } } }, updateDictData({ commit, state }, dictType) { if (!state.requestDictList.has(dictType)) { commit('pushRequestDictList', dictType) return getDicDataList(dictType).then(({ data }) => { commit('setDictDataList', { [dictType]: data || [] }) return data }).finally(() => { commit('spliceRequestDictList', dictType) }) } }}export default { namespaced: true, state, getters, mutations, actions}
  • 总体来说,这个模块实现了以下功能:
  • 根据字典类型获取对应的字典数据,并且可以处理多个字典类型的请求。
  • 在数据请求过程中对重复请求进行了控制,避免重复请求相同的字典类型。

lodash.memoize

  • 在上述的代码中,我们是使用请求集合来判断是否是重复的数据字典请求。后面看了一些文章,发现可以使用loadsh函数中的memoize方法进行重复请求的判断。既缓存又像平常请求一样调用。
  • lodash.memoize是由流行的JavaScript实用程序库Lodash提供的一个函数。它用于对函数的结果进行记忆化,这意味着它根据传递给它的参数缓存函数的结果。对具有相同参数的函数的后续调用将返回缓存的结果,而不是重新执行函数
  • 以下是关于lodash.memoize如何工作的简要概述:1. 它接受两个参数: - func:要进行记忆化的函数。- resolver:一个可选函数,根据传递给记忆化函数的参数确定存储结果的缓存键。2. 当首次使用特定参数调用记忆化函数时,lodash.memoize会计算该参数的函数结果,并将其存储在缓存中。3. 对具有相同参数的记忆化函数进行后续调用将返回缓存的结果,而不是重新执行函数。4. 如果使用不同参数调用记忆化函数,它将为这些参数计算结果并分别进行缓存。
  • 以下是如何使用lodash.memoize的简单示例:
  • const memoizedFunction = _.memoize((arg1, arg2) => { console.log('执行带参数的函数:', arg1, arg2); return arg1 + arg2;});​console.log(memoizedFunction(1, 2)); // 这将执行函数并返回3console.log(memoizedFunction(1, 2)); // 这将返回缓存的结果(3)而不重新执行函数console.log(memoizedFunction(3, 4)); // 这将使用新参数执行函数并返回7
  • 在这个示例中,传递给lodash.memoize的函数将仅对每组唯一参数执行一次,并且对具有相同参数的后续调用将返回缓存的结果。

方法封装

  • import store from '@/store'// 数据字典请求export function getDictData (dictType) { return store.dispatch('dataDictionary/getDictData', dictType)}// 数据字典转义export function getDictLabel (dictType, dictValue) { // 初始化 拉取字典数据 getDictData(dictType).catch(error => { }) return store.getters['dataDictionary/getDictLabel'](dictType, dictValue)}
  • 通过全局方法的封装,我们可以更加方便地在表单获取下拉数据或者表格字典转义中使用。

本文转载自: https://blog.csdn.net/Andrew_Chenwq/article/details/139971246
版权归原作者 IT枫斗者 所有, 如有侵权,请联系我们删除。

“前端数据字典最优方案讨论”的评论:

还没有评论