组件复用,如当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})} ))} // 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; }; // 商品类目 const CommodityCategoryData: T = { Options: [], totalRecords: 0, currentPage: 0, pageSize: 15, }; //另外的脚本文件 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(); 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);是我实践之后解决该类问题方法