Vue3+TypeScript中Lodash的omit函数(去除对象属性:用于创建一个新对象,该对象省略(排除)了源对象中指定的属性)

在 Vue3 与 TypeScript 的项目中,Lodash 是一个常用的实用工具库,其中的 omit 函数能够帮助我们从对象中排除指定的属性,并返回一个新的对象。这对于数据处理、属性过滤等场景非常有用。下面我将详细讲解 omit 在 Vue3 + TypeScript 环境下的使用方式、类型安全以及实际案例。


1. Lodash 的 omit 函数是什么?

_.omit(object, [paths])

  • 作用:创建一个从原对象中排除指定属性(或属性路径)的新对象。

  • 参数

    • object:源对象。

    • paths:要排除的属性路径(可以是字符串或字符串数组)。

  • 返回值:一个新对象,包含源对象中除 paths 指定的属性之外的所有可枚举属性。

示例

typescript

import { omit } from 'lodash-es';

const original = { a: 1, b: 2, c: 3 };
const result = omit(original, ['b', 'c']);
console.log(result); // => { a: 1 }

2. 在 TypeScript 中的类型支持

lodash 提供了完善的 TypeScript 类型定义,omit 的类型签名大致如下(简化):

typescript

omit<T extends object, K extends keyof T>(object: T, ...paths: K[]): Omit<T, K>;
  • T 是源对象类型。

  • K 是 T 的键的联合类型,即要排除的属性名。

  • 返回值类型是 Omit<T, K>,这是 TypeScript 内置的工具类型,表示从 T 中移除 K 指定的属性后的类型。

因此,使用 omit 时,TypeScript 能够自动推断返回对象的类型,并确保你排除的键确实存在于源对象中,提供编译时的类型安全。

类型推导示例

typescript

interface User {
  id: number;
  name: string;
  password: string;
  email: string;
}

const user: User = { id: 1, name: 'Alice', password: 'secret', email: 'alice@example.com' };

// 排除 password 和 email,返回的类型为 { id: number; name: string; }
const publicUser = omit(user, 'password', 'email');
// publicUser 的类型自动推导为 Omit<User, 'password' | 'email'>

3. Vue3 + TypeScript 中使用 omit 的常见场景

在 Vue3 组件中,我们经常需要处理响应式对象(reactive 或 ref),有时希望从对象中排除某些属性,用于以下目的:

  • 传递给子组件时隐藏敏感字段(如密码、token)。

  • 过滤掉不需要的属性,避免污染子组件的 props。

  • 基于现有对象创建简化版本,用于渲染或 API 提交。

  • 配合计算属性(computed)生成派生数据

需要注意的是,omit 返回的是普通对象,不是响应式对象。如果需要在模板中保持响应性,应当将 omit 的结果包裹在 computed 中,或者使用 toRefs 手动处理。


4. 示例:Vue3 组件中使用 omit

假设我们有一个用户详情组件,需要显示用户的基本信息,但排除密码和内部 ID。我们将使用组合式 API 和 TypeScript。

vue

<template>
  <div>
    <h2>用户信息</h2>
    <pre>{{ publicUser }}</pre>
    <!-- 也可以分别显示 -->
    <p>姓名:{{ publicUser.name }}</p>
    <p>邮箱:{{ publicUser.email }}</p>
  </div>
</template>

<script setup lang="ts">
import { reactive, computed } from 'vue';
import { omit } from 'lodash-es';

// 定义用户接口
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
  createdAt: Date;
}

// 模拟响应式用户数据
const user = reactive<User>({
  id: 1,
  name: '张三',
  email: 'zhangsan@example.com',
  password: '123456',
  createdAt: new Date(),
});

// 计算属性:排除 password 和 id,用于展示
const publicUser = computed(() => {
  // omit 返回一个新对象,类型自动推导为 Omit<User, 'password' | 'id'>
  return omit(user, ['password', 'id']);
});

// 也可以使用方法返回,但 computed 更高效(缓存)
</script>

在上面的例子中:

  • user 是响应式对象,当它变化时,publicUser 会自动更新。

  • omit 移除了 password 和 id,避免了敏感数据泄漏到模板中。

  • TypeScript 确保了 publicUser 的类型正确(不包含排除的属性)。


5. 在方法中使用 omit

有时我们只是在某个方法中临时过滤对象,例如提交表单前去除某些字段:

typescript

const submitForm = () => {
  const formData = { ... }; // 可能包含一些内部字段
  const dataToSend = omit(formData, ['internalId', 'tempFlag']);
  // 发送 dataToSend 到 API
};

TypeScript 同样会推导出 dataToSend 的正确类型。


6. 注意事项

6.1 响应式丢失

直接使用 omit(user, ...) 返回的是普通对象,如果将其直接赋值给模板变量,模板将不会响应式更新。必须配合 computed 或 ref/reactive 使用

6.2 性能考虑

omit 每次调用都会创建一个新对象并进行属性复制。在频繁更新的场景下(如动画或高频事件),需要注意性能。通常用于计算属性或一次性操作是完全可以接受的。

6.3 深层排除

omit 也支持排除深层路径,例如 omit(obj, 'a.b.c'),但类型支持可能不如浅层排除完善。如果类型比较复杂,可以考虑使用更具体的类型断言。

6.4 替代方案

  • 如果只需要排除少量属性,可以手动解构:const { password, id, ...rest } = user;,但这样会丢失响应性,且需要手动处理类型。

  • Vue3 的 toRefs 可以将响应式对象的每个属性转为 ref,但无法直接排除属性。

  • 对于 TypeScript,也可以使用 Omit<Type, Keys> 工具类型手动声明类型。


7. 总结

  • Lodash 的 omit 函数在 Vue3 + TypeScript 中用于从对象中排除指定属性,返回一个新对象。

  • TypeScript 类型定义完善,能够自动推导返回类型,并提供编译时检查。

  • 在 Vue3 组件中,常与 computed 结合使用,以保持响应式派生数据的正确性。

  • 适用于过滤敏感字段、简化对象、准备 API 数据等场景。

  • 注意响应式丢失问题,避免在模板中直接使用 omit 返回的普通对象。

掌握 omit 的用法,可以让你的 Vue3 代码更加简洁、类型安全。如果你有更多关于 Lodash 或 Vue3 类型的问题,欢迎继续探讨!


lodash.omit 是 Lodash 库提供的一个实用函数,用于创建一个新对象,该对象省略(排除)了源对象中指定的属性。它常用于数据清洗、对象比较、过滤不需要的字段等场景,尤其是在前后端数据交互或状态管理时,需要移除某些临时字段。


语法

javascript

_.omit(object, [paths])
  • object (Object):源对象。

  • [paths] (...(string|string[])):要省略的属性路径,可以是单个字符串、多个字符串或字符串数组。

返回值:返回一个新对象,该对象包含源对象中除指定路径外的所有属性(仅自身的可枚举属性)。


使用示例

1. 基本用法

javascript

const original = { a: 1, b: 2, c: 3, d: 4 };

// 省略单个属性
const omitted1 = _.omit(original, 'c');
console.log(omitted1); // { a: 1, b: 2, d: 4 }

// 省略多个属性
const omitted2 = _.omit(original, ['b', 'd']);
console.log(omitted2); // { a: 1, c: 3 }
2. 省略嵌套属性(支持路径语法)

javascript

const user = {
  id: 1,
  name: 'Alice',
  address: {
    city: 'Beijing',
    street: 'ChangAn'
  }
};

const omitted = _.omit(user, ['address.city', 'id']);
console.log(omitted);
// { name: 'Alice', address: { street: 'ChangAn' } }
// 注意:address.city 被移除,但 address 对象仍保留其他属性
3. 结合实际问题:排除前端临时属性

在你的场景中,localCapitalInfo 包含一个额外的 capitalAllocateDetailList 属性,而 capitalInfoStore.currentSelectedCapitalInfo 没有该属性。为了正确比较两个对象,可以创建临时副本:

javascript

import _ from 'lodash-es'; // 或 import { omit } from 'lodash-es'

// 排除 localCapitalInfo 中的临时属性,得到用于比较的对象
const localForCompare = _.omit(localCapitalInfo, ['capitalAllocateDetailList']);

// 如果 store 对象也可能包含该属性,也排除掉(通常 store 中没有,但为了安全可以统一处理)
const storeForCompare = _.omit(capitalInfoStore.currentSelectedCapitalInfo, ['capitalAllocateDetailList']);

if (!_.isEqual(storeForCompare, localForCompare)) {
  await capitalInfoStore.updateCapitalInfo(localCapitalInfo); // 更新时仍使用包含临时属性的原对象(如果后端需要忽略该字段)
}

与其他方法的对比

方法作用示例
_.omit排除指定属性_.omit(obj, 'a') → 不含 a 的新对象
_.pick只保留指定属性_.pick(obj, ['a', 'b']) → 仅含 ab 的新对象
_.omitBy根据断言函数排除属性_.omitBy(obj, (val) => typeof val === 'number') → 排除所有数字类型的属性
_.pickBy根据断言函数保留属性_.pickBy(obj, (val) => typeof val === 'string') → 只保留字符串类型的属性

注意事项

  1. 浅拷贝_.omit 返回的新对象是浅拷贝。如果源对象的属性值是对象或数组,则新对象中该属性引用的是同一个对象(即嵌套对象未被克隆)。若需要深层次排除或深拷贝,可结合 _.cloneDeep 使用。

    javascript

    const obj = { a: { b: 1 } };
    const omitted = _.omit(obj, 'c'); // 没有排除嵌套属性
    omitted.a.b = 2;
    console.log(obj.a.b); // 2,因为共享引用
  2. 属性路径:支持点号路径(如 'a.b.c'),也支持数组路径(['a', 'b', 'c'])。但需要注意,路径语法对非普通对象(如 Map、Set)可能不适用。

  3. 性能:在处理大型对象时,_.omit 会遍历源对象的可枚举属性并过滤,性能与属性数量成正比。如果频繁调用且对象庞大,可考虑手动解构排除(适用于少量属性):

    javascript

    const { capitalAllocateDetailList, ...rest } = localCapitalInfo;
    // 此时 rest 即为排除后的对象

    这种方式更轻量,但需要你知道所有要排除的属性名。

  4. Symbol 类型属性_.omit 只能排除字符串类型的属性名,无法排除 Symbol 类型的属性。


在 Vue 3 中的使用建议

  • 响应式对象localCapitalInfo 可能是 reactive 或 ref 包装的响应式对象。直接传入 _.omit 是安全的,因为 _.omit 会读取源对象的属性值(自动解包 ref?Lodash 不处理 Vue 的响应式代理,所以会直接操作 Proxy 对象,得到的是原始值或响应式对象本身)。为了避免潜在的副作用,建议先使用 toRaw 获取原始对象:

    javascript

    import { toRaw } from 'vue';
    const rawLocal = toRaw(localCapitalInfo);
    const localForCompare = _.omit(rawLocal, ['capitalAllocateDetailList']);
  • 保持响应性_.omit 返回的是普通对象,不再具备响应性。如果需要将处理后的数据用于模板或计算属性,应再次包装为响应式(如 reactive(_.omit(...))),但通常比较操作不需要响应性。

  • 结合 cloneDeep:如果需要完全深拷贝并排除属性,可以组合使用:

    javascript

    const localForCompare = _.cloneDeep(_.omit(localCapitalInfo, ['capitalAllocateDetailList']));

总结

_.omit 是一个简单实用的工具,用于快速排除对象中的指定属性。在对象比较、数据清洗、接口参数过滤等场景中非常常用。使用时需注意其浅拷贝特性,并根据需求选择合适的排除方式(手动解构、omit 或 omitBy)。在与 Vue 响应式系统结合时,可先使用 toRaw 剥离代理,避免意外行为。


示例代码:

import { isEqual, omit } from "lodash-es";

    // 比较之前,先使用lodash的omit去除属性(资金分配明细列表 capitalAllocateDetailList)
    const localForCompare = omit(localCapitalInfo, ["capitalAllocateDetailList"]);
    const storeForCompare = omit(capitalInfoStore.currentSelectedCapitalInfo, ["capitalAllocateDetailList"]);

    console.log("localCapitalInfo = ", localCapitalInfo);
    console.log("localForCompare = ", localForCompare);

    // 深度比较两个对象是否相等,两个对象不相同,需要更新数据;如果两个对象相同(所有属性值都相同),不需要更新数据
    if (!isEqual(storeForCompare, localForCompare)) {
      await capitalInfoStore.updateCapitalInfo(localCapitalInfo);
    }

应用效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值