2026/1/21 12:56:01
网站建设
项目流程
南京博物馆网站哪家做的,西安seo诊断,网站建设企业谁家好,正能量网站免费进入无需下载Quasar v-close-popup 指令核心用法总结
v-close-popup 是 Quasar 框架的辅助指令#xff0c;专为 QDialog#xff08;对话框#xff09;和 QMenu#xff08;菜单#xff09;设计#xff0c;点击绑定该指令的元素时#xff0c;会自动关闭其祖先链中的弹出组件#xff…Quasar v-close-popup 指令核心用法总结v-close-popup 是 Quasar 框架的辅助指令专为 QDialog对话框和 QMenu菜单设计点击绑定该指令的元素时会自动关闭其祖先链中的弹出组件优先关闭最近的父级弹出组件。核心配置API指令值支持 Boolean、Number 或 String 类型不同值对应不同关闭行为指令值行为说明示例0 / false禁用指令点击不关闭任何弹出组件v-close-popup0 0如 -1关闭链中所有弹出组件v-close-popup-11 / true / 未定义仅关闭最近的父级弹出组件默认行为v-close-popup/v-close-popuptrue 1如 2、3关闭链中指定数量的父级弹出组件链式 QMenu 视为 1 个弹出组件v-close-popup2关闭 2 级父弹出组件基础用法1. 关闭单个弹出组件QMenu/QDialog示例QMenu 中使用q-btn label打开菜单 colorprimary q-menu q-list !-- 点击关闭当前菜单 -- q-item clickable v-close-popup q-item-section菜单选项 1/q-item-section /q-item !-- 动态禁用指令cancelEnabled 为布尔值 -- q-item clickable v-close-popupcancelEnabled q-item-section菜单选项 2/q-item-section /q-item /q-list /q-menu /q-btn示例QDialog 中使用q-dialog v-modelisDialogOpen q-card q-card-actions !-- 点击关闭当前对话框 -- q-btn label取消 v-close-popup / q-btn label确认 v-close-popup / /q-card-actions /q-card /q-dialog2. 关闭多个级别的弹出组件适用于弹出组件嵌套场景如 “对话框内嵌套菜单”“菜单内嵌套子菜单”!-- 对话框内嵌套菜单点击关闭菜单和对话框2 级弹出组件 -- q-dialog v-modeldialog q-card q-btn label打开菜单 q-menu q-list q-item clickable v-close-popup2 q-item-section关闭菜单和对话框/q-item-section /q-item /q-list /q-menu /q-btn /q-card /q-dialog !-- 嵌套对话框点击关闭两个对话框2 级弹出组件 -- q-dialog v-modeldialog1 q-card q-btn clickdialog2 true label打开子对话框 / q-dialog v-modeldialog2 q-card q-btn label关闭两个对话框 v-close-popup2 / /q-card /q-dialog /q-card /q-dialog3. 链式菜单特殊规则链式 QMenu一个菜单直接嵌套在另一个菜单内视为 1 个弹出组件无需指定多级数值使用v-close-popup即可关闭整个链式菜单q-btn label主菜单 q-menu q-list q-item clickable q-item-section子菜单/q-item-section q-menu q-list q-item clickable q-item-section三级菜单/q-item-section q-menu !-- 点击关闭整个链式菜单视为 1 级 -- q-item clickable v-close-popup q-item-section关闭所有菜单/q-item-section /q-item /q-menu /q-item /q-list /q-menu /q-item /q-list /q-menu /q-btn关键特性与注意事项作用范围仅对 QDialog 和 QMenu 生效且只关闭其祖先链中的弹出组件非同级或后代组件动态控制指令值支持响应式变量如v-close-popupisEnabled可动态启用 / 禁用关闭功能同级弹出组件若弹出组件为同级关系非嵌套需通过v-model手动控制关闭指令无法直接关闭QPopupProxy 影响QPopupProxy 会分隔链式菜单此时嵌套菜单需按实际级别指定数值。Quasar v-intersection 指令核心用法总结v-intersection 是 Quasar 基于 Intersection Observer API 封装的指令用于监听元素是否进入 / 离开视口或指定的根容器常用于实现懒加载、无限滚动、曝光埋点等功能。一、核心配置API1. 指令值格式支持Function回调函数或Object配置对象两种格式的核心参数如下配置项类型默认值说明handlerFunction-元素交叉状态变化时的回调函数必传optionsObject{}Intersection Observer 配置项可选onceBooleanfalse是否只触发一次回调触发后自动停止监听2. options 详细配置同原生 API子配置项类型默认值说明rootElement/Stringnull根容器监听元素相对于该容器的交叉状态传 CSS 选择器或 DOM 元素默认是视口rootMarginString0px根容器的外边距扩展 / 收缩根容器的检测区域支持px/%如100px 20pxthresholdNumber/Array0交叉比例阈值0~1触发回调的交叉比例如0.5表示元素 50% 进入根容器时触发3. 回调函数参数(entries, observer, isIntersecting) { // entries: 原生 IntersectionObserverEntry 数组 // observer: 原生 IntersectionObserver 实例 // isIntersecting: 布尔值元素是否进入根容器简化判断 }二、基础用法1. 最简用法监听视口交叉直接传入回调函数默认监听元素是否进入视口template !-- 监听元素进入/离开视口 -- div v-intersectionhandleIntersection classh-200 bg-grey-2 滚动视口观察我 /div /template script setup const handleIntersection (entries, observer, isIntersecting) { if (isIntersecting) { console.log(元素进入视口) // 执行懒加载/曝光埋点等逻辑 } else { console.log(元素离开视口) } } /script2. 只触发一次如懒加载图片通过once: true配置触发一次后停止监听避免重复执行template !-- 图片懒加载进入视口后加载真实图片只触发一次 -- div classimg-placeholder v-intersectionlazyLoadConfig img refimgRef :srcplaceholder alt懒加载图片 / /div /template script setup import { ref } from vue const imgRef ref(null) const placeholder https://via.placeholder.com/400x300 const realSrc https://picsum.photos/400/300 const lazyLoadConfig { once: true, // 只触发一次 handler: (entries, observer, isIntersecting) { if (isIntersecting) { imgRef.value.src realSrc // 加载真实图片 } } } /script3. 自定义根容器与阈值监听元素相对于指定容器的交叉状态设置交叉比例阈值template !-- 根容器带滚动条的区域 -- div refrootContainer classh-400 overflow-auto bg-grey-1 p-4 div classh-800 mb-4占位内容/div !-- 监听该元素相对于根容器的交叉状态 -- div v-intersectioncontainerIntersectConfig classh-200 bg-primary text-white 相对于根容器的交叉元素 /div /div /template script setup import { ref } from vue const rootContainer ref(null) const containerIntersectConfig { handler: (entries, observer, isIntersecting) { console.log(相对于根容器的交叉状态, isIntersecting) }, options: { root: rootContainer, // 根容器为 ref 指向的 DOM 元素 threshold: 0.3, // 元素 30% 进入根容器时触发 rootMargin: 50px // 根容器外边距扩展 50px 检测区域 } } /script4. 无限滚动加载更多数据结合滚动容器监听 “加载更多” 按钮的交叉状态实现无限滚动template div refscrollContainer classh-500 overflow-auto div v-foritem in list :keyitem.id classp-4 border-b {{ item.content }} /div !-- 监听加载更多按钮进入视口 -- div v-intersectionloadMoreConfig classtext-center p-4 q-spinner v-ifloading / span v-else{{ hasMore ? 加载更多 : 没有更多数据了 }}/span /div /div /template script setup import { ref, reactive } from vue const scrollContainer ref(null) const list ref([]) const loading ref(false) const hasMore ref(true) let page 1 // 模拟加载数据 const fetchData async () { loading.value true // 模拟接口请求 await new Promise(resolve setTimeout(resolve, 1000)) const newData Array.from({ length: 10 }, (_, i) ({ id: ${page}-${i}, content: 列表项 ${page}-${i} })) list.value.push(...newData) loading.value false if (page 5) hasMore.value false // 模拟最多5页数据 page } // 无限滚动配置 const loadMoreConfig { handler: (entries, observer, isIntersecting) { // 元素进入视口 非加载中 有更多数据时加载下一页 if (isIntersecting !loading.value hasMore.value) { fetchData() } }, options: { root: scrollContainer, threshold: 0.1 } } // 初始化加载第一页 fetchData() /script特殊得到template div classrelative-position div classexample-area q-pa-lg scroll div classexample-filler / q-list q-item v-forn in 30 :keyn :data-idn classq-my-md q-pa-sm bg-grey-3 v-intersectiononIntersection q-item-section classtext-center stylebackground: #eee Item #{{ n }} /q-item-section /q-item /q-list div classexample-filler / /div div classexample-state bg-primary text-white overflow-hidden rounded-borders text-center absolute-top-left q-ma-md q-pa-sm transition-group v-ifinView.length 0 namein-view tagul li v-fori in inView :keyi classin-view-item {{i}} /li /transition-group /div /div /template script import { ref } from vue export default { setup () { const inView ref([]) function onIntersection (entry) { if (entry.isIntersecting true) { add(entry.target.dataset.id) } else { remove(entry.target.dataset.id) } } function add (i) { remove(i) inView.value.push(i) inView.value.sort(sortAtoi) } function remove (i) { let index while ((index inView.value.indexOf(i)) -1) { inView.value.splice(index, 1) inView.value.sort(sortAtoi) } } function sortAtoi (a, b) { return Number(a) - Number(b) } return { inView, onIntersection } } } /script style langsass scoped .example-state width: 50px height: 226px opacity: 0.85 ul list-style: none margin: 0 padding: 0 li padding: 0.5em .example-area height: 300px .example-filler height: 350px .in-view-item transition: all 0.3s display: block .in-view-enter, .in-view-leave-to opacity: 0 transform: translateX(-30px) .in-view-leave-active position: absolute /style三、关键特性与注意事项1. 核心特性性能优化基于原生 Intersection Observer API异步监听交叉状态不阻塞主线程优于 scroll 事件监听灵活配置支持自定义根容器、阈值、触发次数适配不同业务场景简化判断回调函数直接提供isIntersecting布尔值无需解析entries数组自动清理组件卸载时自动停止监听并销毁 Observer 实例避免内存泄漏。2. 注意事项根容器要求若指定root为自定义容器该容器必须具有overflow: auto/scroll样式否则无法检测滚动阈值理解threshold: 0表示元素刚进入根容器时触发threshold: 1表示元素完全进入根容器时触发rootMargin 单位仅支持px或%不支持rem/em等单位浏览器兼容性支持所有现代浏览器IE 需 polyfillQuasar 未内置需自行引入 intersection-observer polyfill。3. 高级技巧手动停止监听若需在回调外停止监听可通过observer.disconnect()销毁 Observer 实例javascript运行const handleIntersection (entries, observer) { if (someCondition) { observer.disconnect() // 手动停止监听 } }多阈值触发threshold传数组如[0, 0.5, 1]元素交叉比例达到每个阈值时都会触发回调javascript运行options: { threshold: [0, 0.5, 1] // 进入、半进入、完全进入时各触发一次 }四、常见业务场景图片 / 视频懒加载元素进入视口后加载真实资源减少首屏加载时间无限滚动列表监听 “加载更多” 按钮自动加载下一页数据曝光埋点元素进入视口时上报埋点数据如广告曝光、内容曝光滚动动画触发元素进入视口时执行 CSS/JS 动画吸顶 / 吸底组件监听元素与视口的交叉状态动态切换固定定位。Quasar v-ripple 指令核心用法总结v-ripple 是 Quasar 框架提供的 Material 风格波纹效果指令可快速为任意 DOM 元素或组件添加点击 / 触摸波纹反馈核心信息如下核心注意事项无需在已有波纹效果的 Quasar 组件如 QBtn上使用需通过组件自身ripple属性配置目标元素必须设置position: relative或 Quasar 辅助类relative-position否则波纹定位异常。核心配置API配置项类型说明示例center修饰符Boolean波纹从元素绝对中心触发默认从触摸点触发v-ripple.centerearly修饰符 / 属性Boolean提前触发波纹用户首次交互即触发如 mousedown/touchstartv-ripple.early或v-ripple{ early: true }stop修饰符Boolean阻止点击 / 触摸事件冒泡v-ripple.stopcolorString波纹颜色使用 Quasar 调色板颜色名v-ripple:purple或v-ripple{ color: yellow }keyCodesArray/Number触发波纹的键盘按键编码v-ripple{ keyCodes: [13, 32] }回车 / 空格指令值Boolean控制波纹启用 / 禁用v-ripplestatestate 为布尔值基础用法1. 基础效果vuediv v-ripple classrelative-position p-4 bg-grey-2 Click/tap me /div2. 自定义颜色直接通过参数指定颜色v-ripple:purple通过对象配置颜色v-ripple{ color: yellow }默认继承元素文本颜色3. 定位控制中心触发v-ripple.center触摸点触发默认v-ripple4. 提前触发v1.9.8vuediv v-ripple.early classrelative-position p-4 bg-grey-2 提前触发波纹 /div5. 动态启用 / 禁用vuetemplate div v-rippleisRippleEnabled classrelative-position p-4 bg-grey-2 动态控制波纹 /div q-toggle v-modelisRippleEnabled label启用波纹 / /template script setup const isRippleEnabled ref(true) /script关键特性兼容性适配桌面端点击 / 键盘和移动端触摸交互灵活性支持修饰符.center/.early/.stop和对象配置两种方式样式继承默认继承元素文本颜色减少配置成本事件控制可通过stop修饰符阻止事件冒泡适配复杂交互场景。Quasar v-mutation 指令深度解析附实战案例v-mutation 是 Quasar 对原生MutationObserver API的封装用于监听 DOM 元素的属性、子节点、文本内容变化解决了传统 DOM 监听需手动绑定 / 销毁的痛点适用于第三方组件 DOM 监控、动态内容渲染检测等场景。一、核心能力与适用场景1. 能监听的 DOM 变化类型✅ 元素属性class/style/id 等增删改✅ 子节点新增 / 删除 / 移动✅ 文本内容修改✅ 子孙节点变化通过subtree配置2. 典型业务场景第三方组件状态同步如监听弹窗display属性变化动态渲染内容检测如富文本编辑器加载完成DOM 结构合规性校验如列表渲染后子节点数量检查响应式样式变更监听如主题切换后 class 变化二、完整 API 配置1. 指令值格式二选一格式类型示例说明回调函数v-mutationhandleChange最简用法默认监听所有变化配置对象v-mutation{ handler: fn, options: {}, once: true }精细控制监听规则2. 配置对象核心参数参数类型默认值作用handlerFunction-必传DOM 变化触发的回调函数optionsObject见下表监听规则配置同原生 MutationObserveronceBooleanfalse是否仅触发一次触发后自动停止监听3. options 详细配置精准控制监听范围子配置类型默认值作用实战建议attributesBooleantrue监听属性变化仅需监听属性时设为true其他设为falseattributeFilterArray[]仅监听指定属性如[class, style]避免无关属性触发回调提升性能attributeOldValueBooleanfalse回调中返回属性旧值需要对比属性前后值时开启childListBooleantrue监听子节点增删列表渲染 / 动态组件场景必开subtreeBooleantrue监听子孙节点变化仅需监听当前元素时设为falsecharacterDataBooleantrue监听文本内容变化仅需监听文本时开启characterDataOldValueBooleanfalse回调中返回文本旧值需要对比文本前后值时开启4. 回调函数参数详解// 回调函数完整参数 const handleMutation (mutations, observer) { mutations.forEach(mutation { // 1. 变化类型attributes/childList/characterData console.log(变化类型, mutation.type); // 2. 发生变化的DOM元素 console.log(目标元素, mutation.target); // 3. 不同变化类型的专属信息 if (mutation.type attributes) { console.log(变化属性名, mutation.attributeName); console.log(属性旧值, mutation.oldValue); // 需开启 attributeOldValue } else if (mutation.type childList) { console.log(新增节点, mutation.addedNodes); console.log(移除节点, mutation.removedNodes); } else if (mutation.type characterData) { console.log(文本旧值, mutation.oldValue); // 需开启 characterDataOldValue } }); };三、实战案例覆盖 80% 业务场景案例0template div div classrow no-wrap justify-around q-px-md q-pt-md div v-mutationhandler1 dragenteronDragEnter dragleaveonDragLeave dragoveronDragOver droponDrop classdrop-target rounded-borders overflow-hidden div idbox1 draggabletrue dragstartonDragStart classbox navy / div idbox2 draggabletrue dragstartonDragStart classbox red / div idbox3 draggabletrue dragstartonDragStart classbox green / div idbox4 draggabletrue dragstartonDragStart classbox orange / div idbox5 draggabletrue dragstartonDragStart classbox navy / div idbox6 draggabletrue dragstartonDragStart classbox red / div idbox7 draggabletrue dragstartonDragStart classbox green / div idbox8 draggabletrue dragstartonDragStart classbox orange / /div div v-mutationhandler2 dragenteronDragEnter dragleaveonDragLeave dragoveronDragOver droponDrop classdrop-target rounded-borders overflow-hidden / /div div classrow justify-around items-start div classcol row justify-center q-pa-md div classtext-subtitle1 Mutation Info /div div v-forstatus in status1 :keystatus {{ status }} /div /div div classcol row justify-center q-pa-md div classtext-subtitle1 Mutation Info /div div v-forstatus in status2 :keystatus {{ status }} /div /div /div /div /template script import { ref } from vue export default { setup () { const status1 ref([]) const status2 ref([]) return { status1, status2, handler1 (mutationRecords) { status1.value [] for (const index in mutationRecords) { const record mutationRecords[ index ] const info type: ${record.type}, nodes added: ${record.addedNodes.length 0 ? true : false}, nodes removed: ${record.removedNodes.length 0 ? true : false}, oldValue: ${record.oldValue} status1.value.push(info) } }, handler2 (mutationRecords) { status2.value [] for (const index in mutationRecords) { const record mutationRecords[ index ] const info type: ${record.type}, nodes added: ${record.addedNodes.length 0 ? true : false}, nodes removed: ${record.removedNodes.length 0 ? true : false}, oldValue: ${record.oldValue} status2.value.push(info) } }, // store the id of the draggable element onDragStart (e) { e.dataTransfer.setData(text, e.target.id) e.dataTransfer.dropEffect move }, onDragEnter (e) { // dont drop on other draggables if (e.target.draggable ! true) { e.target.classList.add(drag-enter) } }, onDragLeave (e) { e.target.classList.remove(drag-enter) }, onDragOver (e) { e.preventDefault() }, onDrop (e) { e.preventDefault() // dont drop on other draggables if (e.target.draggable true) { return } const draggedId e.dataTransfer.getData(text) const draggedEl document.getElementById(draggedId) // check if original parent node if (draggedEl.parentNode e.target) { e.target.classList.remove(drag-enter) return } // make the exchange draggedEl.parentNode.removeChild(draggedEl) e.target.appendChild(draggedEl) e.target.classList.remove(drag-enter) } } } } /script style scoped langsass .drop-target height: 400px width: 200px min-width: 200px background-color: gainsboro .drag-enter outline-style: dashed .box width: 100px height: 100px float: left cursor: pointer media only screen and (max-width: 500px) .drop-target height: 200px width: 100px min-width: 100px background-color: gainsboro .box width: 50px height: 50px .box:nth-child(3) clear: both .navy background-color: navy .red background-color: firebrick .green background-color: darkgreen .orange background-color: orange /style案例 1监听第三方组件弹窗状态属性监听需求监听第三方弹窗组件的display属性变化同步本地弹窗状态template !-- 第三方弹窗组件假设无法通过v-model控制 -- third-party-modal refmodalRef v-mutationmodalMutationConfig / div弹窗状态{{ isModalOpen ? 打开 : 关闭 }}/div /template script setup import { ref } from vue; const isModalOpen ref(false); const modalRef ref(null); // 弹窗监听配置 const modalMutationConfig { handler: (mutations) { const display mutations[0].target.style.display; isModalOpen.value display ! none; }, options: { attributes: true, // 仅监听属性 attributeFilter: [style], // 仅监听style属性 subtree: false, // 不监听子孙节点 childList: false, // 不监听子节点 characterData: false // 不监听文本 } }; /script案例 2动态列表渲染完成检测子节点监听需求监听异步加载的列表是否渲染完成完成后执行统计逻辑template div reflistRef v-mutationlistMutationConfig classlist-container !-- 异步渲染的列表项 -- div v-foritem in listData :keyitem.id classlist-item {{ item.name }} /div /div /template script setup import { ref, onMounted } from vue; const listRef ref(null); const listData ref([]); // 模拟异步加载数据 const fetchList () { setTimeout(() { listData.value [ { id: 1, name: 商品1 }, { id: 2, name: 商品2 }, { id: 3, name: 商品3 } ]; }, 1000); }; // 列表渲染监听配置 const listMutationConfig { once: true, // 仅触发一次 handler: () { console.log(列表渲染完成当前数量, listRef.value.children.length); // 执行统计/埋点逻辑 }, options: { childList: true, // 仅监听子节点变化 attributes: false, characterData: false } }; onMounted(() { fetchList(); }); /script案例 3文本内容修改监控防篡改场景需求监听重要文本区域的内容修改记录修改日志template div reftextRef v-mutationtextMutationConfig contenteditabletrue classeditable-text 请输入重要内容修改会被记录 /div div classlog修改日志{{ logs.join(, ) }}/div /template script setup import { ref } from vue; const textRef ref(null); const logs ref([]); // 文本修改监听配置 const textMutationConfig { handler: (mutations) { const oldText mutations[0].oldValue; const newText mutations[0].target.textContent; logs.value.push(旧值${oldText} → 新值${newText}); }, options: { characterData: true, // 监听文本变化 characterDataOldValue: true, // 返回文本旧值 subtree: true, // 监听子节点文本contenteditable 元素的文本可能在子节点 attributes: false, childList: false } }; /script四、性能优化与避坑指南1. 性能优化技巧✅ 最小化监听范围通过attributeFilter/subtree限制监听内容避免全量监听✅ 按需开启once只需一次监听的场景如加载完成开启后自动销毁 Observer✅ 避免循环触发回调中修改当前监听元素的 DOM 时需加条件判断如通过标记跳过2. 常见坑点与解决方案坑点解决方案回调不触发1. 检查options配置是否正确2. 确保监听元素已挂载配合nextTick3. 第三方组件需等待其渲染完成重复触发回调1. 开启once单次场景2. 通过条件过滤无效变化如属性值未实际改变内存泄漏1. 组件卸载时 Quasar 会自动销毁 Observer无需手动处理2. 手动停止监听用observer.disconnect()无法监听输入框值变化输入框值变化优先用input事件DOM 监听仅作为兜底监听value属性需开启attributes3. 手动控制监听生命周五、与原生 MutationObserver 的对比特性Quasar v-mutation原生 MutationObserver初始化一行指令绑定需手动创建实例、调用observe销毁组件卸载自动销毁需手动调用disconnect配置简化默认配置覆盖常见场景需手动配置所有参数兼容性自动适配需 polyfill 时自行引入需手动处理兼容性易用性高Vue 生态无缝集成低原生 API 繁琐六、扩展场景结合其他指令使用1. v-mutation v-intersection曝光 内容修改监控template !-- 元素进入视口后开始监控内容修改 -- div v-intersectioninitMutation refcardRef classcontent-card 曝光后监控修改 /div /template script setup import { ref } from vue; const cardRef ref(null); let mutationDirective null; const initMutation (entries, observer, isIntersecting) { if (isIntersecting) { // 元素曝光后手动绑定v-mutation指令Quasar 指令可通过vnode动态绑定 mutationDirective cardRef.value.$q.directives.mutation; mutationDirective.bind(cardRef.value, { value: { handler: () console.log(内容已修改), options: { characterData: true } } }); observer.disconnect(); // 停止曝光监听 } }; /scriptQuasar v-morph 指令核心用法总结v-morph 是 Quasar 提供的元素过渡变形指令用于实现两个不同 DOM 元素之间的平滑过渡动画如形状、位置、大小的渐变核心原理是在过渡过程中创建一个 “替身元素” 模拟变形效果适用于模态框弹出、组件切换、元素复用等场景替代传统的淡入淡出 / 滑动过渡提升交互视觉体验。一、核心概念与原理变形主体通过指令绑定的 “源元素” 和 “目标元素”需通过key关联替身元素过渡期间自动创建的临时元素继承源元素的样式并逐步过渡到目标元素样式过渡触发通过修改绑定的key值触发变形key 变化时Quasar 识别源 / 目标元素并启动动画样式继承默认继承元素的width/height/position/background/border-radius等核心样式确保变形连贯。二、基础配置API1. 指令绑定格式!-- 核心v-morph唯一key值key变化触发变形 -- component v-morphmorphKey :iscurrentComponent / !-- 或单个元素切换状态 -- div v-morphmorphKey :classisActive ? active : inactive /2. 全局 / 局部配置可通过 Quasar 配置或指令修饰符自定义变形行为配置项类型默认值说明durationNumber300变形动画时长mseasingStringcubic-bezier(0.4, 0, 0.2, 1)动画缓动函数delayNumber0动画延迟msopacityBooleantrue是否包含透明度过渡scaleBooleanfalse是否包含缩放过渡优先级高于宽高过渡zIndexNumber4000替身元素的 z-index确保覆盖其他元素3. 指令修饰符修饰符作用示例.no-opacity禁用透明度过渡v-morph.no-opacitykey.scale启用缩放过渡替代宽高过渡v-morph.scalekey.instant立即完成变形无动画v-morph.instantkey三、实战案例案例 1按钮 → 模态框变形经典场景实现点击按钮后按钮平滑变形为模态框的过渡效果template div classq-pa-md !-- 源元素按钮 -- q-btn v-if!showModal v-morphmorphKey label打开模态框 colorprimary classq-mb-md clickshowModal true / !-- 目标元素模态框 -- q-dialog v-ifshowModal v-morphmorphKey v-modelshowModal maximizedfalse q-card classq-pa-md q-card-title变形后的模态框/q-card-title q-card-section 这是由按钮变形而来的模态框关闭后会反向变形为按钮 /q-card-section q-card-actions q-btn label关闭 colornegative clickshowModal false / /q-card-actions /q-card /q-dialog /div /template script setup import { ref } from vue const showModal ref(false) const morphKey ref(btn-to-modal) // 固定key通过v-if切换元素触发变形 /script案例 2卡片切换变形组件复用实现两个卡片之间的平滑变形切换template div classq-pa-md div classflex flex-col gap-md q-btn label切换卡片 colorprimary clicktoggleCard / !-- 变形容器通过key切换卡片 -- component v-morphcardKey :iscurrentCard classw-64 h-40 rounded-lg shadow-md flex items-center justify-center / /div /div /template script setup import { ref, computed } from vue const currentCard ref(card1) const cardKey ref(card-switch) // 变形key // 切换卡片组件 const toggleCard () { currentCard.value currentCard.value card1 ? card2 : card1 } // 卡片组件1 const Card1 { template: div classbg-primary text-white卡片 1/div } // 卡片组件2 const Card2 { template: div classbg-secondary text-white卡片 2/div } /script案例 3带缩放的元素变形修饰符使用启用缩放过渡实现元素大小和位置的同步变形template div classq-pa-md relative !-- 源元素小方块 -- div v-if!expanded v-morph.scalescaleKey classabsolute top-10 left-10 w-20 h-20 bg-primary rounded-md clickexpanded true / !-- 目标元素大方块 -- div v-ifexpanded v-morph.scalescaleKey classabsolute top-20 left-20 w-60 h-60 bg-primary rounded-lg clickexpanded false / /div /template script setup import { ref } from vue const expanded ref(false) const scaleKey ref(scale-morph) /script四、关键特性与注意事项1. 核心特性自动样式匹配替身元素自动计算源 / 目标元素的位置、大小、样式差异生成平滑过渡支持动态元素通过v-if/component切换的元素均可触发变形轻量级实现基于 CSS 过渡无额外 DOM 开销过渡后替身元素自动销毁兼容 Quasar 组件可直接用于 QBtn、QCard、QDialog 等内置组件。2. 注意事项key 唯一性同一变形组的源 / 目标元素必须绑定相同的key否则无法触发变形定位要求变形元素建议使用position: relative/absolute/fixed避免静态定位导致位置计算错误样式冲突避免为元素设置overflow: hidden可能裁剪替身元素或transform手动变换会干扰变形动画性能优化复杂元素变形如包含图片 / 大量子节点建议开启scale修饰符缩放比宽高过渡更高效反向变形关闭目标元素如模态框时需保持key不变通过v-if切换回源元素实现反向变形z-index 层级替身元素默认 z-index 为 4000若被其他元素覆盖可通过全局配置提高zIndex// quasar.config.js framework: { config: { morph: { zIndex: 5000 } } }3. 高级配置全局 / 局部全局配置quasar.config.jsmodule.exports { framework: { config: { morph: { duration: 500, // 动画时长500ms easing: ease-in-out, // 缓动函数 opacity: false // 禁用透明度过渡 } } } }局部配置指令值为对象template div v-morphmorphConfig :keymorphKey.../div /template script setup const morphConfig { key: custom-morph, // 变形key duration: 400, easing: cubic-bezier(0.1, 0.9, 0.2, 1), opacity: true } /script五、常见问题与解决方案问题解决方案变形动画不触发1. 检查源 / 目标元素是否绑定相同key2. 确保通过v-if/component切换元素而非v-show3. 元素定位是否为非静态relative/absolute/fixed变形过程中元素闪烁1. 开启opacity过渡默认开启2. 提高替身元素 z-index3. 避免元素有box-shadow/border等复杂样式变形位置偏移1. 统一源 / 目标元素的父容器定位方式2. 避免使用margin控制位置改用top/left或 flex 布局3. 检查元素是否有transform手动变换反向变形失效关闭目标元素时保持key不变仅通过v-if切换回源元素不要修改key值六、适用场景总结按钮 → 弹窗 / 抽屉点击按钮后变形为弹窗提升交互连贯性列表项 → 详情页列表项点击后放大变形为详情页替代跳转动画组件切换不同状态组件如空状态 / 数据状态之间的平滑变形菜单展开按钮变形为下拉菜单增强视觉关联加载状态过渡加载中元素变形为加载完成元素减少视觉断层。Quasar v-scroll 指令核心用法总结v-scroll 是 Quasar 提供的滚动监听指令用于监听元素或视口的滚动事件支持配置滚动触发条件、节流控制等适用于实现滚动加载、吸顶 / 吸底、滚动动画等场景。一、核心配置API1. 指令值格式支持Function滚动回调或Object配置对象核心参数如下配置项类型默认值说明handlerFunction-滚动触发的回调函数必传targetString/Elementwindow滚动监听目标window视口、CSS 选择器、DOM 元素throttleNumber0滚动回调节流时间ms0 表示无节流passiveBooleantrue滚动事件是否为被动监听提升移动端性能immediateBooleanfalse是否在指令绑定时立即执行一次回调2. 回调函数参数(scrollPosition, event) { // scrollPosition: 滚动位置对象 { top, left, height, width, direction } // - top/left垂直/水平滚动距离px // - height/width滚动容器高度/宽度px // - direction滚动方向up/down/left/right // event原生滚动事件对象 }3. 指令修饰符修饰符作用示例.horizontal仅监听水平滚动v-scroll.horizontalhandler.vertical仅监听垂直滚动默认v-scroll.verticalhandler.once仅触发一次滚动回调v-scroll.oncehandler二、基础用法规则1. 最简用法监听视口垂直滚动!-- 监听视口滚动无节流 -- div v-scrollhandleScroll / script setup const handleScroll (scrollPos) { console.log(垂直滚动距离, scrollPos.top) console.log(滚动方向, scrollPos.direction) } /script2. 自定义滚动目标!-- 监听指定DOM元素的滚动 -- template div refscrollContainer classh-400 overflow-auto div classh-1000 v-scrollscrollConfig / /div /template script setup const scrollContainer ref(null) const scrollConfig { target: scrollContainer, // 监听指定容器 throttle: 100, // 100ms节流 handler: (scrollPos) { console.log(容器滚动距离, scrollPos.top) } } /script3. 仅监听水平滚动div v-scroll.horizontalhandleHorizontalScroll / script setup const handleHorizontalScroll (scrollPos) { console.log(水平滚动距离, scrollPos.left) } /script三、关键特性与注意事项1. 核心特性多目标支持可监听视口、任意 DOM 元素的滚动性能优化支持节流、被动监听减少高频回调开销滚动信息封装回调直接返回滚动位置、方向等结构化数据无需手动计算自动清理组件卸载时自动移除滚动监听避免内存泄漏。2. 注意事项滚动容器要求监听非视口元素时目标元素需设置overflow: auto/scroll且有固定高度 / 宽度节流配置高频滚动场景如滚动加载建议设置throttle: 100-300避免回调触发过频繁被动监听移动端建议保持passive: true防止滚动卡顿方向判断direction仅在滚动距离变化时更新静止时无方向值兼容性兼容所有现代浏览器无需 polyfill。四、高级配置规则1. 节流 立即执行div v-scrolladvancedConfig / script setup const advancedConfig { throttle: 200, immediate: true, // 绑定时立即执行一次 handler: (scrollPos) { // 初始化时执行一次后续滚动每200ms触发一次 } } /script2. 手动停止监听若需主动移除滚动监听可通过回调的event对象操作const handleScroll (scrollPos, event) { if (scrollPos.top 1000) { // 移除监听 event.target.removeEventListener(scroll, handleScroll) } }Quasar v-scroll-fire 指令核心用法总结v-scroll-fire 是 Quasar 专为滚动触发动作设计的指令基于 v-scroll 扩展核心功能是当元素滚动到指定位置时触发一次回调默认进入视口时触发且仅触发一次适用于滚动曝光、滚动加载、滚动动画触发等场景。一、核心配置API1. 指令值格式支持Function触发回调或Object配置对象核心参数如下配置项类型默认值说明handlerFunction-元素滚动到目标位置时的回调函数必传offsetNumber/String0触发偏移量- 数字像素值如100表示元素顶部距离视口顶部 100px 时触发- 字符串百分比如50%表示元素 50% 进入视口时触发directionStringvertical监听方向vertical垂直滚动/horizontal水平滚动onceBooleantrue是否仅触发一次默认开启关闭后每次滚动到位置都会触发2. 指令修饰符修饰符作用示例.horizontal切换为水平滚动监听v-scroll-fire.horizontalhandler.repeat允许重复触发覆盖once: falsev-scroll-fire.repeathandler3. 回调函数参数(element, position) { // element触发指令的DOM元素 // position滚动位置对象 { top, left, direction }同v-scroll }二、基础用法规则1. 最简用法元素进入视口触发!-- 元素进入视口时触发一次回调 -- div v-scroll-firehandleScrollFire classh-200 bg-grey-2 进入视口触发 /div script setup const handleScrollFire (el, pos) { console.log(元素进入视口, el) console.log(当前滚动位置, pos.top) // 执行曝光埋点/加载数据/动画触发等逻辑 } /script2. 自定义偏移量触发!-- 元素底部进入视口时触发offset设为元素高度 -- div reftargetEl v-scroll-fire{ handler: handleScrollFire, offset: 100% // 元素100%进入视口底部进入时触发 } classh-200 bg-grey-2 / !-- 或像素偏移元素顶部距离视口顶部200px时触发 -- div v-scroll-fire{ handler: handleScrollFire, offset: 200 } /3. 水平滚动触发!-- 水平滚动时元素进入视口触发 -- div v-scroll-fire.horizontalhandleHorizontalFire classw-200 h-100 bg-grey-2 / script setup const handleHorizontalFire (el, pos) { console.log(水平滚动触发左侧位置, pos.left) } /script4. 重复触发!-- 每次滚动到位置都触发需.repeat修饰符 -- div v-scroll-fire.repeathandleRepeatFire classh-200 bg-grey-2 / script setup const handleRepeatFire () { console.log(重复触发每次滚动到位置都会执行) } /script三、关键特性与注意事项1. 核心特性单次触发默认默认仅触发一次回调避免重复执行如曝光埋点无需重复上报偏移量灵活支持像素 / 百分比偏移精准控制触发时机自动解绑单次触发后自动移除滚动监听无性能开销依赖滚动容器默认监听视口滚动若元素在自定义滚动容器内需确保容器设置overflow: auto/scroll。2. 注意事项偏移量正负正值元素未完全进入视口时触发如offset: 100表示元素顶部还在视口上方 100px 时触发负值元素部分离开视口时触发如offset: -50表示元素顶部进入视口下方 50px 时触发百分比偏移基于元素自身尺寸如50%表示元素一半进入视口重复触发限制开启.repeat后每次滚动到目标位置都会触发需注意性能避免高频执行复杂逻辑动态元素若元素是动态渲染的如v-for生成指令会自动绑定无需额外处理与 v-intersection 区别v-scroll-fire基于滚动位置触发更轻量仅关注滚动到指定位置的单次 / 重复动作v-intersection基于元素交叉状态支持持续监听进入 / 离开视口功能更全面。四、适用场景滚动曝光埋点元素进入视口时上报曝光数据默认单次触发避免重复上报滚动加载动画元素进入视口时触发 CSS/JS 动画如渐入、滑入效果分段加载数据滚动到页面底部一定偏移量时加载下一页数据结合offset: 100%吸顶 / 吸底触发滚动到指定位置时触发吸顶组件显示 / 隐藏阅读进度标记水平滚动时元素进入视口标记阅读进度。Quasar v-touch-hold 指令核心用法总结v-touch-hold 是 Quasar 提供的触摸 / 鼠标长按触发指令支持监听元素的长按事件同时适配触摸和鼠标操作可自定义长按等待时间、操作灵敏度适用于长按删除、长按预览、长按触发菜单等场景。一、核心配置API1. 指令参数格式通过冒号分隔支持配置长按等待时间、触摸灵敏度、鼠标灵敏度参数顺序固定v-touch-hold:[等待时间]:[触摸灵敏度]:[鼠标灵敏度]回调函数参数位置类型默认值说明等待时间Number600触发长按所需的最小时间毫秒如2000表示长按 2 秒触发触摸灵敏度Number5触摸时允许的最大移动距离像素超过则中止长按鼠标灵敏度Number7鼠标点击时允许的最大移动距离像素超过则中止长按2. 指令修饰符修饰符作用示例.mouse启用鼠标事件监听默认仅支持触摸事件v-touch-hold.mousehandleHold.capture优先捕获事件内部元素调用stopPropagation仍会触发指令v-touch-hold.capturehandleHold.mouseCapture优先捕获鼠标事件v-touch-hold.mouse.mouseCapturehandleHold3. 回调函数参数(details) { // details长按事件详情对象 // - evt原生事件对象touchstart/mousedown // - touch布尔值是否为触摸事件触发 // - mouse布尔值是否为鼠标事件触发 // - position长按位置 { top: 距离顶部像素, left: 距离左侧像素 } // - duration实际长按时长毫秒 }二、基础用法规则1. 最简用法默认配置!-- 默认长按600ms触发仅支持触摸事件 -- div v-touch-holdhandleHold classp-4 bg-primary text-white 触摸长按600ms触发 /div script setup const handleHold (details) { console.log(长按触发位置, details.position) console.log(是否触摸触发, details.touch) } /script2. 自定义等待时间!-- 长按2秒2000ms触发 -- div v-touch-hold:2000handleLongHold classp-4 bg-purple text-white 长按2秒触发 /div3. 自定义灵敏度!-- 等待600ms 触摸灵敏度12px 鼠标灵敏度15px 启用鼠标监听 -- div v-touch-hold:600:12:15.mousehandleCustomSensitivity classp-4 bg-grey-2 触摸灵敏度12px鼠标灵敏度15px /div4. 禁用局部区域的长按通过stop阻止事件传播禁用元素内部指定区域的长按触发div v-touch-hold.mousehandleHold classp-4 bg-primary text-white 外部区域支持长按 !-- 内部区域禁用长按 -- div touchstart.stop mousedown.stop classmt-2 p-2 bg-white text-black 此区域禁用长按 /div /div三、关键特性与注意事项1. 核心特性跨端适配默认支持触摸事件启用.mouse修饰符后支持鼠标事件适配移动端和桌面端灵活配置可自定义长按时长、操作灵敏度适配不同业务场景如敏感操作需更长长按时间容错机制允许轻微移动基于灵敏度配置避免误触导致长按中止提升用户体验事件控制支持通过stopPropagation禁用局部区域长按或通过capture修饰符优先捕获事件。2. 注意事项修饰符响应式部分修饰符如.capture非响应式修改后需刷新组件 / 页面才能生效灵敏度理解灵敏度值越大允许的移动距离越大长按越容易触发值越小长按要求越严格需保持静止事件冲突若元素同时绑定touchstart/mousedown事件需避免与长按指令冲突可通过capture控制事件优先级性能优化避免在长按回调中执行复杂逻辑可通过防抖 / 节流优化如数据请求、DOM 操作。四、适用场景移动端长按操作如长按删除列表项、长按显示菜单桌面端鼠标长按触发如长按预览图片、长按拖拽敏感操作确认如长按提交表单、长按删除重要数据通过长按时长防止误操作自定义交互如长按显示详情弹窗、长按触发动画效果。Quasar v-touch-pan 指令核心用法总结v-touch-pan 是 Quasar 提供的触摸 / 鼠标平移拖拽滑动指令同时适配触摸事件和鼠标事件支持监听元素在任意方向的平移动作可用于实现拖拽、滑动控制、手势交互等功能无需依赖第三方手势库如 Hammer.js。一、核心配置API1. 指令值与回调参数指令值为平移动作触发的回调函数参数为包含平移详情的对象(details) { // details 核心属性 // - evt: 原生事件对象touchmove/mousemove // - touch/mouse: 布尔值标记是触摸/鼠标触发 // - position: 当前位置 { top: 距离顶部像素, left: 距离左侧像素 } // - direction: 平移方向up/right/down/left // - isFirst/isFinal: 布尔值是否为平移开始/结束的首次/末次回调 // - duration: 平移时长毫秒 // - distance: 累计平移绝对距离 { x: 水平像素, y: 垂直像素 } // - offset: 累计平移偏移量含方向x/y 可正负 // - delta: 本次回调与上次的偏移差 { x: 水平像素, y: 垂直像素 } }2. 核心修饰符13 个常用关键修饰符修饰符作用示例.mouse启用鼠标事件监听默认仅支持触摸事件v-touch-pan.mousehandlePan.prevent阻止页面滚动触摸设备上防止平移时页面滚动v-touch-pan.preventhandlePan.horizontal仅监听水平方向平移left/rightv-touch-pan.horizontalhandlePan.vertical仅监听垂直方向平移up/downv-touch-pan.verticalhandlePan.up/.down/.left/.right仅监听指定单个 / 多个方向v-touch-pan.up.righthandlePan仅上 / 右方向.capture事件捕获模式优先触发指令再触发内部元素事件v-touch-pan.capturehandlePan.mouseCapture鼠标事件捕获模式v-touch-pan.mouse.mouseCapturehandlePan二、基础用法规则1. 最简用法任意方向平移!-- 支持触摸鼠标平移阻止页面滚动 -- div v-touch-pan.prevent.mousehandlePan classw-400 h-400 bg-primary text-white 任意方向平移触摸/鼠标均可 /div script setup const handlePan (details) { console.log(平移方向, details.direction) console.log(累计水平偏移, details.offset.x) console.log(是否平移结束, details.isFinal) } /script2. 限制平移方向!-- 仅水平方向平移 -- div v-touch-pan.horizontal.prevent.mousehandleHorizontalPan classw-400 h-200 bg-grey-2 仅左右平移 /div !-- 仅上/右方向平移 -- div v-touch-pan.up.right.preventhandleCustomDirPan classw-400 h-200 bg-purple text-white 仅上/右平移 /div3. 禁用局部区域平移通过stop阻止事件传播禁用元素内部指定区域的平移触发div v-touch-pan.prevent.mousehandlePan classw-400 h-400 bg-primary text-white 外部支持平移 div touchstart.stop mousedown.stop classmt-4 p-4 bg-white text-black 此区域禁用平移 /div /div4. 拖拽元素示例核心实战实现元素跟随平移动作拖拽移动template div classrelative w-full h-600 div refdragEl v-touch-pan.prevent.mousemoveDragEl classabsolute w-20 h-20 bg-accent text-white flex items-center justify-center :style{ top: ${elTop}px, left: ${elLeft}px } 拖拽我 /div /div /template script setup import { ref } from vue const dragEl ref(null) const elTop ref(100) // 初始top位置 const elLeft ref(100) // 初始left位置 let startPos null // 平移开始时的元素位置 const moveDragEl (details) { if (details.isFirst) { // 记录平移开始时的元素位置 startPos { top: elTop.value, left: elLeft.value } } else if (!details.isFinal) { // 平移中更新元素位置初始位置 平移偏移量 elTop.value startPos.top details.offset.y elLeft.value startPos.left details.offset.x } } /script三、关键特性与注意事项1. 核心特性跨端适配默认支持触摸事件启用.mouse修饰符后支持鼠标拖拽适配移动端和桌面端方向精准控制支持任意 / 水平 / 垂直 / 自定义方向监听满足不同交互需求事件细节丰富回调提供平移方向、偏移量、时长等完整信息便于精准控制滚动冲突处理通过.prevent修饰符阻止页面滚动避免平移与滚动冲突灵活的事件控制支持捕获模式、局部禁用适配复杂 DOM 结构。2. 注意事项图像拖拽干扰若平移元素包含图片需给图片添加draggablefalse避免浏览器原生拖拽行为干扰修饰符响应式部分修饰符如.capture非响应式修改后需刷新组件 / 页面生效性能优化平移回调触发频率高避免在回调中执行复杂 DOM 操作可通过节流优化边界控制拖拽元素时需手动处理边界如防止元素超出容器指令不自带边界限制事件优先级若元素同时绑定touchmove/mousemove事件可通过.capture修饰符确保指令优先触发。四、适用场景拖拽交互如可拖动的悬浮按钮、拖拽排序、拖拽调整位置滑动控制如滑动切换图片、滑动调节音量 / 亮度手势操作如水平滑动删除列表项、垂直滑动刷新自定义组件交互如可拖拽的面板、拖拽调整大小的容器。Quasar v-touch-repeat 指令核心用法总结v-touch-repeat 是 Quasar 提供的触摸 / 鼠标长按重复触发指令核心功能是长按元素时持续触发回调区别于 v-touch-hold 的 “单次触发”支持自定义触发间隔、长按等待时间、操作灵敏度适配触摸和鼠标操作适用于长按连续操作如长按增减数量、长按滚动、长按删除等场景。一、核心配置API1. 指令参数格式通过冒号分隔参数顺序固定支持配置 “长按等待时间”“触发间隔时间”“触摸灵敏度”“鼠标灵敏度”v-touch-repeat:[长按等待时间]:[触发间隔时间]:[触摸灵敏度]:[鼠标灵敏度]回调函数参数位置类型默认值说明长按等待时间Number600首次触发回调前的等待时间毫秒即长按多久后开始持续触发触发间隔时间Number100连续触发回调的时间间隔毫秒值越小触发越频繁触摸灵敏度Number5触摸时允许的最大移动距离像素超过则中止长按重复触发鼠标灵敏度Number7鼠标点击时允许的最大移动距离像素超过则中止长按重复触发2. 指令修饰符修饰符作用示例.mouse启用鼠标事件监听默认仅支持触摸事件v-touch-repeat.mousehandleRepeat.capture事件捕获模式优先触发指令再触发内部元素事件v-touch-repeat.capturehandleRepeat.mouseCapture鼠标事件捕获模式v-touch-repeat.mouse.mouseCapturehandleRepeat.prevent阻止页面滚动触摸设备上避免长按重复时页面滚动v-touch-repeat.preventhandleRepeat3. 回调函数参数(details) { // details长按重复事件详情对象 // - evt原生事件对象touchstart/mousedown/touchmove/mousemove // - touch/mouse布尔值标记是触摸/鼠标触发 // - position当前触摸/鼠标位置 { top: 距离顶部像素, left: 距离左侧像素 } // - duration累计长按时长毫秒 // - count已触发回调的次数从1开始累加 // - isFirst布尔值是否为首次触发回调长按等待时间结束后第一次触发 }二、基础用法规则1. 最简用法默认配置!-- 默认长按600ms后开始每100ms触发一次仅支持触摸 -- div v-touch-repeathandleRepeat classp-4 bg-primary text-white 触摸长按持续触发 /div script setup const handleRepeat (details) { console.log(触发次数, details.count) console.log(累计时长, details.duration) // 执行连续操作如数量1、滚动偏移等 } /script2. 自定义等待时间与触发间隔!-- 长按300ms后开始每50ms触发一次触发更频繁启用鼠标支持 -- div v-touch-repeat:300:50.mousehandleFastRepeat classp-4 bg-purple text-white 鼠标/触摸长按快速连续触发 /div3. 结合业务场景长按增减数量template div classflex items-center gap-4 q-btn v-touch-repeat:200:80.mouse.prevent clickcount Math.max(0, count - 1) touch-repeat() count Math.max(0, count - 1) - /q-btn span{{ count }}/span q-btn v-touch-repeat:200:80.mouse.prevent clickcount 1 touch-repeat() count 1 /q-btn /div /template script setup import { ref } from vue const count ref(0) /script4. 禁用局部区域触发通过stop阻止事件传播禁用元素内部指定区域的长按重复触发div v-touch-repeat.mouse.preventhandleRepeat classp-4 bg-primary text-white 外部区域支持长按重复触发 div touchstart.stop mousedown.stop classmt-2 p-2 bg-white text-black 此区域禁用长按重复 /div /div三、关键特性与注意事项1. 核心特性持续触发区别与 v-touch-hold 不同该指令在长按等待时间后持续触发回调而非仅触发一次跨端适配默认支持触摸事件启用.mouse修饰符后适配桌面端鼠标长按灵活配置可自定义 “启动等待时间”避免误触和 “触发间隔”控制触发频率容错机制支持灵敏度配置允许轻微移动提升用户体验事件控制支持prevent阻止滚动冲突capture控制事件优先级。2. 注意事项参数顺序指令参数需严格遵循 “等待时间间隔时间触摸灵敏度鼠标灵敏度” 顺序缺省参数需保留冒号如仅自定义等待时间v-touch-repeat:500:::handleRepeat灵敏度配置灵敏度值越小长按要求越严格需保持静止值越大允许的移动范围越大避免误中止性能优化触发间隔过小时如50ms会导致回调高频执行避免在回调中执行复杂 DOM 操作或数据请求可通过节流辅助优化与 v-touch-hold 区分v-touch-repeat长按后持续触发如长按 “” 号连续加 1v-touch-hold长按后仅触发一次如长按弹出菜单修饰符响应式capture/mouseCapture等修饰符非响应式修改后需刷新组件 / 页面生效。四、适用场景数值连续调整如长按增减商品数量、音量 / 亮度调节连续滚动控制如长按滚动列表、长按滑动图片连续删除操作如长按连续删除列表项、清空内容连续触发动作如长按连续发送消息、连续生成内容。Quasar v-touch-swipe 指令核心用法总结v-touch-swipe 是 Quasar 提供的触摸 / 鼠标滑动指令专为 “快速滑动” 交互设计区别于 v-touch-pan 的 “平移拖拽”同时适配触摸和鼠标操作支持监听指定方向的滑动动作无需依赖第三方手势库适用于滑动切换、滑动删除、滑动刷新等场景。一、核心配置API1. 指令值与回调参数指令值为滑动动作触发的回调函数参数为包含滑动详情的对象(details) { // details 核心属性 // - evt: 原生事件对象touchmove/mousemove // - touch/mouse: 布尔值标记是触摸/鼠标触发 // - direction: 滑动方向up/right/down/left唯一值 // - duration: 滑动总时长毫秒快速滑动通常耗时较短 // - distance: 滑动绝对距离 { x: 水平像素, y: 垂直像素 } }2. 核心修饰符修饰符作用示例.mouse启用鼠标事件监听默认仅支持触摸事件鼠标需快速滑动触发v-touch-swipe.mousehandleSwipe.up/.down/.left/.right仅监听指定单个 / 多个方向的滑动v-touch-swipe.righthandleRightSwipe仅右滑、v-touch-swipe.up.lefthandleSwipe仅上滑 / 左滑.capture事件捕获模式优先触发指令再触发内部元素事件v-touch-swipe.capturehandleSwipe.mouseCapture鼠标事件捕获模式v-touch-swipe.mouse.mouseCapturehandleSwipe二、基础用法规则1. 最简用法任意方向滑动!-- 支持触摸鼠标任意方向滑动 -- div v-touch-swipe.mousehandleSwipe classw-400 h-400 bg-primary text-white 任意方向快速滑动触摸/鼠标均可 /div script setup const handleSwipe (details) { console.log(滑动方向, details.direction) console.log(滑动距离, details.distance.x, details.distance.y) // 执行滑动切换/删除等逻辑 } /script2. 限制滑动方向!-- 仅监听右滑 -- div v-touch-swipe.right.mousehandleRightSwipe classw-400 h-200 bg-grey-2 仅右滑触发 /div !-- 仅监听上滑/左滑 -- div v-touch-swipe.up.left.mousehandleCustomDirSwipe classw-400 h-200 bg-purple text-white 仅上滑/左滑触发 /div3. 禁用局部区域滑动通过stop阻止事件传播禁用元素内部指定区域的滑动触发div v-touch-swipe.mousehandleSwipe classw-400 h-400 bg-primary text-white 外部支持滑动 div touchstart.stop mousedown.stop classmt-4 p-4 bg-white text-black 此区域禁用滑动 /div /div三、关键特性与注意事项1. 核心特性滑动判定强调 “快速滑动”区别于 v-touch-pan 的 “缓慢平移”触发条件更侧重滑动速度跨端适配默认支持触摸滑动启用.mouse修饰符后适配桌面端鼠标快速滑动方向精准控制支持单个 / 多个方向过滤仅响应指定方向的滑动动作事件细节完整回调提供滑动方向、时长、距离等信息便于业务逻辑判断如滑动距离达标才触发切换无滚动冲突默认不主动阻止页面滚动需手动处理复杂场景的滚动冲突。2. 注意事项图像干扰滑动元素包含图片时需给图片添加draggablefalse避免浏览器原生拖拽行为干扰修饰符响应式capture/mouse/mouseCapture修饰符在 HMR 更新时不生效需刷新组件 / 页面与 v-touch-pan 区分v-touch-swipe针对 “快速滑动”触发一次回调适用于切换 / 删除等一次性动作v-touch-pan针对 “缓慢平移拖拽”持续触发回调适用于拖拽移动 / 实时控制鼠标触发条件鼠标需快速、连续滑动才能触发缓慢移动不会触发符合 “滑动” 交互直觉。四、适用场景滑动切换如图片轮播、页面切换、标签页切换滑动操作如列表项左滑删除、右滑收藏滑动刷新 / 加载如下拉刷新、上拉加载更多手势控制如滑动调节音量、滑动关闭弹窗。