Vue3变量全局化+响应式+懒加载+初始化+性能提升(避免重复请求)
创始人
2024-11-11 14:12:08
实际应用场景:

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

popProp}>    {CCOptions.map((item, index) => (      index}        value={item.value}        label={item.label}        popup-props={{          overlayClassName: "tdesign-demo-select__overlay-option",        }}      >        {item.label}        {item.count && ({item.count})}          ))}   

解决问题逻辑:

  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 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();  }; 
 popProp}>    {CCOptions.map((item, index) => (      index}        value={item.value}        label={item.label}        popup-props={{          overlayClassName: "tdesign-demo-select__overlay-option",        }}      >        {item.label}        {item.count && ({item.count})}          ))}   

你需要明白:

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);是我实践之后解决该类问题方法

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...