title: 组件存储缓存

组件存储缓存

组件存储缓存作为 AMS 存储的其中一个模块主要用于存储页面级所有通过 JSON 创建的 组件。组件存储缓存会随着 页面加载时缓存所有JSON创建的组件并在页面销毁时随之销毁。 之所以将这么一个模块单独记录成一个文档是因为 这个组件存储缓存机制会直接影响后面章节中的组件交互

注意: 理解这个章节有助于后续理解组件交互

组件存储缓存部分源码

源码部分可能在未来存在更新,如果同步不及时可以提出 github issuegithub pull request

  1. export interface ICacheValue {
  2. registryName: keyof typeof registries;
  3. componentName: string;
  4. props: IAnyObject;
  5. key: string;
  6. source: IAnyObject;
  7. }
  8. export interface ICache {
  9. [key: string]: ICacheValue;
  10. }
  11. /**
  12. * 组件缓存存储对象
  13. */
  14. class ComponentStoreCaches {
  15. ...
  16. /**
  17. * 通过 key 进行搜索
  18. * @param {string} key - 缓存中的唯一标识, 也是组件中 key 唯一标识组件
  19. */
  20. public searchByKey(key: string): ICacheValue | null {
  21. const searchResult = this.search({ key });
  22. return searchResult[0] || null;
  23. }
  24. /**
  25. * 通过短名称进行快速搜索, 组合方式为 "<registryName:componentName>" 例如:
  26. * searchByShortName('html:a');
  27. * 其中:
  28. * registryName: 'html',
  29. * componentName: 'a'
  30. *
  31. * 对于仅需要搜索 registryName 时: searchByShortName('html');
  32. *
  33. * 对于仅需要搜索 componentName 时: searchByShortName(':a');
  34. * @param {string} shortName - 短名
  35. */
  36. public searchByShortName(shortName: string): ICacheValue[] {
  37. if (!shortName) {
  38. throw new error.UnexpectedError('参数 shortName 不能为空, 常规用法: searchByShortName(\'html:a\')');
  39. }
  40. const splits = shortName.split(':');
  41. const registryName = splits[0] as ICacheValue['registryName'];
  42. const componentName = splits[1];
  43. if (registryName && componentName) {
  44. return this.search({ registryName, componentName });
  45. }
  46. if (registryName) {
  47. return this.search({ registryName });
  48. }
  49. return this.search({ componentName });
  50. }
  51. /**
  52. * 高级查询
  53. * @param {} searchCondition - 查询条件, 可以使用 ICacheValue 中的值进行比对查询
  54. * 例如:
  55. * // 找出所有 registryName = 'antd' 的缓存值
  56. * searchCondition = {
  57. * registryName: 'antd'
  58. * };
  59. * // 找出所有 componentName = 'a' 的缓存值
  60. * searchCondition = {
  61. * componentName: 'a'
  62. * };
  63. */
  64. public search(searchCondition: Partial<ICacheValue>): ICacheValue[] {
  65. const { key } = searchCondition;
  66. if (key) {
  67. const cacheValue = this.get(key);
  68. return cacheValue ? [cacheValue] : [];
  69. }
  70. const { cache } = this;
  71. return Object.keys(cache).reduce((founds, cacheKey) => {
  72. const cacheValue = cache[cacheKey];
  73. if (this.checkOverlap(searchCondition, cacheValue)) {
  74. founds.push(cacheValue);
  75. }
  76. return founds;
  77. }, [] as ICacheValue[]);
  78. }
  79. }
  80. const componentStoreCaches = new ComponentStoreCaches();
  81. /**
  82. * 仅用于本地测试, 禁止作为其他用途
  83. */
  84. if (process.env.NODE_ENV === 'development') {
  85. (window as any).componentStoreCaches = componentStoreCaches;
  86. }
  87. export default componentStoreCaches;

用法

通过上述源码,我们基本能够了解如下几点:

  1. 在 development 环境时,开发者可以通过 window.componentStoreCaches 获取该对象
  2. public 方法为允许外部使用的方法
    • componentStoreCaches.search
    • componentStoreCaches.searchByShortName
    • componentStoreCaches.searchByKey
  3. 其中 search 为基础通用搜索,searchByShortNamesearchByKey 为基于 search 函数的拓展函数

componentStoreCaches.search 为高级查询,函数的参数 search(searchCondition: Partial<ICacheValue>) 中的 searchCondition 搜索条件很容易理解, 搜索条件只要是所属 ICacheValue 值即可搜索出结果,举个例子:

  1. // 当前缓存列表存在的缓存值
  2. {
  3. 'auto-1586876874713-2': {key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}
  4. 'auto-1586876874713-3': {key: 'auto-1586876874713-3', source: Proxy, registryName: "antd", componentName: "Card.Meta", props: {…}, lifecycle: undefined, …}
  5. 'auto-1586876874713-4': {key: 'auto-1586876874713-4', source: Proxy, registryName: "antd", componentName: "Card", props: {…}, lifecycle: undefined, …}
  6. 'auto-1586876874713-5': {key: 'auto-1586876874713-5', source: Proxy, registryName: "antd", componentName: "Card.Grid", props: {…}, lifecycle: undefined, …}
  7. 'auto-1586876874713-6': {key: 'auto-1586876874713-6', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}
  8. 'auto-1586876874713-7': {key: 'auto-1586876874713-7', source: Proxy, registryName: "antd", componentName: "Card.Meta", props: {…}, lifecycle: undefined, …}
  9. 'auto-1586876874713-8': {key: 'auto-1586876874713-8', source: Proxy, registryName: "antd", componentName: "Card", props: {…}, lifecycle: undefined, …}
  10. }

这时我们希望搜索出 key = 'auto-1586876874713-2' 的一项:

  1. window.componentStoreCaches.search({key: 'auto-1586876874713-2'});
  2. // returns:[ {key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …} ]

或者可以使用 searchByKey, 由于 key 是唯一的,所以返回值将直接获得最终的对象结果而非数组:

  1. window.componentStoreCaches.searchByKey('auto-1586876874713-2');
  2. // returns:{key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}

我们也可以直接使用非 key 的比对搜索,如:

  1. window.componentStoreCaches.search({registryName: 'html', componentName: 'div'});
  2. // returns:[
  3. // {key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …},
  4. // {key: 'auto-1586876874713-6', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}
  5. // ]

为了让使用者有更便捷的体验,我们还提供了 searchByShortName 的简便用法, 基本结构如下:

  1. window.componentStoreCaches.searchByShortName('<registryName>:<componentName>');

searchByShortName 的基本用法:

  1. window.componentStoreCaches.searchByShortName('html:div');
  2. // returns:[
  3. // {key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …},
  4. // {key: 'auto-1586876874713-6', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}
  5. // ]

我们也可以只搜索 registryName

  1. window.componentStoreCaches.searchByShortName('html');
  2. // returns:[
  3. // {key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …},
  4. // {key: 'auto-1586876874713-6', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}
  5. // ]

我们也可以只搜索 componentName, 需要注意的是,我们需要加上 : 用于标识搜索字段为 componentName

  1. window.componentStoreCaches.searchByShortName(':div');
  2. // returns:[
  3. // {key: 'auto-1586876874713-2', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …},
  4. // {key: 'auto-1586876874713-6', source: Proxy, registryName: "html", componentName: "div", props: {…}, lifecycle: {…}, …}
  5. // ]