Vue 3 深入学习笔记 07:v-model 与受控组件设计
Vue 3 深入学习笔记 07v-model 与受控组件设计一、为什么要学习 v-model在前面的学习中我们已经掌握了组件设计与职责边界知道了父组件通过props向子组件传递数据。子组件通过emit通知父组件发生了什么。共享状态应该由合适的组件统一管理。但是在实际开发中还有一个非常常见的问题。如果父组件需要管理数据而子组件又需要修改数据应该怎么设计例如我们开发一个订单搜索页面。父组件需要保存搜索关键词子组件负责展示输入框。当用户在输入框中输入ORD001时我们希望输入框显示ORD001。父组件中的keyword同步变成ORD001。父组件可以使用这个关键词执行搜索。如果父组件主动清空关键词子组件的输入框也同步清空。这种需求就是 Vue 中v-model的典型应用场景。本篇将重点学习v-model的工作原理。原生表单元素与组件上的v-model有什么区别。如何实现自定义组件的v-model。如何理解受控组件与非受控组件。多个v-model如何使用。如何设计可复用的表单组件。二、先理解原生元素上的 v-model在学习组件上的v-model之前我们先看一个最简单的例子。script setup import { ref } from vue const keyword ref() /script template input v-modelkeyword / p当前关键词{{ keyword }}/p /template当用户在输入框中输入内容时keyword会自动更新。例如用户输入ORD001页面显示当前关键词ORD001这里发生了什么对于普通文本输入框可以将v-model理解为以下两部分input :valuekeyword inputkeyword $event.target.value /上面只是帮助理解的简化写法。在使用ref时实际 JavaScript 中需要通过keyword.value修改值在模板中Vue 会自动解包顶层的ref。对应的 JavaScript 写法是keyword.value event.target.value这两部分分别承担不同职责语法职责:valuekeyword将状态同步到输入框input...将用户输入同步回状态因此v-model并不是一种神秘的双向绑定机制而是将数据传递与数据变更通知组合起来的便捷语法。需要注意不同表单元素的实现细节并不完全相同。例如复选框和单选框会使用不同的属性与事件但整体思想一致。三、组件上的 v-model 与原生元素不同这是本篇最重要的知识点之一。先看原生元素input v-modelkeyword /再看自定义组件SearchInput v-modelkeyword /它们的写法非常相似但内部机制不同。原生元素的v-model直接处理输入框等 DOM 元素的属性和事件。组件上的v-model则需要父子组件配合父组件传递当前值。子组件通知父组件值发生变化。父组件更新状态后再将新值传回子组件。在 Vue 3 中默认的组件v-model可以展开为SearchInput :modelValuekeyword update:modelValuekeyword $event /其中有两个重要约定名称作用modelValue父组件传入的当前值update:modelValue子组件通知父组件更新值的事件请记住这两个名称。理解了它们就基本掌握了 Vue 3 组件v-model的核心原理。四、手动实现一个支持 v-model 的组件我们通过一个完整例子来理解。假设我们要开发一个通用的搜索输入框SearchInput.vue。1. 子组件 SearchInput.vuescript setup const props defineProps({ modelValue: { type: String, default: } }) const emit defineEmits([update:modelValue]) function handleInput(event) { emit(update:modelValue, event.target.value) } /script template input :valueprops.modelValue inputhandleInput placeholder请输入搜索关键词 / /template这里有三个关键点。第一通过 props 接收父组件的数据。const props defineProps({ modelValue: { type: String, default: } })子组件并不自己决定最终保存什么值而是接收父组件传来的modelValue。第二通过 emit 通知父组件更新数据。emit(update:modelValue, event.target.value)当用户输入新内容时子组件发出事件并将新值作为参数传出去。第三输入框始终展示父组件传入的值。input :valueprops.modelValue /父组件更新modelValue后输入框也会显示最新值。2. 父组件使用 SearchInput.vuescript setup import { ref } from vue import SearchInput from ./SearchInput.vue const keyword ref() /script template SearchInput v-modelkeyword / p当前关键词{{ keyword }}/p button clickkeyword 清空关键词 /button /template运行后可以看到用户输入时父组件的keyword自动更新。页面上的关键词同步变化。点击清空按钮输入框也会同步清空。整个过程如下用户输入内容 ↓ SearchInput 发出 update:modelValue ↓ 父组件更新 keyword ↓ 父组件重新向 SearchInput 传递 modelValue ↓ 输入框显示最新值这就是 Vue 3 组件v-model的基本工作流程。五、为什么子组件不能直接修改 props理解v-model时一个非常容易犯的错误是直接修改props。例如script setup const props defineProps({ modelValue: String }) function handleInput(event) { props.modelValue event.target.value } /script这种写法是不正确的。Vue 的设计原则是父组件拥有传入的数据子组件不能直接修改 props。为什么假设父组件有以下代码const keyword ref(ORD001)然后传递给子组件SearchInput :model-valuekeyword /如果子组件直接修改传入的值就会出现一个问题父组件的数据应该由谁负责修改如果父组件和子组件都可以随意修改同一份状态那么数据的修改来源就会变得难以追踪。Vue 因此采用了明确的协作方式父组件拥有数据 ↓ 通过 props 传给子组件 ↓ 子组件需要修改数据 ↓ 通过 emit 通知父组件 ↓ 父组件修改自己的状态这样做的价值不只是符合 Vue 的语法要求更重要的是让数据流向清晰、便于维护。注意props的只读约束主要针对属性本身。对于传入的对象或数组其嵌套属性在 JavaScript 中仍可能被修改但这不代表应该这样做。通常应避免在子组件中直接修改父组件拥有的对象或数组。六、受控组件与非受控组件现在进入一个更重要的设计概念受控组件。1. 什么是受控组件受控组件是指组件展示的值由外部状态决定组件通过事件请求外部更新状态。例如SearchInput v-modelkeyword /在这种设计中keyword由父组件维护。子组件通过modelValue接收值。子组件通过update:modelValue通知父组件更新。父组件可以随时修改keyword从而改变输入框显示内容。这意味着父组件始终可以控制输入框的当前值。受控组件并不意味着所有逻辑都必须写在父组件里而是指关键状态的最终所有权在外部。2. 什么是非受控组件非受控组件是指组件主要在内部管理自己的状态外部不必持续提供当前值。例如script setup import { ref } from vue const keyword ref() function search() { console.log(搜索关键词, keyword.value) } /script template input v-modelkeyword / button clicksearch 搜索 /button /template在这个例子中输入框的状态由当前组件内部的keyword管理。外部组件不需要知道用户输入了什么也不需要控制输入框的每一次变化。这就是一种内部状态管理的思路。严格来说判断一个组件是否受控关键在于其值是否由外部持续提供和控制而不是看它有没有使用ref。3. 两者如何选择对比项受控组件非受控组件状态主要由谁管理父组件或外部组件内部外部能否直接控制当前值可以通常不能直接控制是否适合父组件统一重置表单很适合需要额外提供方法或同步机制是否适合独立、简单的输入功能可以但可能略显复杂通常很方便是否适合多个组件协同使用同一状态很适合需要额外设计通信实际开发中两者没有绝对的优劣。例如一个独立的搜索框可以内部管理输入状态。一个复杂的订单编辑表单通常需要由父组件或表单模块统一管理数据。一个需要父组件随时重置、回显和校验的通用输入组件通常适合使用受控设计。核心是明确状态的所有权。七、v-model 与 props emit 的关系学到这里你可能会有一个疑问既然v-model最终也是通过props和emit实现的那么为什么不一直使用props emit答案是两者的底层协作方式一致只是表达形式不同。假设父组件需要传递一个关键词并监听关键词变化。写法一显式使用 props emitSearchInput :model-valuekeyword update:model-valuekeyword $event /写法二使用 v-modelSearchInput v-modelkeyword /第二种写法更加简洁。当组件存在多个需要双向同步的字段时v-model的优势会更加明显。但是如果子组件只需要通知父组件执行一个操作例如OrderTable view-orderhandleViewOrder /这里不适合强行使用v-model。因为“查看订单”表达的是一个操作事件并不是某个需要双向同步的值。因此可以这样区分需要同步某个值 考虑v-model。需要通知外部发生了某个动作 使用emit自定义事件。八、多个 v-model一个组件管理多个字段真实业务中一个组件经常需要同时管理多个值。例如订单筛选组件需要维护keyword订单编号。status订单状态。如果只使用默认的v-model就只能通过默认的modelValue对应一个值。Vue 3 支持为v-model指定不同的名称。1. 父组件script setup import { ref } from vue import OrderFilter from ./OrderFilter.vue const keyword ref() const status ref(all) /script template OrderFilter v-model:keywordkeyword v-model:statusstatus / p订单编号{{ keyword }}/p p订单状态{{ status }}/p /template这里有两个v-modelv-model:keywordkeyword v-model:statusstatus它们分别绑定不同的数据。2. 子组件 OrderFilter.vuescript setup defineProps({ keyword: { type: String, default: }, status: { type: String, default: all } }) const emit defineEmits([ update:keyword, update:status ]) /script template div input :valuekeyword inputemit(update:keyword, $event.target.value) placeholder订单编号 / select :valuestatus changeemit(update:status, $event.target.value) option valueall全部/option option valuepending待支付/option option valuepaid已支付/option /select /div /template这里的映射关系是父组件写法子组件接收的 prop子组件发出的事件v-model:keywordkeywordupdate:keywordv-model:statusstatusupdate:status可以看出命名参数keyword对应keyword属性和update:keyword事件。这使得一个组件能够同时维护多个由外部控制的字段而不需要把所有字段塞进一个对象中。3. 使用 defineModel 简化代码Vue 3.4 及以上版本提供了defineModel()可以进一步简化组件v-model的实现。默认v-model的子组件可以这样写script setup const model defineModel({ type: String, default: }) /script template input v-modelmodel / /template父组件仍然可以这样使用SearchInput v-modelkeyword /defineModel()帮助我们处理modelValue和update:modelValue这套约定不需要手动编写对应的props和emit。如果要使用命名v-model例如v-model:keyword则可以这样写script setup const keyword defineModel(keyword, { type: String, default: }) /script template input v-modelkeyword / /template对于 Vue 3.4 及以上版本编写自定义v-model组件时通常可以优先考虑defineModel()。如果项目使用 Vue 3.3 或更早版本则需要继续采用手动定义props和emit的方式。还需要注意一个细节defineModel()的default值可能导致父组件绑定值与子组件初始值不同步尤其是在父组件绑定值为undefined时。因此如果希望父子状态始终一致最好让父组件明确提供初始值。九、v-model 在实际业务中的应用我们将前面的知识结合起来看看如何设计一个订单编辑组件。需求如下父组件维护订单数据。用户点击编辑后打开编辑弹窗。子组件展示订单编辑表单。用户修改订单名称。点击取消时不修改原始订单数据。点击保存时将修改结果提交给父组件。1. 父组件 OrderPage.vuescript setup import { ref } from vue import OrderEdit from ./OrderEdit.vue const order ref({ id: 101, name: 测试订单, status: pending }) const editVisible ref(false) const editForm ref({ name: , status: pending }) function openEdit() { // 创建独立的编辑数据避免直接修改原始订单 editForm.value { name: order.value.name, status: order.value.status } editVisible.value true } function saveEdit(form) { order.value { ...order.value, ...form } editVisible.value false } /script template div p订单名称{{ order.name }}/p p订单状态{{ order.status }}/p button clickopenEdit 编辑订单 /button OrderEdit v-ifeditVisible :model-valueeditForm savesaveEdit canceleditVisible false / /div /template这里父组件维护原始订单数据和编辑表单的初始值。打开编辑窗口时我们复制需要编辑的字段而不是直接把原始订单对象交给表单修改。2. 子组件 OrderEdit.vuescript setup import { reactive, watch } from vue const props defineProps({ modelValue: { type: Object, required: true } }) const emit defineEmits([ save, cancel ]) const form reactive({ name: , status: pending }) watch( () props.modelValue, (value) { Object.assign(form, value) }, { immediate: true } ) function handleSave() { emit(save, { ...form }) } /script template div input v-modelform.name / select v-modelform.status option valuepending待支付/option option valuepaid已支付/option /select button clickhandleSave 保存 /button button clickemit(cancel) 取消 /button /div /template这个例子使用的是props emit的数据传递方式而不是直接对整个表单对象使用v-model。原因是这里需要区分两个概念表单内部正在编辑的临时数据。父组件真正拥有的订单数据。只有用户点击保存后子组件才通知父组件提交修改结果。这是一种常见的表单设计方式。3. 为什么不直接对原始订单使用 v-model假设直接写成OrderEdit v-modelorder /如果子组件通过v-model实时同步每一次表单输入那么父组件的order就会在用户编辑过程中持续变化。此时用户点击取消原始订单数据可能已经被修改。所以对于具有“保存”和“取消”语义的编辑表单通常需要维护一份独立的临时数据。当然如果业务明确要求实时同步例如实时预览设置那么直接使用v-model可能更合适。关键不是能不能使用v-model而是数据应该在什么时候真正生效。十、学习 v-model 时最容易犯的错误错误 1认为 v-model 可以直接修改父组件数据不准确。组件v-model通过传值和更新事件实现同步。子组件发出事件后最终仍由父组件更新其状态。错误 2所有事件都使用 v-model不正确。v-model适合表达某个值的同步关系而不是所有用户操作。例如查看详情、删除订单、导出数据等操作通常应该使用自定义事件。错误 3把对象传给子组件后直接修改对象属性例如props.order.name 新名称即使某些情况下这段代码可以修改嵌套属性也会让数据所有权变得模糊。更好的做法是由父组件维护原始对象子组件通过事件提交修改请求或者使用独立的编辑副本。错误 4认为 defineModel 会自动创建全局共享状态不正确。const model defineModel()它处理的是当前组件的v-model通信并不会让其他组件自动共享同一份状态。跨页面共享数据仍然需要合适的状态管理方案例如 Pinia。错误 5认为受控组件就必须没有内部状态不正确。受控组件仍然可以维护内部状态例如下拉菜单是否展开、动画进度、临时校验信息等。只要关键业务值由外部控制就仍然可以采用受控设计。十一、课后练习假设现在要开发一个通用的UserNameInput.vue组件。需求如下父组件维护用户名username。子组件展示用户名输入框。用户输入时父组件中的username自动更新。父组件点击“重置”按钮后输入框同步清空。请完成以下三个练习。练习 1理解原理下面两种写法有什么区别UserNameInput v-modelusername /UserNameInput :model-valueusername update:model-valueusername $event /请说明它们之间的关系。练习 2实现组件请使用传统的defineProps()和defineEmits()实现UserNameInput.vue。要求接收父组件传入的用户名。用户输入时发出update:modelValue事件。不允许直接修改props。练习 3设计订单编辑表单一个订单编辑弹窗包含订单名称和订单状态。用户可以修改表单但只有点击“保存”后才更新原始订单点击“取消”则丢弃修改。请思考应该直接对原始订单使用v-model吗临时表单数据应该由谁维护子组件应该通过什么方式提交修改结果十二、课后练习参考答案练习 1理解原理两种写法的功能基本等价。第一种使用v-model语法糖第二种显式写出了数据传递和事件监听。可以将第一种展开为UserNameInput :model-valueusername update:model-valueusername $event /其中:model-valueusername父组件把当前用户名传给子组件。update:model-valueusername $event子组件通知父组件更新用户名。$event就是子组件发出事件时传递的新值。练习 2实现组件UserNameInput.vuescript setup const props defineProps({ modelValue: { type: String, default: } }) const emit defineEmits([ update:modelValue ]) function handleInput(event) { emit(update:modelValue, event.target.value) } /script template input :valueprops.modelValue inputhandleInput placeholder请输入用户名 / /template父组件script setup import { ref } from vue import UserNameInput from ./UserNameInput.vue const username ref() /script template UserNameInput v-modelusername / p当前用户名{{ username }}/p button clickusername 重置 /button /template当用户输入时子组件发出更新事件父组件修改username。点击重置时父组件直接将username设置为空字符串新的值会通过props传给子组件输入框随之清空。练习 3设计订单编辑表单参考答案不建议直接使用原始订单作为实时双向绑定的数据。推荐设计如下父组件保存原始订单。打开编辑弹窗时创建一份临时表单数据。子组件只编辑临时表单。点击保存时子组件通过emit(save, formData)提交修改结果。父组件接收修改结果更新原始订单。点击取消时直接关闭弹窗并丢弃临时数据。例如function openEdit() { editForm.value { name: order.value.name, status: order.value.status } } function saveEdit(formData) { order.value { ...order.value, ...formData } }这种设计将原始数据与编辑过程分离避免用户在尚未保存时就修改了正式数据。十三、本篇总结本篇需要掌握以下核心知识原生元素上的v-model用于同步表单元素与响应式状态。Vue 3 组件上的v-model默认通过modelValue和update:modelValue实现。子组件不应该直接修改props而应该通过事件通知父组件。受控组件由外部控制关键状态非受控组件主要管理自己的内部状态。多个v-model可以分别同步组件中的多个字段。Vue 3.4 及以上版本可以使用defineModel()简化组件双向绑定。对于需要保存和取消的编辑表单应当区分原始数据和临时编辑数据。本篇最重要的设计思想v-model解决的是值如何同步的问题而受控组件设计解决的是状态由谁拥有、由谁负责修改的问题。

相关新闻

零基础秒转AMR,3大神器全解析

零基础秒转AMR,3大神器全解析

AMR这个格式, 它是专门针对移动通信和语音录音这块儿设计的轻量化音频方案。它就是为了把那些人声通话的场景、语音消息的场景, 还有设备录音的场景给优化好而存在的。它的文件体积是最小最小的, 压缩率也是高得出奇的。而且在兼容性方面, 它覆盖了从前老式的手机、功能机这些设…

2026/10/19 2:05:30 阅读更多 →
第 14 章 Doris 读湖:经 Paimon Catalog 的服务层

第 14 章 Doris 读湖:经 Paimon Catalog 的服务层

第 14 章 Doris 读湖:经 Paimon Catalog 的服务层 章节定位:第四篇(Lakestream)的收口章,也是全系列"技术栈闭环"的最后一环。前三章让湖仓"能分层、能读、能 Union",但 Union Read 只有 Flink / Spark 会;真正扛 BI、报表与对外服务的是 Doris——…

2026/10/19 2:05:30 阅读更多 →
AI智能体项目实战记录(07):RAG项目实战之文档内容向量化入库

AI智能体项目实战记录(07):RAG项目实战之文档内容向量化入库

1. 引言 在上一篇实战记录中,我们已经完成了上传文档的解析工作,将 PDF、Word、TXT 等格式的文档内容提取为纯文本。然而,仅仅解析出文本还不够——要让 AI 智能体能够"读懂"并检索这些内容,还需要将文本转换为向量并存…

2026/10/19 2:05:30 阅读更多 →

最新新闻

Excel函数九大模块导航:从基础引用到动态数组的完整学习路线

Excel函数九大模块导航:从基础引用到动态数组的完整学习路线

日常跟Excel打交道的人,应该都有过这种经历:遇到一个数据问题,明明知道有函数能解决,但就是想不起来叫什么名字。更常见的是VLOOKUP用到了第三参数返回错误,SUMIFS写条件范围时把求和区域放错位置,或者一个…

2026/10/19 2:43:50 阅读更多 →
AI改造求职全链路:告别海投零面试,实现精准匹配

AI改造求职全链路:告别海投零面试,实现精准匹配

求职这件事,这两年越来越像一场“玄学”。我见过不少背景不错的候选人,学历、经验、项目都拿得出手,却卡在了一个极其尴尬的环节:简历投出去石沉大海,面试邀约寥寥无几,甚至出现“投100份简历0面试”的荒唐…

2026/10/19 2:43:50 阅读更多 →
Linux uniq命令详解:从sort配合到日志去重实战

Linux uniq命令详解:从sort配合到日志去重实战

1. 先搞清楚uniq到底在做什么用Linux的人迟早都会遇到uniq,但很多人第一次用它的经历都不太愉快——明明是想把重复行去掉,结果文件一模一样,一行都没少。这不是uniq没干活,而是它天生就是个“挑食”的工具:uniq只处理…

2026/10/19 2:43:50 阅读更多 →
模块化函数调用异常中断的上下文恢复思路与实战

模块化函数调用异常中断的上下文恢复思路与实战

模块化函数调用异常中断后的上下文恢复问题模块化架构是当前复杂系统设计的标配,但当某个函数在调用过程中异常中断,整个链路的上下文信息往往会跟着丢失。我最近在重构一套“检测-决策-执行”三段式系统时,就被这个问题反复摩擦。表面上看&a…

2026/10/19 2:43:50 阅读更多 →
Python爬虫与朴素贝叶斯:电商评论情感分析实战链路解析

Python爬虫与朴素贝叶斯:电商评论情感分析实战链路解析

简介:基于Python的京东商品评论爬取与情感分析可视化研究资源包,面向数据分析、自然语言处理与爬虫开发的初学者或课程研究者,完整演示了从电商平台采集用户评论、清洗整理、情感分类到图表可视化的处理链路。资源共20个文件,压缩…

2026/10/19 2:43:50 阅读更多 →
手把手教你制作每日AI研究简报:信息筛选与追踪方法

手把手教你制作每日AI研究简报:信息筛选与追踪方法

经常看到有人问:AI 领域更新这么快,一天不看是不是就跟不上了?我的回答是,确实会跟不上,但没人能把一天内所有论文和动态都看完,所以才需要“每日 AI 研究简报”这种东西来兜底。2026 年 3 月 28 号这一期&…

2026/10/19 2:42:49 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →