Vue中操作DOM的正确姿势:ref、自定义指令与模板引用全解析
入行这几年带过不少刚转Vue的同事几乎每周都会有人拿着代码来问同一个问题我想拿到某个元素然后改一下样式或者滚动位置到底怎么操作DOM这个问题在不同阶段答案完全不一样。在原生JS里是document.querySelector在jQuery里是选择器加方法而到了Vue里如果你不管三七二十一继续用document.querySelector很容易写出绕开框架、数据状态和视图不同步的坑代码。这篇文章就把Vue里正规的DOM操作姿势掰开揉碎讲清楚包括ref和$refs、自定义指令、组合式API模板引用、vnode层面访问元素以及各自的使用边界和避坑经验。适合刚接触Vue、想搞清楚模板引用用法的前端新手也适合已经在项目里写了很多命令式DOM操作、想整理一套规范的老手。1. 为什么在Vue里操作DOM要讲方法1.1 声明式渲染和命令式操作之间的矛盾Vue的核心设计理念是“数据驱动”我们只需要维护状态框架负责把状态变成DOM。模板里的{{ msg }}、:class、v-if本质都是在描述“数据长什么样界面就长什么样”。这就是声明式渲染。你不需要告诉Vue每一步怎么增删节点只需要告诉它目标状态是什么剩下的事情交给虚拟DOM和diff算法。但这套设计也有一个隐含前提尽量不要绕开框架去手动改DOM。我见过不少刚上手Vue的人遇到“按钮点击后把这个div变红”的需求第一反应是document.querySelector(.box).style.color red。第一次点击确实有效可一旦组件重新渲染数据一变这条手动修改就会被虚拟DOM的patch过程覆盖屏幕上的效果又“消失”了。这不是Vue不让你改而是你改的方式和框架的管理方式冲突了。我经常用一个类比来解释数据是图纸DOM是施工完的墙面。正确做法是改图纸、重新施工直接拿锤子敲墙等下一次重新装修敲掉的地方又会被糊回去。Vue里也一样能用v-bind、v-if、v-for这类声明式语法表达的效果永远优先用声明式。手动操作DOM是例外不是常态。1.2 哪些场景逼着你非操作DOM不可当然声明式不是万能的。模板语法再怎么强大也描述不了下面这些情况初始化某个第三方图表库必须传入一个真实的DOM容器节点。日期选择器、富文本编辑器这类组件本身就要挂载到指定元素上。需要精确测量元素的尺寸、位置比如做拖拽边界计算。元素聚焦、选中文本、设置剪贴板内容。操作canvas、video、audio这类有内部状态的媒体元素。做复杂滚动控制比如聊天列表滚动到底部、懒加载触发判断。判断标准我归纳成一句话模板语法能不能表达能就交给模板不能才考虑用ref、自定义指令或者其他方式去拿DOM。这个原则看起来简单但在真实项目里很容易被忽略。拿一个最常见的场景来说给列表项加一个当前选中样式完全可以通过v-for循环里的:class绑定实现根本不需要操作DOM。可如果不假思索地用document.querySelectorAll去改不仅会导致状态和UI不一致还会让组件难以测试、难以复用。2. 最入门的操作方式ref 与 $refs2.1 模板引用怎么用元素和组件Options API时代最直观的DOM操作方式就是ref属性加this.$refs。在模板任意元素上写一个refbox组件实例上就会多出一个$refs对象里面存着对应的DOM元素。template div classchart refchartBox/div /template script export default { mounted() { const el this.$refs.chartBox if (el) { // 这时候才能安全地初始化图表、绑定事件 this.initChart(el) } }, methods: { initChart(el) { // 把第三方库挂在el上 } } } /script需要特别注意的是时机。组件实例在created阶段已经创建但此时模板对应的DOM还没有挂载this.$refs.chartBox是undefined。最早能安全访问的钩子是mounted。如果你的某个DOM是v-if控制的那么在条件不成立的时候$refs里也没有这个属性必须等条件成立后下一次事件循环才能拿到。如果在子组件上使用ref拿到的就不再是DOM元素而是子组件的组件实例。通过这个实例访问data、methods或者调用$emit等方法。有时候你想拿子组件内部的根节点DOM可以用this.$refs.child.$el但我不太建议养成这个习惯。一旦子组件结构变化$el指向的节点可能就不符合预期了还容易造成组件间强耦合后面会专门讲这个问题。2.2 使用时机与注意点$refs 并不是响应式的this.$refs虽然挂在组件实例上但它本质上一个普通对象并不会触发响应式更新。这意味着你不能在computed里依赖它也不能通过watch监听某个$refs属性变化。很多新手在这里踩坑想在数据变化后立刻拿$refs读取新DOM的尺寸结果拿到的还是旧值然后就怀疑是不是框架有bug。其实这不是bug而是Vue的异步更新机制。当你修改响应式数据后DOM并不会同步更新Vue会把这个更新放到一个异步队列里等当前脚本执行完再统一patch。所以数据变了你想立刻拿到新DOM正确的姿势是等nextTickmethods: { async sendMessage() { this.messages.push(新消息) // 如果在下面直接访问this.$refs.scroller高度还是旧的 await this.$nextTick() this.$refs.scroller.scrollTop this.$refs.scroller.scrollHeight } }除了时机$refs还有两个容易忽略的细节。第一在v-for中使用ref$refs对应的值会是一个数组数组顺序和渲染顺序保持一致。但如果你同时在循环里做条件渲染数组的下标不一定等于数据下标操作时最好通过v-for的索引去对应别想当然。第二模板里的ref名字写错了不会报错$refs只会静默地返回undefined。调试这种问题最浪费时间我一般会先检查拼写再检查当前元素是否处于v-iffalse状态这两种情况占了九成。3. 把DOM操作封装成自定义指令3.1 指令钩子和生命周期如果同一个DOM操作需要在很多组件里重复使用每次都写在mounted里再复制粘贴代码会越来越难维护。这时候就该用自定义指令。自定义指令本身就是一个针对“单个元素DOM生命周期”的封装你可以指定它在什么时机做初始化、什么时候做清理。Vue 3里指令的钩子统一成了一套和组件生命周期对应created元素的属性或事件监听初始化前beforeMount元素挂载前mounted元素挂载完成可以访问DOM大部分初始操作放在这里beforeUpdate组件更新前updated组件更新后beforeUnmount元素卸载前unmounted元素卸载后举个例子一个最简单的“自动聚焦”指令const vFocus { mounted(el) { el.focus() } }在模板里用v-focus即可。这比在每个组件的mounted里手动this.$refs.input.focus()干净得多而且指令的钩子天然帮你处理了“元素刚挂载好”这个时机不需要再等nextTick。不过指令最容易被忽略的是清理工作。很多教程只讲mounted里加事件不讲unmounted里移除事件导致组件销毁后全局监听器还在内存泄漏、重复绑定问题接踵而至。我在实际开发里凡是往document、window上挂过监听的指令都会用el上挂一个私有属性来保存清理函数再在卸载钩子里调用。3.2 一个clickOutside实例点击元素外部关闭下拉框是自定义指令里最有代表性的场景。原因是这个行为涉及“全局监听”没法靠模板语法实现而且几乎每个下拉、弹窗、气泡组件都需要非常适合封装。const vClickOutside { mounted(el, binding) { const handler (event) { if (el.contains(event.target)) return if (typeof binding.value function) { binding.value(event) } } el.__clickOutsideHandler handler document.addEventListener(click, handler) }, unmounted(el) { document.removeEventListener(click, el.__clickOutsideHandler) delete el.__clickOutsideHandler } }用法template div v-click-outsidecloseDropdown button clickvisible !visible切换/button div v-ifvisible下拉内容/div /div /template几个细节要说明一下。事件监听器如果直接在mounted里写匿名函数unmounted里无法移除同一个引用所以你必须要用一个变量把它存下来。我习惯直接挂在el上这样即使多个指令叠加使用也不会互相干扰。其次判断是否点击外部用el.contains而不是document.contains因为el.contains(event.target)天然兼容点击了元素内部的文本节点、子元素等情况。指令里能拿到的binding还有很多内容binding.value表示传给指令的绑定值binding.arg表示指令参数binding.modifiers表示修饰符。比如v-click-outside:click.capture里的:click和.capture都能让你在不改代码逻辑的情况下区分监听事件类型或捕获阶段这是做通用设计时很有用的扩展点。4. Composition API 下的DOM操作4.1 script setup中如何绑定模板引用到了script setup组合式API时代模板引用变得更简洁了。核心规则是你在模板里写refxxx时它会自动去setup作用域里找有没有同名变量。如果存在一个const xxx ref(null)就把对应的DOM元素或组件实例赋给这个引用变量的.value。script setup import { ref, onMounted } from vue const inputRef ref(null) onMounted(() { inputRef.value?.focus() }) /script template input refinputRef typetext / /template这里有两个容易踩的点。第一变量名必须和模板里的ref字符串完全一致否则绑定不上但也不报错拿到的是null。第二访问模板引用要通过.value这跟在普通ref变量里存数字一样。很多人刚转组合式API时在onMounted里写inputRef.focus()结果调用的其实是ref对象的某个方法自然报错。组合式API下同样存在DOM更新时机问题。想在修改数据后马上操作DOM有两个选择。一是用await nextTick()这和Options API里的$nextTick是同一个机制。二是在watch回调里指定flush: post这样回调会在DOM更新之后执行适合“当某个数据变化后需要基于新DOM做下一步处理”的场景watch(() props.activeIndex, (newIndex) { listRef.value?.children[newIndex]?.scrollIntoView() }, { flush: post })4.2 v-for列表与函数式ref处理动态列表时简单地在v-for里写reflist会得到一个数组。这个数组能用但如果有大量条件渲染、元素增删数组的下标和当前数据项容易错位。更稳的方案是使用函数式ref也就是把ref绑定成一个函数由你自己来控制把元素存到哪里。script setup import { ref } from vue const itemRefs ref([]) function setItemRef(el, index) { if (el) { itemRefs.value[index] el } else { itemRefs.value.splice(index, 1) } } /script template div v-for(item, index) in items :keyitem.id :ref(el) setItemRef(el, index) {{ item.name }} /div /template函数式ref的规则是每次DOM更新后会用新的元素调用一次元素卸载时也会用null调用一次。所以函数里必须判断el是否存在。如果只做itemRefs.value[index] el而不处理null删除列表项时数组里会残留旧引用造成“明明删除了但还能拿到那个节点”的诡异问题。还有一点在模板里写:ref(el) setItemRef(el, index)每次重新渲染都会生成一个新的箭头函数。Vue在这种场景下把旧的函数以null调用所以处理逻辑要放在同一个命名函数里不要在setItemRef里依赖旧闭包。如果只是读取元素不涉及元素增删用内置数组ref的写法也可以但要注意索引稳定性。5. 更底层和更可靠的辅助手段5.1 组件实例与$el的边界除了模板ref组件实例本身也暴露了一些和DOM相关的入口。Vue 3里每个组件实例可以通过$el拿到当前组件渲染出的根元素。在Options API里是this.$el在script setup中可以通过getCurrentInstance()的proxy.$el访问但后者属于底层API日常开发不推荐直接使用。真正的核心问题是你有没有必要去拿一个子组件的根元素。很多人在父组件里获取子组件实例然后child.$el.querySelector(.xxx)去改里面的DOM这会把父组件和子组件的内部实现死死绑在一起。子组件一旦改了根节点结构父组件里的DOM操作可能直接失效而且这种跨组件修改对子组件来说是一种“意外入侵”。更合理的做法是让子组件自己暴露一个方法父组件通过模板引用调用。比如一个滚动容器子组件内部维护列表DOM然后提供scrollToBottom方法defineExpose({ scrollToBottom() { scrollerRef.value.scrollTop scrollerRef.value.scrollHeight } })父组件拿到的是子组件实例调用这个方法而不需要知道内部用的是哪个元素、类名是什么。这样DOM操作被封装在离DOM最近的地方也是我比较推荐的一种“安全操作DOM”姿势。5.2 render函数中的ref与vnodeVue的模板最终会被编译成render函数ref在render函数里其实就是一个普通的vnode属性。如果你在写手写render函数同样可以给节点挂ref而且可以用ref变量直接接收import { h, ref, onMounted } from vue export default { setup() { const box ref(null) onMounted(() { console.log(box.value) }) return () h(div, { ref: box }) } }这种写法能从更底层理解ref的本质它不是DOM操作API而是Vnode创建过程中预留的钩子。当Vnode被patch成真实DOM后Vue会把节点实例赋值给对应的ref变量。理解了这一点也就明白为什么ref只能在初始化之后拿到值因为虚拟DOM还没有变成真实DOM之前能赋值的对象根本不存在。5.3 nextTick异步更新下的DOM时机前面已经多次提到nextTick它值得单独拎出来说清楚。Vue的数据更新不是同步的。当你修改一个响应式数据页面上的DOM不会立刻变化而是等当前宏任务运行完微任务队列里执行patch。这个设计是为了合并同一轮里多次数据修改避免反复触发渲染代价就是你无法在数据修改后立刻读取到最新DOM。nextTick就是帮你等下一次DOM更新结束的Promise。在组合式API中可以直接await nextTick()在Options API里可以用this.$nextTick。很多情况下这是个兜底方案但我们还可以更进一步用watch搭配flush: post把“等DOM更新”这个动作和数据变化监听合并起来代码更清晰watch(source, async () { // 这时候DOM还没更新 await nextTick() // 这里可以安全读取最新DOM })需要警惕的是nextTick只保证“Vue的patch完成”不保证浏览器已经完成布局、样式计算和绘制。如果你需要读取元素的实际高度、位置建议在nextTick之后再用requestAnimationFrame包一层。这个组合我在做拖拽、动画的时候经常用能有效避开样式还没计算完导致的偏差。6. 实战中常见问题与避坑6.1 几个典型的坑第一个坑created里访问$refs。这个钩子里组件实例已经创建但渲染还没开始所以$refs一定是undefined。不只是$refs依赖DOM的第三方库初始化也绝对不能在created里做。所有涉及DOM的操作都推迟到mounted或者用户交互事件里。第二个坑把DOM节点放进reactive。有些人喜欢用reactive({ list: [] })来存一组元素引用结果发现操作卡顿或者引用行为诡异。因为reactive会给对象做深度代理而DOM节点本身结构复杂、属性很多被代理后会生成大量Proxy对象白白增加性能开销。存储DOM引用用普通数组或者ref就足够了别让响应式系统去劫持一个本不需要响应式的对象。第三个坑自定义指令卸载后没清理。在document、window上绑定的监听器、IntersectionObserver实例、定时器等如果在unmounted里不清理组件销毁后依然会被触发。尤其是Vue 3的keep-alive缓存组件组件不是销毁而是停用指令的unmounted可能根本不会被调用这时你就要考虑用deactivated钩子配合清理。第四个坑通过$el拿子组件根元素后直接改子组件内部的DOM。这会让数据流变得不可控。你在父组件里改了一个DOM类名但子组件内部的数据状态并没有同步下次子组件更新时改动就被覆盖。排查起来特别费劲因为“改的时候有效、刷新后失效”这种问题很难一眼定位。第五个坑动态ref的索引错位。在v-for里用数组ref时如果列表数据有插入、删除元素数组的顺序不一定和你的v-for索引一致。尤其配合v-if或动态组件时更容易出现“拿到的元素不是当前项”的问题。函数式ref虽然要自己维护数组但可控性更高。6.2 问题速查表症状常见原因推荐解法this.$refs.xxx或xxx.value是undefined访问时机太早元素还没挂载或v-if为false放在mounted、nextTick、watch的flush: post中修改数据后读取的DOM尺寸是旧值Vue异步更新DOM尚未patch完成使用await nextTick()后再读取v-for中ref数组顺序对不上循环里有条件渲染或动态增删改用函数式ref显式维护元素数组指令绑定的全局事件触发两次以上指令卸载时没有解绑或组件被keep-alive缓存重复触发在unmounted中移除监听必要时处理activated/deactivatedref拿到的是组件实例而不是DOM在组件标签上使用ref需要DOM时用$el但更推荐子组件通过defineExpose暴露方法列表删除后函数式ref里仍残留旧引用没有在el null时清理数组项在函数式ref中判断el为null时splice或置空6.3 我的操作习惯最后分享几个我这些年沉淀下来的操作习惯也算是对整个主题的实践总结。第一凡是能通过数据驱动解决的问题坚决不在业务代码里写querySelector。比如切换类名用:class绑定控制显隐用v-if修改文本用插值表达式。这不是教条而是为了让你维护状态时有一个唯一可信的数据来源。一但开始直接操作DOM以后别人改代码时很难猜到这个状态是从哪里来的。第二如果必须操作DOM优先找“最靠近这个DOM的位置”去操作。一个组件内部的ref好过父组件跨越层级去拿子组件的$el一个自定义指令的mounted钩子好过在每个页面里重复写初始化和清理逻辑。把DOM操作约束在局部后续重构时才不会牵一发而动全身。第三写任何和DOM相关的代码前先想清楚清理工作。事件监听要解绑定时器要清除第三方实例要销毁。把这些代码和初始化代码放在一起形成一种条件反射。我见过太多因为漏了清理导致的内存泄漏问题最后排查时都特别痛苦因为问题往往在页面切换几十次之后才出现。在Vue里操作DOM并不难难的是在正确的地方、用正确的方式去操作。理解了声明式渲染、ref、自定义指令、组件边界和异步更新时机你在真实项目里遇到任何“拿不到DOM”“改完没生效”的问题基本都能快速定位。希望这篇经验整理能给正在跟DOM搏斗的你一点帮助。

相关新闻

RT-LAB实时仿真实战:模型拆分、HIL测试与常见故障排查指南

RT-LAB实时仿真实战:模型拆分、HIL测试与常见故障排查指南

最近团队接了一个半实物仿真项目,甲方要求控制系统必须在实时环境下验证,我花了差不多两个星期啃 RT-LAB 文档。本来以为实时仿真就是把 Simulink 模型搭好直接编译下装,结果一上手就发现根本不是这么回事。光是Perspectives.144117571这一份…

2026/10/18 9:33:31 阅读更多 →
LJ-Navigator2安装部署全解析:从YAML配置到批处理引擎

LJ-Navigator2安装部署全解析:从YAML配置到批处理引擎

简介:LJ-Navigator2安装包是一份面向LJ系列设备使用者的专业调试工具资源,由作者以RAR压缩包形式提供,整体容量约397.08MB。该工具聚焦互换积分操作,能够辅助用户完成通信协议解析、设备状态监控以及交互数据检查,适用…

2026/10/18 9:33:31 阅读更多 →
AI营销如何打通全域增长命脉:断点拆解与落地指南

AI营销如何打通全域增长命脉:断点拆解与落地指南

AI营销榜单发布后的那段时间,我被问得最多的一个词不是“AI”,而是“全域增长”。榜单上被重点提到的,正是一家以前很少出现在大众视野里的MarTech公司。它凭什么能被视为2026年增长命脉的打通者?很多人以为这只是又一轮概念包装&…

2026/10/18 9:33:31 阅读更多 →

最新新闻

银行卡BIN号数据迁移实战:Excel到MySQL与PostgreSQL完整方案

银行卡BIN号数据迁移实战:Excel到MySQL与PostgreSQL完整方案

简介:这份资源面向金融数据分析、风控开发及数据库运维人员,提供2020年4月25日版银行卡BIN号数据集合,用于识别发卡行、卡片类型与归属机构,支撑交易验证、反欺诈与客户分析等场景。压缩包共7个文件,包含5个xls表格与2…

2026/10/18 10:08:39 阅读更多 →
RDMA Queue Pair(QP)状态机详解:从Reset到RTS的配置与故障排查

RDMA Queue Pair(QP)状态机详解:从Reset到RTS的配置与故障排查

RDMA这个技术,特别是Queue Pair(QP)这一块,很多做网络、存储和高性能计算的同学,最初都会被两个概念卡住:为什么网卡收包非要搞出一对队列?状态机又是什么鬼?我当年第一次从Reset状态…

2026/10/18 10:08:39 阅读更多 →
SpringBoot+Vue3在线文档管理系统:权限、版本与部署实战

SpringBoot+Vue3在线文档管理系统:权限、版本与部署实战

说到在线文档管理系统,不少人第一反应是装一个现成的开源 Wiki 完事。但真去企业里做一轮知识库整合之后,你会发现项目最难的地方根本不是“把文档传上去”,而是怎么把权限、版本、分类、检索和在线编辑这些看似零散的能力收进同一套框架里。…

2026/10/18 10:08:39 阅读更多 →
Flink SQL自定义Connector开发:从零实现数据源接入

Flink SQL自定义Connector开发:从零实现数据源接入

做 Flink 实时计算的同学迟早会遇到一个场景:官方提供的 JDBC、Kafka、File 等连接器都试了一遍,发现某类业务数据源官方根本没适配。要么是自研消息队列只能通过 API 硬编码拉数据,要么是某内部存储系统需要以 Source 方式接入 SQL 作业&…

2026/10/18 10:08:39 阅读更多 →
Flink SQL自定义Connector实战:实现数据源扩展的完整指南

Flink SQL自定义Connector实战:实现数据源扩展的完整指南

经常有朋友问我,Flink SQL 里想接入一个内部系统,结果官方连接器里根本没有,要怎么搞?我的回答一直是:自己写一个自定义 Connector,别等官方。这篇文章就来聊聊 Flink SQL Connector 开发里最实用的一条链路…

2026/10/18 10:08:39 阅读更多 →
告别熬夜改稿:AI辅助PPT制作全流程效率提升实战指南

告别熬夜改稿:AI辅助PPT制作全流程效率提升实战指南

凌晨两点十七分,我对着同一页公司介绍已经改了第九遍,只因为上面那条业务模块的配图怎么摆都差那么点意思。这不是我第一次为PPT熬夜,也大概率不会是最后一次——如果我没在那个周末试过那款叫PaperXieAIPPT的工具的话。真正让我把标题写成“…

2026/10/18 10:07:39 阅读更多 →

日新闻

基于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/18 0:00:55 阅读更多 →

周新闻

基于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/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 14:23:36 阅读更多 →