惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
U
Unit 42
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
N
Netflix TechBlog - Medium
C
Check Point Blog
Security Latest
Security Latest
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
J
Java Code Geeks
The GitHub Blog
The GitHub Blog
V
Vulnerabilities – Threatpost
阮一峰的网络日志
阮一峰的网络日志
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes
F
Full Disclosure
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
Latest news
Latest news
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
Cyberwarzone
Cyberwarzone
The Hacker News
The Hacker News
A
Arctic Wolf
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
NISL@THU
NISL@THU
腾讯CDC
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
罗磊的独立博客
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 司徒正美
K
Kaspersky official blog
L
Lohrmann on Cybersecurity
C
CXSECURITY Database RSS Feed - CXSecurity.com
月光博客
月光博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Project Zero
Project Zero
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ

博客园 - VipSoft

Python 项目简单部署(Linux) MinerU - 将非结构化文档(PDF、图片、Office 文件等)转换为机器可读的 Markdown 和 JSON LangChain 入门 服务端部署-FastAPI LangChain 入门 LangSmith LangChain 入门 实战 - 食谱推荐 LangChain 入门 Memory 会话记忆 LangChain 入门 Tools 工具 LangChain 入门 Tools 工具 LangChain 入门 Prompts 提示词 LangChain 入门 Message 消息 LangChain 入门 Model 的初始化和调用 LangChain 入门 Agent 的基本运行机制 AI 0基础学习,名词解析 LangChain 和 LangGraph AI大模型知识体系 Dify — Workflow - 数据可视化 Dify — 连接MySQL配置 Dify — Chatflow - 数据库智能查询 Dify — Chatflow - 文档知识库 Dify — Agent 智能体 高安全券码、注册码生成 Dify — 文本生成应用 Dify — 聊天助手 -- 知识库 Windows 下 Docker 安装 Dify Ollama — 命令 Ollama — 为什么能够运行不同的模型 Ollama — 接口 Qwen — 自定义模型文件 Ollama Qwen — 安装测试 Ollama Windows 安装 & 指定安装目录 跟着AI学AI - 诊断结论信息抽取 - 批量处理脚本 跟着AI学AI - 诊断结论信息抽取 - 模型压缩与部署 跟着AI学AI - 诊断结论信息抽取 - 模型评估与调试 跟着AI学AI - 诊断结论信息抽取 - 模型训练 轻型民用无人驾驶航空器安全操控理论考试培训材料 FreeRedis Helper Windbg w3wp.DMP 内存分析 跟着AI学AI - 诊断结论信息抽取 - 数据增强 QQ 录屏软件 Java - 加权随机算法 - 示例 Java - 加权随机算法--Demo Java LoadBalanceUtil 负载均衡、轮询加权 SpringBoot 集成 IP2Region 获取IP地域信息 Windows 服务器和虚拟主机,创建.开头的文件夹 .well-known 跟着AI学AI - 诊断结论信息抽取 - 数据格式转换BERT训练格式 跟着AI学AI - 诊断结论信息抽取 - LabelStudio 标注 -- 结论标注 跟着AI学AI - 诊断结论信息抽取 - 学习路径 跟着AI学AI - UV 安装 数据标注工具 Label-Studio `VIRTUAL_ENV=venv` does not match the project environment 跟着AI学AI - 学习路径 - 命名实体识别(NER)和信息抽取(IE) 跟着AI学AI - 需要购买显卡吗? C# 无BOM的UTF-8编码 Vue - el-table 嵌套表 Spring `@Scheduled` 中这些参数的区别、组合和应用场景 Python 找出同步日志中的重复数据 Python - UV PyCharm 不能识别 .venv 的环境
Vue ref reactive
VipSoft · 2026-01-09 · via 博客园 - VipSoft

问题1

const allotVO = reactive<DeviceInfoVO[]>([]);
allotVO = [];
不能对 allotVO  进行初始化,怎么能把 allotVO 里面的数据给清掉。

直接修改数组长度(推荐)

// 方法1 - 最简洁
allotVO.length = 0;

// 或者方法2 - 更明确
allotVO.splice(0);

问题2

const selectedItems = ref<DeviceInfoVO[]>([]);

const allotVO = ref<DeviceInfoVO[]>([]);

怎么把 selectedItems 赋值给 allotVO,可以直接等吗。
为什么不能直接等?

// 解构赋值(推荐)
allotVO.value = [...selectedItems.value];

// ❌ 错误做法 - 会共享引用
allotVO.value = selectedItems.value;

// 这样修改 allotVO 也会影响 selectedItems
allotVO.value.push(someItem); // selectedItems 也会被修改!

深层次对象拷贝

// 浅拷贝(对于一层结构足够)
allotVO.value = [...selectedItems.value];

// 深拷贝(如果对象有嵌套)
import { cloneDeep } from 'lodash-es';
allotVO.value = cloneDeep(selectedItems.value);

// 或者使用 JSON(有局限性,不能处理函数、循环引用等)
allotVO.value = JSON.parse(JSON.stringify(selectedItems.value));

赋值问题

const selectedItems = ref<DeviceInfoVO[]>([]);

const allotVO = reactive<DeviceInfoVO[]>([]);

Object.assign(allotVO, { ...selectedItems.value });
我第一次选10条,第二次选2条。最后  allotVO 还是 10条

原因分析

// 第一次:selectedItems 有10条
selectedItems.value = [item1, item2, ..., item10]; // 10条
Object.assign(allotVO, { ...selectedItems.value });
// 结果:allotVO 变成 {0:item1, 1:item2, ..., 9:item9},length=10

// 第二次:selectedItems 有2条
selectedItems.value = [itemA, itemB]; // 2条
Object.assign(allotVO, { ...selectedItems.value });
// 结果:allotVO 变成 {0:itemA, 1:itemB, 2:item3, ..., 9:item9}
// 因为 Object.assign 只覆盖已有的属性,不会删除多余的属性!
// 所以 allotVO.length 仍然是 10,后面8个是旧数据

正确的解决方案:

方案1:使用 splice(最推荐)

// 清空并替换
allotVO.splice(0, allotVO.length, ...selectedItems.value);

方案2:先清空再push

allotVO.length = 0;
allotVO.push(...selectedItems.value);

方案3:如果需要用 Object.assign

// 必须先清空所有属性
allotVO.splice(0); // 清空数组
// 然后再赋值
selectedItems.value.forEach((item, index) => {
  allotVO[index] = item;
});

总结:

  • Object.assign 只是合并属性,不会删除多余的属性
  • 对于数组操作,应该使用数组的原生方法
  • 使用 splice 可以确保完全替换数组内容

reactive 的优缺点:

优点:

  1. 直接访问:不需要 .value
  2. 更直观:对于对象/数组,代码更简洁
  3. 性能稍好:Vue 内部优化

缺点:

  1. 不能解构:解构会失去响应性
  2. 类型限制:只能是对象类型(对象、数组、Map、Set)
  3. 替换麻烦:不能直接赋值 = [],需要用 splice

ref 的优缺点:

优点:

  1. 更灵活:可以存储任何类型的值
  2. 直接赋值:可以 allotVO.value = []
  3. 解构方便:在组合式函数中更容易返回
  4. 类型支持更好:TypeScript 类型推断更准确

缺点:

  1. 需要 .value:访问和修改都要加 .value
  2. 代码稍繁琐:多了 .value

具体建议:

使用 reactive 的场景:

// 场景1:作为组件内部状态,不经常重新赋值
const formState = reactive({
  name: '',
  age: 0,
  list: [] as DeviceInfoVO[]
});

// 场景2:嵌套在对象中的数组
const state = reactive({
  allotList: [] as DeviceInfoVO[],
  selectedList: [] as DeviceInfoVO[],
  loading: false
});
// 使用:state.allotList.push(item)

使用 ref 的场景:

// 场景1:需要频繁重新赋值的数组
const allotVO = ref<DeviceInfoVO[]>([]);
// 清空:allotVO.value = []
// 赋值:allotVO.value = [...selectedItems.value]

// 场景2:在组合式函数中返回
function useDeviceList() {
  const list = ref<DeviceInfoVO[]>([]);
  
  const clear = () => {
    list.value = []; // 直接赋值很方便
  };
  
  return { list, clear }; // 返回 ref 更方便
}

// 场景3:需要模板自动解包
// 模板中可以直接使用 allotVO 而不是 allotVO.value

针对你的情况:

如果你需要:

  • 频繁清空和重新赋值 → 用 ref
  • 主要是 push/pop/splice 操作 → 用 reactive 也可以

推荐方案:

// 如果经常需要 allotVO = [] 或 allotVO = newArray
const allotVO = ref<DeviceInfoVO[]>([]); // ✅ 推荐

// 如果主要是数组方法操作
const allotVO = reactive<DeviceInfoVO[]>([]); // 也可以

// 或者结合使用(最灵活)
const state = reactive({
  allotVO: [] as DeviceInfoVO[],
  // 其他状态...
});

// 清空和赋值可以用辅助函数
const clearAllotVO = () => {
  state.allotVO.splice(0);
};

const setAllotVO = (items: DeviceInfoVO[]) => {
  state.allotVO.splice(0, state.allotVO.length, ...items);
};

结论:

对于你的 allotVO,我推荐使用 ref,因为:

  1. 你明显需要清空和重新赋值操作
  2. refallotVO.value = []reactivesplice 更直观
  3. 现代 Vue 3 项目中更倾向于使用 ref
  4. 组合式 API 中 ref 更通用
// 最终建议
const selectedItems = ref<DeviceInfoVO[]>([]);
const allotVO = ref<DeviceInfoVO[]>([]); // 改用 ref

// 使用
allotVO.value = [...selectedItems.value]; // 赋值
allotVO.value = []; // 清空
allotVO.value.push(item); // 添加
allotVO.value = [...selectedItems.value];
      // 根据条件遍历赋值
      allotVO.forEach((item) => {
        // 示例:根据索引或其他逻辑赋值
        item.HospitalId = dept.HospitalId;
        item.HospitalName = dept.HospitalName;
        item.HospitalShortName = dept.HospitalShortName;
        item.DeptId = dept.Id;
        item.DeptName = dept.DeptName;
      }); 
是不是得用 allotVO.value.forEach

是的,必须用 allotVO.value.forEach

因为 allotVOref,所以访问它的值需要使用 .value

// ✅ 正确
allotVO.value.forEach((item) => {
  item.HospitalId = dept.HospitalId;
  item.HospitalName = dept.HospitalName;
  item.HospitalShortName = dept.HospitalShortName;
  item.DeptId = dept.Id;
  item.DeptName = dept.DeptName;
});

// ❌ 错误:allotVO 是 ref,没有 forEach 方法
allotVO.forEach((item) => { ... });

完整正确代码:

// 定义 ref
const allotVO = ref<DeviceInfoVO[]>([]);

// 赋值
allotVO.value = [...selectedItems.value];

// 遍历修改每一项
allotVO.value.forEach((item) => {
  item.HospitalId = dept.HospitalId;
  item.HospitalName = dept.HospitalName;
  item.HospitalShortName = dept.HospitalShortName;
  item.DeptId = dept.Id;
  item.DeptName = dept.DeptName;
});

如果你用的是 reactive:

// 如果用 reactive(不需要 .value)
const allotVO = reactive<DeviceInfoVO[]>([]);

// 赋值(需要 splice 而不是直接 =)
allotVO.splice(0, allotVO.length, ...selectedItems.value);

// 遍历(直接使用 allotVO,没有 .value)
allotVO.forEach((item) => {
  item.HospitalId = dept.HospitalId;
  // ... 其他赋值
});

简化建议:

你可以考虑使用 map 一步完成赋值和修改:

// 一步完成:复制数组并修改每一项
allotVO.value = selectedItems.value.map(item => ({
  ...item, // 保留原有属性
  HospitalId: dept.HospitalId,
  HospitalName: dept.HospitalName,
  HospitalShortName: dept.HospitalShortName,
  DeptId: dept.Id,
  DeptName: dept.DeptName
}));

这样更简洁,而且不会修改原始的 selectedItems.value

总结:

  • ref 需要 .valueallotVO.value.forEach
  • reactive 不需要 .valueallotVO.forEach
  • 推荐用 map 一步完成复制和修改