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

实际应用场景:

组件复用,如当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);是我实践之后解决该类问题方法

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值