了解学习和编写npm库 学习工程化 扎实前端功底 有助于我们提升核心竞争力
计算属性中使用ref会导致二次刷新吗
在Vue 2中,使用计算属性中的ref并不会导致二次刷新。当计算属性中的依赖项发生变化时,计算属性会重新计算,并返回一个新的值。如果该计算属性中使用了ref,则该值将被更新,但它不会导致额外的计算属性更新。
然而,在Vue 3中,使用计算属性中的ref可能会导致额外的刷新。这是因为Vue 3使用了Proxy来实现响应式,而ref实际上是使用了一种特殊的Proxy对象。当ref所引用的值发生变化时,Proxy对象会将变化通知给Vue,从而触发组件的重新渲染。因此,如果计算属性中使用了ref,则可能会导致计算属性和组件进行额外的刷新。
数据合并的优化代码
const dataSplice = async (res: any[], type: string | number) => {
const tasks = res.map((item) =>
tree<any>(type, item.id).then((child) => ({
...item,
level: 1,
children: child.data.tree_data.children,
}))
);
const tree_data = await Promise.all(tasks);
console.log('tree_data', tree_data);
return tree_data;
};
在优化后的代码中,我们首先使用Array.prototype.map()方法创建了一个由异步任务(即获取每个元素的子节点)组成的数组tasks。这里我们使用了箭头函数和Promise.then()语法来处理异步结果,并将每个异步任务包装成了一个对象。
然后,我们使用Promise.all()方法等待所有异步任务完成,并返回一个包含每个异步任务结果的数组tree_data。在异步任务完成后,我们将每个元素的属性值,如level和children,合并到新的对象中,并将其推入tree_data数组中。
使用Promise.all()可以并行执行异步任务,从而显著提高性能。请注意,在异步任务之间不存在依赖关系时,使用Promise.all()可以使得所有异步任务同时运行,从而更快地完成整个操作。
合并对象数组
const dataSplice = async (
res: any[],
type: string
): Promise<{ counts: { [key: number]: number }, tree_data: any[] }> => {
const counts: Counts = {};
const tasks = res.map((item, index) =>
tree<any>(type, item.id).then(child => {
const count_data = child.data.count_data;
counts[index] = count_data; // 使用索引来设置每个元素的值
return {
...item,
id: item.name, // 添加 id 属性
level: 1,
children: child.data.tree_data.children,
};
})
);
const tree_data = await Promise.all(tasks);
const mergedCounts = Object.values(counts).reduce((acc, cur) => ({
...acc,
...cur,
}), {});
console.log('counts', mergedCounts);
// 返回 counts 和 tree_data 对象数组
return { counts: mergedCounts, tree_data };
};
reduce()方法可以用于将一个数组转换成另一个类型的值,例如对象或字符串。在这个例子中,我们使用reduce()方法将一个包含数字索引的对象转换为一个不带数字索引的对象,并合并其中的所有属性。
下面是具体的实现方式:
- 我们首先调用
Object.values(counts)方法,将输入对象counts中的所有值转换成一个数组。该数组中包含了counts对象中所有属性值,按照数字索引的顺序排列。 - 然后,我们使用
reduce()方法遍历该数组,并在每次迭代中将当前元素与累加器对象合并。累加器对象会在每次迭代中不断更新,以反映当前已经处理过的所有属性。 - 在每次迭代中,我们使用对象展开运算符 (
...) 将当前元素与累加器对象合并。由于对象属性必须是唯一的,因此在处理重复的属性时,后面的值会覆盖前面的值。最后,我们返回累加器对象作为结果。 - 最后,由于可能存在输入对象为空的情况,我们传递一个空对象
{}作为初始值。这个空对象会在第一次迭代中被作为累加器对象传递给reduce()方法。
下面是具体的代码实现:
typescript复制代码
const mergedCounts = Object.values(counts).reduce((acc, cur) => ({
...acc,
...cur,
}), {});
在这个代码中,我们使用箭头函数 (acc, cur) => ({ ...acc, ...cur }) 作为 reduce() 方法的回调函数。该回调函数接收两个参数:累加器 acc 和当前元素 cur。在每次迭代中,回调函数都会将当前元素 cur 与累加器 acc 合并,并返回一个新的对象作为累加器。
由于我们要将所有属性合并到一个单一的对象中,因此我们使用对象展开运算符 {...acc, ...cur} 来将当前元素 cur 中的所有属性合并到累加器 acc 中,并返回一个新的对象。这个新的对象将作为下一次迭代的累加器传递给回调函数,直到所有元素都被迭代完毕,最终返回聚合器的最终值。
需要注意的是,在实际应用中,回调函数可以根据您的需求执行各种操作,并生成不同的结果。同时,初始值也可以是其他类型的值,例如空字符串、空对象或空数组等。在使用 reduce() 方法时,请确保选择正确的回调函数和初始值,以便得到所需的结果。
如果数据为空如何优化
可以进一步优化代码,使用可选链操作符(Optional Chaining Operator)来简化空值判断的语法:
复制代码
const tasks = res.map((item, index) =>
tree<any>(type, item.id).then(child => {
const count_data = child?.data?.count_data;
console.log('child.data', child?.data);
counts[index] = count_data || {};
return {
...item,
id: item.name,
level: 1,
children: child?.data?.tree_data?.children || [],
};
})
);
这样就可以避免显式地检查child.data和child.data.tree_data是否存在,而是直接使用可选链操作符来进行访问。如果某个属性不存在,则表达式会返回undefined,避免了程序报错。同时,将counts[index]设置为一个空对象,可以保证在count_data不存在时也不会报错,因为后续的数据合并过程中会忽略空对象。
基于可选链操作符的语法优化,可以让代码更加简洁和易读。
数据管理
大型项目参与人数过多,统一把数据存放在一个固定文件夹里,方便管理和修改
跨端 B端 C端
跨端
多个设备和平台上进行适配和兼容。 响应式设计
移动端专属网站
B端的定义
B端是面向企业的互联网产品,用户通过它进行日常的商业活动。
C端
C端消费者,个体用户端。C端的英文名称是(consumer) C端产品也叫2C(to Customer)产品,是面向终端用户或消费者的产品,往往承担引流和转化的任务 C端产品是企业与消费者之间的重要媒介,也是企业重要的获客手段之一。