[{"data":1,"prerenderedAt":585},["ShallowReactive",2],{"navigation_docs":3,"diagnostic-content-VUE0025":44},[4,8,12,16,20,24,28,32,36,40],{"title":5,"path":6,"stem":7},"CLI","\u002Fcli","1.cli",{"title":9,"path":10,"stem":11},"Nuxt","\u002Fnuxt","2.nuxt",{"title":13,"path":14,"stem":15},"Vue","\u002Fvue","3.vue",{"title":17,"path":18,"stem":19},"Vite","\u002Fvite","4.vite",{"title":21,"path":22,"stem":23},"Nitro","\u002Fnitro","5.nitro",{"title":25,"path":26,"stem":27},"TypeScript","\u002Ftypescript","6.typescript",{"title":29,"path":30,"stem":31},"shadcn","\u002Fshadcn","7.shadcn",{"title":33,"path":34,"stem":35},"Package","\u002Fpackage","8.package",{"title":37,"path":38,"stem":39},"Extending Doctor","\u002Fextending","9.extending",{"title":41,"path":42,"stem":43},"Pinia","\u002Fpinia","9.pinia",{"id":45,"title":46,"body":47,"category":53,"code":574,"description":575,"docsUrl":54,"extension":576,"fix":577,"framework":578,"meta":579,"navigation":580,"pack":56,"path":581,"ruleId":57,"rulePath":58,"seo":582,"severity":59,"source":60,"sourceUrl":61,"stem":583,"why":70,"__hash__":584},"diagnostics\u002Fdiagnostics\u002FVUE0025.md","VUE0025: Prefer VueUse event listener cleanup",{"type":48,"value":49,"toc":564},"minimark",[50,62,67,71,75,83,87,92,95,331,334,494,498,501,532,536,548,552,560],[51,52],"rule-metadata",{"category":53,"docsUrl":54,"fix":55,"pack":56,"ruleId":57,"rulePath":58,"severity":59,"source":60,"sourceUrl":61},"lifecycle","https:\u002F\u002Fvueuse.org\u002Fcore\u002Fuseeventlistener\u002F","suggestion","vite-doctor\u002Fvue","vue\u002Flifecycle\u002Fprefer-use-event-listener","\u002Fvue\u002Frules\u002Flifecycle\u002Fprefer-use-event-listener","warn","src\u002Frule-packs\u002Fvue\u002Frules\u002Fvue\u002Fprefer-use-event-listener.ts","https:\u002F\u002Fgithub.com\u002Fonmax\u002Fvite-doctor\u002Fblob\u002Fmain\u002Fsrc\u002Frule-packs\u002Fvue\u002Frules\u002Fvue\u002Fprefer-use-event-listener.ts",[63,64,66],"h2",{"id":65},"why-it-happens","Why it happens",[68,69,70],"p",{},"DOM listeners are lifecycle resources. Keeping setup and disposal behind a composable makes repeated watcher runs, component unmounts, and composable scope disposal harder to drift apart.",[63,72,74],{"id":73},"fix","Fix",[68,76,77,78,82],{},"Use VueUse ",[79,80,81],"code",{},"useEventListener()"," for DOM listeners. In watcher callbacks, keep the returned stop handle in watcher cleanup when each watcher run owns a fresh listener.",[63,84,86],{"id":85},"example","Example",[88,89,91],"h3",{"id":90},"use-vueuse-for-watcher-owned-listeners","Use VueUse for watcher-owned listeners",[68,93,94],{},"Before",[96,97,102],"pre",{"className":98,"code":99,"language":100,"meta":101,"style":101},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","watch(active, (_value, _oldValue, onCleanup) => {\n  const el = document.querySelector('.target')\n  if (!el) return\n  const onEnd = () => el.classList.remove('active')\n  el.addEventListener('animationend', onEnd, { once: true })\n  onCleanup(() => el.removeEventListener('animationend', onEnd))\n})\n","ts","",[79,103,104,148,185,206,244,288,323],{"__ignoreMap":101},[105,106,109,113,117,121,124,128,130,133,135,138,141,145],"span",{"class":107,"line":108},"line",1,[105,110,112],{"class":111},"s2Zo4","watch",[105,114,116],{"class":115},"sTEyZ","(active",[105,118,120],{"class":119},"sMK4o",",",[105,122,123],{"class":119}," (",[105,125,127],{"class":126},"sHdIc","_value",[105,129,120],{"class":119},[105,131,132],{"class":126}," _oldValue",[105,134,120],{"class":119},[105,136,137],{"class":126}," onCleanup",[105,139,140],{"class":119},")",[105,142,144],{"class":143},"spNyl"," =>",[105,146,147],{"class":119}," {\n",[105,149,151,154,157,160,163,166,169,173,176,180,182],{"class":107,"line":150},2,[105,152,153],{"class":143},"  const",[105,155,156],{"class":115}," el",[105,158,159],{"class":119}," =",[105,161,162],{"class":115}," document",[105,164,165],{"class":119},".",[105,167,168],{"class":111},"querySelector",[105,170,172],{"class":171},"swJcz","(",[105,174,175],{"class":119},"'",[105,177,179],{"class":178},"sfazB",".target",[105,181,175],{"class":119},[105,183,184],{"class":171},")\n",[105,186,188,192,194,197,200,203],{"class":107,"line":187},3,[105,189,191],{"class":190},"s7zQu","  if",[105,193,123],{"class":171},[105,195,196],{"class":119},"!",[105,198,199],{"class":115},"el",[105,201,202],{"class":171},") ",[105,204,205],{"class":190},"return\n",[105,207,209,211,214,216,219,221,223,225,228,230,233,235,237,240,242],{"class":107,"line":208},4,[105,210,153],{"class":143},[105,212,213],{"class":115}," onEnd",[105,215,159],{"class":119},[105,217,218],{"class":119}," ()",[105,220,144],{"class":143},[105,222,156],{"class":115},[105,224,165],{"class":119},[105,226,227],{"class":115},"classList",[105,229,165],{"class":119},[105,231,232],{"class":111},"remove",[105,234,172],{"class":171},[105,236,175],{"class":119},[105,238,239],{"class":178},"active",[105,241,175],{"class":119},[105,243,184],{"class":171},[105,245,247,250,252,255,257,259,262,264,266,268,270,273,276,279,283,286],{"class":107,"line":246},5,[105,248,249],{"class":115},"  el",[105,251,165],{"class":119},[105,253,254],{"class":111},"addEventListener",[105,256,172],{"class":171},[105,258,175],{"class":119},[105,260,261],{"class":178},"animationend",[105,263,175],{"class":119},[105,265,120],{"class":119},[105,267,213],{"class":115},[105,269,120],{"class":119},[105,271,272],{"class":119}," {",[105,274,275],{"class":171}," once",[105,277,278],{"class":119},":",[105,280,282],{"class":281},"sfNiH"," true",[105,284,285],{"class":119}," }",[105,287,184],{"class":171},[105,289,291,294,296,299,301,303,305,308,310,312,314,316,318,320],{"class":107,"line":290},6,[105,292,293],{"class":111},"  onCleanup",[105,295,172],{"class":171},[105,297,298],{"class":119},"()",[105,300,144],{"class":143},[105,302,156],{"class":115},[105,304,165],{"class":119},[105,306,307],{"class":111},"removeEventListener",[105,309,172],{"class":171},[105,311,175],{"class":119},[105,313,261],{"class":178},[105,315,175],{"class":119},[105,317,120],{"class":119},[105,319,213],{"class":115},[105,321,322],{"class":171},"))\n",[105,324,326,329],{"class":107,"line":325},7,[105,327,328],{"class":119},"}",[105,330,184],{"class":115},[68,332,333],{},"After",[96,335,337],{"className":98,"code":336,"language":100,"meta":101,"style":101},"watch(active, (_value, _oldValue, onCleanup) => {\n  const el = document.querySelector('.target')\n  if (!el) return\n  const stop = useEventListener(el, 'animationend', () => {\n    el.classList.remove('active')\n  }, { once: true })\n  onCleanup(stop)\n})\n",[79,338,339,365,389,403,436,459,476,487],{"__ignoreMap":101},[105,340,341,343,345,347,349,351,353,355,357,359,361,363],{"class":107,"line":108},[105,342,112],{"class":111},[105,344,116],{"class":115},[105,346,120],{"class":119},[105,348,123],{"class":119},[105,350,127],{"class":126},[105,352,120],{"class":119},[105,354,132],{"class":126},[105,356,120],{"class":119},[105,358,137],{"class":126},[105,360,140],{"class":119},[105,362,144],{"class":143},[105,364,147],{"class":119},[105,366,367,369,371,373,375,377,379,381,383,385,387],{"class":107,"line":150},[105,368,153],{"class":143},[105,370,156],{"class":115},[105,372,159],{"class":119},[105,374,162],{"class":115},[105,376,165],{"class":119},[105,378,168],{"class":111},[105,380,172],{"class":171},[105,382,175],{"class":119},[105,384,179],{"class":178},[105,386,175],{"class":119},[105,388,184],{"class":171},[105,390,391,393,395,397,399,401],{"class":107,"line":187},[105,392,191],{"class":190},[105,394,123],{"class":171},[105,396,196],{"class":119},[105,398,199],{"class":115},[105,400,202],{"class":171},[105,402,205],{"class":190},[105,404,405,407,410,412,415,417,419,421,424,426,428,430,432,434],{"class":107,"line":208},[105,406,153],{"class":143},[105,408,409],{"class":115}," stop",[105,411,159],{"class":119},[105,413,414],{"class":111}," useEventListener",[105,416,172],{"class":171},[105,418,199],{"class":115},[105,420,120],{"class":119},[105,422,423],{"class":119}," '",[105,425,261],{"class":178},[105,427,175],{"class":119},[105,429,120],{"class":119},[105,431,218],{"class":119},[105,433,144],{"class":143},[105,435,147],{"class":119},[105,437,438,441,443,445,447,449,451,453,455,457],{"class":107,"line":246},[105,439,440],{"class":115},"    el",[105,442,165],{"class":119},[105,444,227],{"class":115},[105,446,165],{"class":119},[105,448,232],{"class":111},[105,450,172],{"class":171},[105,452,175],{"class":119},[105,454,239],{"class":178},[105,456,175],{"class":119},[105,458,184],{"class":171},[105,460,461,464,466,468,470,472,474],{"class":107,"line":290},[105,462,463],{"class":119},"  },",[105,465,272],{"class":119},[105,467,275],{"class":171},[105,469,278],{"class":119},[105,471,282],{"class":281},[105,473,285],{"class":119},[105,475,184],{"class":171},[105,477,478,480,482,485],{"class":107,"line":325},[105,479,293],{"class":111},[105,481,172],{"class":171},[105,483,484],{"class":115},"stop",[105,486,184],{"class":171},[105,488,490,492],{"class":107,"line":489},8,[105,491,328],{"class":119},[105,493,184],{"class":115},[63,495,497],{"id":496},"verify-the-fix","Verify the fix",[68,499,500],{},"Run only this rule after editing so the report stays focused on the diagnostic you are closing:",[96,502,506],{"className":503,"code":504,"language":505,"meta":101,"style":101},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm vite-doctor . --framework vue --rules vue\u002Flifecycle\u002Fprefer-use-event-listener\n","bash",[79,507,508],{"__ignoreMap":101},[105,509,510,514,517,520,523,526,529],{"class":107,"line":108},[105,511,513],{"class":512},"sBMFI","pnpm",[105,515,516],{"class":178}," vite-doctor",[105,518,519],{"class":178}," .",[105,521,522],{"class":178}," --framework",[105,524,525],{"class":178}," vue",[105,527,528],{"class":178}," --rules",[105,530,531],{"class":178}," vue\u002Flifecycle\u002Fprefer-use-event-listener\n",[63,533,535],{"id":534},"useful-links","Useful links",[537,538,539],"ul",{},[540,541,542],"li",{},[543,544,547],"a",{"href":54,"rel":545},[546],"nofollow","Upstream docs",[63,549,551],{"id":550},"related-rule","Related rule",[537,553,554],{},[540,555,556],{},[543,557,558],{"href":58},[79,559,57],{},[561,562,563],"style",{},"html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":101,"searchDepth":150,"depth":150,"links":565},[566,567,568,571,572,573],{"id":65,"depth":150,"text":66},{"id":73,"depth":150,"text":74},{"id":85,"depth":150,"text":86,"children":569},[570],{"id":90,"depth":187,"text":91},{"id":496,"depth":150,"text":497},{"id":534,"depth":150,"text":535},{"id":550,"depth":150,"text":551},"VUE0025","Finds Vue scopes that manually pair DOM event listener setup and cleanup when VueUse is already available.","md","Use VueUse useEventListener() for DOM listeners. In watcher callbacks, keep the returned stop handle in watcher cleanup when each watcher run owns a fresh listener.","vue",{},true,"\u002Fdiagnostics\u002Fvue0025",{"title":46,"description":575},"diagnostics\u002FVUE0025","IKUaAOCgckzTizoAnI8VVF3G_fSqbJ1OXkZz6Cs8-SI",1791309482033]