Vue3变量全局化+响应式+懒加载+初始化+性能提升(避免重复请求)

avatar
作者
猴君
阅读量:0
实际应用场景:

组件复用,如当select里面的选项options是走后端动态获取的,如果把网络请求放在组件内部,当单页面多次引用该组件,则获取选项的请求也将发送多次。例如下面这个select组件的CCOptions,需要变量全局化+响应式+懒加载+初始化+性能提升(避免重复请求)。文章末尾附上你需要明白的Vue3 reactive特性!希望你能看到最后。

<t-select popup-props={popProp}>    {CCOptions.map((item, index) => (      <t-option        key={index}        value={item.value}        label={item.label}        popup-props={{          overlayClassName: "tdesign-demo-select__overlay-option",        }}      >        {item.label}        {item.count && <a style="color: var(--td-brand-color)">({item.count})</a>}      </t-option>    ))}  </t-select> 

解决问题逻辑:

  1. 将Function放在全局脚本文件(global.js)内部,按需获取,并且作为导出常量(export const)。例如下面的代码:
// global.ts // 商品类目 export const getCommodityCategoryOptions = async () => {   let next_page = CommodityCategoryData.currentPage + 1;   let next_pageSize = CommodityCategoryData.pageSize;   if (     CommodityCategoryData.Options.length > next_page * next_pageSize ||     CommodityCategoryData.totalRecords < next_pageSize * (next_page - 1)   ) {     // 数据已加载过了或者已经加载完毕     return CommodityCategoryData.Options;   }   await getCommodityCategoryApi({     page: next_page,     pageSize: next_pageSize,   })     .then((result: any) => {       CommodityCategoryData.Options.push(         ...map(result.PagedList, (item: any) => {           return {             label: item.CategoryName ? item.CategoryName : "",             value: item.CategoryID,             count: item.Count,           };         })       );       CommodityCategoryData.totalRecords = result.TotalRecords;       CommodityCategoryData.currentPage = result.PageNo;     })     .catch((err) => {       MessagePlugin.error(err.message);     });   return CommodityCategoryData.Options; };     MerchantClassificationData.Options.length >= next_page * next_pageSize ||     MerchantClassificationData.totalRecords < next_pageSize * (next_page - 1)   ) {     // 数据已加载过了或者已经加载完毕     return MerchantClassificationData.Options;   }   await getMerchantClassificationApi({     page: next_page,     pageSize: next_pageSize,   })     .then((result: MerchantClassificationModel) => {       MerchantClassificationData.Options.push(         ...map(result.PagedList, (item: MerchantModel) => {           return {             label: item.CategoryName,             value: item.CategoryID,             count: item.Count,           };         })       );       MerchantClassificationData.totalRecords = result.TotalRecords;       MerchantClassificationData.currentPage = result.PageNo;     })     .catch((err) => {       MessagePlugin.error(err.message);     });   return MerchantClassificationData.Options; }; 
  1. 将获取到的结果数据存在在全局脚本内部,作为常量就够了(const)。例如下面的代码:
// 商品类目 const CommodityCategoryData: T = {   Options: [],   totalRecords: 0,   currentPage: 0,   pageSize: 15, };  
  1. 优化的关键是请求数据的方法避免重复请求,例如分页获取的数据,可以通过判断该数据是否获取过,以此减少请求次数,达到优化性能的目的;
  2. 数据默认在单页面import的脚本文件里面初始化一次。例如下面的代码:
//另外的脚本文件 export const CCOptions = reactive<Array<{ label: string; value: string; count: number }>>([]); export const getCCOptions = () => {   getCommodityCategoryOptions().then((res) => {     while (CCOptions.length > 0) CCOptions.pop();     CCOptions.push(...res);   }); }; if (Dom_IsExist.formItem_goodsCategory_used) getCCOptions(); 
  1. 最后只需要在单页面中引用CCOptions 和getCCOptions 方法就可以实现数据响应式
import { CCOptions, getCCOptions } from "@/config/appManager"; 

我的组件业务逻辑:

const popProp = {   onScrollToBottom: handleScrollToBottom_MerchantClassification,  }; const handleScrollToBottom_MerchantClassification = () => {   getCCOptions();  }; 
 <t-select popup-props={popProp}>    {CCOptions.map((item, index) => (      <t-option        key={index}        value={item.value}        label={item.label}        popup-props={{          overlayClassName: "tdesign-demo-select__overlay-option",        }}      >        {item.label}        {item.count && <a style="color: var(--td-brand-color)">({item.count})</a>}      </t-option>    ))}  </t-select> 

你需要明白:

1、const+reactive+Array的定义,不能将变量直接=[],因为reactive只响应刚开始那个引用地址;也不能因为报错把const改成let;这样确实不会报错了,但是同样使用=[]之后,变量就不会拥有响应式了。

2、export let CCOptions =
reactive([]);如果使用CCOptions=reactive([…res])则在引用CCOptions的地方也将失去响应式。因为reactive
是跟着括号里面的变量走的;
3、综上所述:while (CCOptions.length > 0) CCOptions.pop();
CCOptions.push(…res);是我实践之后解决该类问题方法

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!