[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f2q1b8fjxr88h5":3,"mdc-gsa4sf-key":23},{"_id":4,"title":5,"slug":6,"excerpt":7,"coverImage":8,"tags":9,"access":14,"publishedAt":15,"views":16,"likes":17,"seo":18,"readingTime":20,"locked":21,"body":22},"6ac40ee77ed2305c5a7a2505","VueUse: a must-have library for Vue 3","vueuse-a-must-have-library-for-vue-3","Four VueUse functions I keep coming back to: onClickOutside, useStorage with createGlobalState, and useRefHistory with undo and redo. Updated for VueUse 14 and Vue 3.5.","https:\u002F\u002Fres.cloudinary.com\u002Fdqjivljzi\u002Fimage\u002Fupload\u002Fv1791237372\u002Fdev-blog\u002F5c5813be-1884-4112-be20-b30f110b91c3.png",[10,11,12,13],"vue","typescript","webdev","javascript","free","2021-09-01T05:20:00.000Z",8,1,{"title":5,"description":19},"Four VueUse functions I keep coming back to: onClickOutside, useStorage with createGlobalState, and useRefHistory with undo and redo. Updated for VueUse 14 and",6,false,"### Updated in October 2026 — the [original version of this article](https:\u002F\u002Fdev.to\u002Fgarmideroman\u002Fvueuse-as-must-have-library-for-vue-3-5o2) was published on dev.to in September 2021\n\nIf you haven't tried [VueUse](https:\u002F\u002Fvueuse.org) yet, I recommend giving it a go. For Vue 3 projects it has become something close to a de facto standard, much like lodash once was for almost any JavaScript project.\n\nThe range of what it offers is impressive. There are small utilities, such as tracking mouse coordinates, and there are larger integrations: Axios, cookies, QR codes, Firebase, RxJS, the router, local storage, browser APIs, animation, geolocation, a media player, extensions for standard Vue reactivity, and much more. The library is actively maintained, receives regular releases and bug fixes, and has a large, growing community.\n\n> **Version note (2026):** the current major version is **VueUse 14**, which requires **Vue 3.5+**. VueUse 13 requires Vue 3.3+, and starting with v12 Vue 2 is no longer supported. If you are still on Vue 2, stay on `@vueuse\u002Fcore@11`.\n\nInstallation:\n\n```bash\nnpm i @vueuse\u002Fcore\n```\n\nIntegrations with third-party libraries (Axios, cookies, QR codes, etc.) live in the separate `@vueuse\u002Fintegrations` package, and Firebase, RxJS and router helpers have their own add-on packages. For Nuxt there is the `@vueuse\u002Fnuxt` module with auto-imports.\n\nIn this article I'll cover only four functions, but the rest of the library deserves your attention too.\n\n## onClickOutside — clicks outside an element\n\nLet's start with a simple warm-up: `onClickOutside`, which tracks clicks outside a given element. Plenty of packages provide this, and many of us have written it ourselves, usually as a custom directive like `v-click-outside`. VueUse offers it as a composable (and, if you prefer, also as the `vOnClickOutside` directive and the `\u003COnClickOutside>` component).\n\nI used it in the `TodoItem.vue` component of my todo app:\n\n```vue\n\u003Cscript setup lang=\"ts\">\nimport { ref, useTemplateRef } from 'vue'\nimport { onClickOutside } from '@vueuse\u002Fcore'\nimport type ToDo from '@\u002Fmodels\u002FToDoModel'\n\ndefineProps\u003C{ todo: ToDo }>()\n\nconst todoItem = useTemplateRef\u003CHTMLLIElement>('todoItem')\nconst editable = ref(false)\n\nonClickOutside(todoItem, () => {\n  editable.value = false\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cli ref=\"todoItem\">\n    \u003Cinput type=\"checkbox\" \u002F>\n    \u003Cspan v-if=\"!editable\" @click=\"editable = true\">\n      {{ todo.text || 'Click to edit Todo' }}\n    \u003C\u002Fspan>\n    \u003Cinput\n      v-else\n      type=\"text\"\n      :value=\"todo.text\"\n      @keyup.enter=\"editable = false\"\n    \u002F>\n  \u003C\u002Fli>\n\u003C\u002Ftemplate>\n```\n\nI've trimmed unrelated code. We get a reference to the `\u003Cli>` element via `useTemplateRef` (available since Vue 3.5; in older versions use `const todoItem = ref(null)`), then pass it as the first argument to `onClickOutside`. The second argument is the callback to run. Clicking the `span` turns it into an `input`; clicking anywhere outside the `li` turns the `input` back into a `span`.\n\n## useStorage and createGlobalState — reactive localStorage\n\nNext up is `useStorage`. It keeps data in `window.localStorage` (or another storage you pass in) and keeps it in sync reactively: data is saved, updated and removed automatically and survives page reloads. It works nicely together with `createGlobalState`, which creates state shared across the whole app:\n\n```ts\n\u002F\u002F @\u002Fstore\u002Fnotes.ts\nimport { createGlobalState, useStorage } from '@vueuse\u002Fcore'\nimport type Note from '@\u002Fmodels\u002FNoteModel'\n\n\u002F\u002F state\nexport const useGlobalNotes = createGlobalState(\n  () => useStorage\u003CNote[]>('my-notes', []),\n)\n\n\u002F\u002F actions\nconst notes = useGlobalNotes()\n\nexport function addNote(note: Note) {\n  notes.value.push(note)\n}\n\nexport function deleteGlobalNote(noteId: number) {\n  notes.value = notes.value.filter(note => note.id !== noteId)\n}\n```\n\nThe first argument of `useStorage` is the key under which the data is stored in `localStorage`; the second is the initial value. Objects and arrays are serialized to JSON automatically and watched deeply, so `notes.value.push(...)` is persisted without any extra code. If you only need `localStorage`, there is also the shorthand `useLocalStorage`.\n\n`createGlobalState` wraps the state factory so that every call returns the same instance. By calling `useGlobalNotes()` in any component (or right in this file, as above) you get the same reactive list of notes. In `\u003Cscript>` you work with it through `.value`; in templates refs are unwrapped automatically, so no `.value` is needed there.\n\nA couple of practical notes:\n\n- `createGlobalState` is great for small apps and simple shared state. For anything larger, the officially recommended store is [Pinia](https:\u002F\u002Fpinia.vuejs.org), and `useStorage`\u002F`useLocalStorage` can be used inside a Pinia store as well.\n- In Nuxt, `useStorage` is excluded from auto-imports to avoid a name clash with Nuxt's own utility, so import it explicitly from `@vueuse\u002Fcore`.\n\nFor comparison, check out the [`useStorage` example](https:\u002F\u002Fvueuse.org\u002Fcore\u002FuseStorage\u002F) in the official docs.\n\n## useRefHistory — change history with undo\u002Fredo\n\n`useRefHistory` records the history of a ref's changes and gives you undo\u002Fredo out of the box. I used it to add Undo and Redo buttons to the note editing page:\n\n```vue\n\u003C!-- Note.vue -->\n\u003Cscript setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { useRefHistory } from '@vueuse\u002Fcore'\nimport type ToDo from '@\u002Fmodels\u002FToDoModel'\n\nconst note = ref({\n  title: '',\n  todos: [] as ToDo[],\n})\n\nconst { undo, redo, canUndo, canRedo, clear } = useRefHistory(note, {\n  deep: true,\n})\n\nfunction updateTitle(title: string) {\n  note.value.title = title\n}\n\nfunction addNewTodo() {\n  note.value.todos.push({} as ToDo)\n}\n\nfunction onRemoveTodo(index: number) {\n  note.value.todos.splice(index, 1)\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003C!-- ... -->\n  \u003Cdiv>\n    \u003Cbutton type=\"button\" :disabled=\"!canUndo\" @click=\"undo()\">Undo\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\" :disabled=\"!canRedo\" @click=\"redo()\">Redo\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003C!-- ... -->\n\u003C\u002Ftemplate>\n```\n\nWe create a reactive `note` with `ref` and pass it to `useRefHistory`. The `deep: true` option is needed because we mutate nested properties of the object; with it, snapshots are also cloned, so each history entry is independent.\n\nFrom the returned object we take `undo`, `redo`, `canUndo`, `canRedo` and `clear`. `canUndo` and `canRedo` are bound to the buttons' `disabled` attributes, and `clear` resets the history, for example after the user finishes editing. The return value has more to offer: `history` (the list of snapshots), `commit`, `reset`, `pause`\u002F`resume` and others. You can also limit the number of stored entries with the `capacity` option.\n\nIf you'd rather decide yourself when a snapshot is taken, use `useManualRefHistory`: it works the same way, but saves to history only when you call `commit()`.\n\n## Conclusion\n\nI've covered only four functions from VueUse's large toolbox. To dig deeper, visit the [library's website](https:\u002F\u002Fvueuse.org): every function comes with an interactive demo, a description of its options and TypeScript types, and both the docs and the library itself are updated regularly.\n\nThe full code of the sandbox project where I tried out the library is available here: *[link to repository]*.\n\n## Thanks to readers of the first version\n\nMany thanks to everyone who commented on the [original article](https:\u002F\u002Fdev.to\u002Fgarmideroman\u002Fvueuse-as-must-have-library-for-vue-3-5o2) — your feedback shaped this update:\n\n- [wheat](https:\u002F\u002Fdev.to\u002Fwheatjs) from the VueUse team pointed me to the library's renderless components, which is why this version mentions `\u003COnClickOutside>` alongside the composable.\n- [Paweł Miczka](https:\u002F\u002Fdev.to\u002Fpawelmiczka) noted that thanks to tree-shaking you don't have to worry much about bundle size, and that still holds true today.\n- [eshimischi](https:\u002F\u002Fdev.to\u002Feshimischi) reminded us that the library's author, Anthony Fu, is a member of the Vue core team and the creator of many other useful projects, such as Vitesse.\n- [박종훈 (Jonghun Park)](https:\u002F\u002Fdev.to\u002Fjonghunbok) translated the article into Korean for the Korean FE Article newsletter.\n",{"data":24,"body":25},{},{"type":26,"children":27},"root",[28,48,63,68,106,111,144,165,170,177,214,227,836,906,912,941,1314,1356,1397,1402,1458,1477,1483,1494,2217,2252,2362,2382,2388,2401,2416,2422,2435,2493],{"type":29,"tag":30,"props":31,"children":33},"element","h3",{"id":32},"updated-in-october-2026-the-original-version-of-this-article-was-published-on-devto-in-september-2021",[34,37,46],{"type":35,"value":36},"text","Updated in October 2026 — the ",{"type":29,"tag":38,"props":39,"children":43},"a",{"href":40,"rel":41},"https:\u002F\u002Fdev.to\u002Fgarmideroman\u002Fvueuse-as-must-have-library-for-vue-3-5o2",[42],"nofollow",[44],{"type":35,"value":45},"original version of this article",{"type":35,"value":47}," was published on dev.to in September 2021",{"type":29,"tag":49,"props":50,"children":51},"p",{},[52,54,61],{"type":35,"value":53},"If you haven't tried ",{"type":29,"tag":38,"props":55,"children":58},{"href":56,"rel":57},"https:\u002F\u002Fvueuse.org",[42],[59],{"type":35,"value":60},"VueUse",{"type":35,"value":62}," yet, I recommend giving it a go. For Vue 3 projects it has become something close to a de facto standard, much like lodash once was for almost any JavaScript project.",{"type":29,"tag":49,"props":64,"children":65},{},[66],{"type":35,"value":67},"The range of what it offers is impressive. There are small utilities, such as tracking mouse coordinates, and there are larger integrations: Axios, cookies, QR codes, Firebase, RxJS, the router, local storage, browser APIs, animation, geolocation, a media player, extensions for standard Vue reactivity, and much more. The library is actively maintained, receives regular releases and bug fixes, and has a large, growing community.",{"type":29,"tag":69,"props":70,"children":71},"blockquote",{},[72],{"type":29,"tag":49,"props":73,"children":74},{},[75,81,83,88,90,95,97,104],{"type":29,"tag":76,"props":77,"children":78},"strong",{},[79],{"type":35,"value":80},"Version note (2026):",{"type":35,"value":82}," the current major version is ",{"type":29,"tag":76,"props":84,"children":85},{},[86],{"type":35,"value":87},"VueUse 14",{"type":35,"value":89},", which requires ",{"type":29,"tag":76,"props":91,"children":92},{},[93],{"type":35,"value":94},"Vue 3.5+",{"type":35,"value":96},". VueUse 13 requires Vue 3.3+, and starting with v12 Vue 2 is no longer supported. If you are still on Vue 2, stay on ",{"type":29,"tag":98,"props":99,"children":101},"code",{"className":100},[],[102],{"type":35,"value":103},"@vueuse\u002Fcore@11",{"type":35,"value":105},".",{"type":29,"tag":49,"props":107,"children":108},{},[109],{"type":35,"value":110},"Installation:",{"type":29,"tag":112,"props":113,"children":118},"pre",{"className":114,"code":115,"language":116,"meta":117,"style":117},"language-bash shiki shiki-themes github-dark","npm i @vueuse\u002Fcore\n","bash","",[119],{"type":29,"tag":98,"props":120,"children":121},{"__ignoreMap":117},[122],{"type":29,"tag":123,"props":124,"children":126},"span",{"class":125,"line":17},"line",[127,133,139],{"type":29,"tag":123,"props":128,"children":130},{"style":129},"--shiki-default:#B392F0",[131],{"type":35,"value":132},"npm",{"type":29,"tag":123,"props":134,"children":136},{"style":135},"--shiki-default:#9ECBFF",[137],{"type":35,"value":138}," i",{"type":29,"tag":123,"props":140,"children":141},{"style":135},[142],{"type":35,"value":143}," @vueuse\u002Fcore\n",{"type":29,"tag":49,"props":145,"children":146},{},[147,149,155,157,163],{"type":35,"value":148},"Integrations with third-party libraries (Axios, cookies, QR codes, etc.) live in the separate ",{"type":29,"tag":98,"props":150,"children":152},{"className":151},[],[153],{"type":35,"value":154},"@vueuse\u002Fintegrations",{"type":35,"value":156}," package, and Firebase, RxJS and router helpers have their own add-on packages. For Nuxt there is the ",{"type":29,"tag":98,"props":158,"children":160},{"className":159},[],[161],{"type":35,"value":162},"@vueuse\u002Fnuxt",{"type":35,"value":164}," module with auto-imports.",{"type":29,"tag":49,"props":166,"children":167},{},[168],{"type":35,"value":169},"In this article I'll cover only four functions, but the rest of the library deserves your attention too.",{"type":29,"tag":171,"props":172,"children":174},"h2",{"id":173},"onclickoutside-clicks-outside-an-element",[175],{"type":35,"value":176},"onClickOutside — clicks outside an element",{"type":29,"tag":49,"props":178,"children":179},{},[180,182,188,190,196,198,204,206,212],{"type":35,"value":181},"Let's start with a simple warm-up: ",{"type":29,"tag":98,"props":183,"children":185},{"className":184},[],[186],{"type":35,"value":187},"onClickOutside",{"type":35,"value":189},", which tracks clicks outside a given element. Plenty of packages provide this, and many of us have written it ourselves, usually as a custom directive like ",{"type":29,"tag":98,"props":191,"children":193},{"className":192},[],[194],{"type":35,"value":195},"v-click-outside",{"type":35,"value":197},". VueUse offers it as a composable (and, if you prefer, also as the ",{"type":29,"tag":98,"props":199,"children":201},{"className":200},[],[202],{"type":35,"value":203},"vOnClickOutside",{"type":35,"value":205}," directive and the ",{"type":29,"tag":98,"props":207,"children":209},{"className":208},[],[210],{"type":35,"value":211},"\u003COnClickOutside>",{"type":35,"value":213}," component).",{"type":29,"tag":49,"props":215,"children":216},{},[217,219,225],{"type":35,"value":218},"I used it in the ",{"type":29,"tag":98,"props":220,"children":222},{"className":221},[],[223],{"type":35,"value":224},"TodoItem.vue",{"type":35,"value":226}," component of my todo app:",{"type":29,"tag":112,"props":228,"children":231},{"className":229,"code":230,"language":10,"meta":117,"style":117},"language-vue shiki shiki-themes github-dark","\u003Cscript setup lang=\"ts\">\nimport { ref, useTemplateRef } from 'vue'\nimport { onClickOutside } from '@vueuse\u002Fcore'\nimport type ToDo from '@\u002Fmodels\u002FToDoModel'\n\ndefineProps\u003C{ todo: ToDo }>()\n\nconst todoItem = useTemplateRef\u003CHTMLLIElement>('todoItem')\nconst editable = ref(false)\n\nonClickOutside(todoItem, () => {\n  editable.value = false\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cli ref=\"todoItem\">\n    \u003Cinput type=\"checkbox\" \u002F>\n    \u003Cspan v-if=\"!editable\" @click=\"editable = true\">\n      {{ todo.text || 'Click to edit Todo' }}\n    \u003C\u002Fspan>\n    \u003Cinput\n      v-else\n      type=\"text\"\n      :value=\"todo.text\"\n      @keyup.enter=\"editable = false\"\n    \u002F>\n  \u003C\u002Fli>\n\u003C\u002Ftemplate>\n",[232],{"type":29,"tag":98,"props":233,"children":234},{"__ignoreMap":117},[235,275,300,322,349,359,393,401,449,485,493,516,534,543,560,568,585,616,648,692,701,718,731,740,758,776,794,803,820],{"type":29,"tag":123,"props":236,"children":237},{"class":125,"line":17},[238,244,250,255,260,265,270],{"type":29,"tag":123,"props":239,"children":241},{"style":240},"--shiki-default:#E1E4E8",[242],{"type":35,"value":243},"\u003C",{"type":29,"tag":123,"props":245,"children":247},{"style":246},"--shiki-default:#85E89D",[248],{"type":35,"value":249},"script",{"type":29,"tag":123,"props":251,"children":252},{"style":129},[253],{"type":35,"value":254}," setup",{"type":29,"tag":123,"props":256,"children":257},{"style":129},[258],{"type":35,"value":259}," lang",{"type":29,"tag":123,"props":261,"children":262},{"style":240},[263],{"type":35,"value":264},"=",{"type":29,"tag":123,"props":266,"children":267},{"style":135},[268],{"type":35,"value":269},"\"ts\"",{"type":29,"tag":123,"props":271,"children":272},{"style":240},[273],{"type":35,"value":274},">\n",{"type":29,"tag":123,"props":276,"children":278},{"class":125,"line":277},2,[279,285,290,295],{"type":29,"tag":123,"props":280,"children":282},{"style":281},"--shiki-default:#F97583",[283],{"type":35,"value":284},"import",{"type":29,"tag":123,"props":286,"children":287},{"style":240},[288],{"type":35,"value":289}," { ref, useTemplateRef } ",{"type":29,"tag":123,"props":291,"children":292},{"style":281},[293],{"type":35,"value":294},"from",{"type":29,"tag":123,"props":296,"children":297},{"style":135},[298],{"type":35,"value":299}," 'vue'\n",{"type":29,"tag":123,"props":301,"children":303},{"class":125,"line":302},3,[304,308,313,317],{"type":29,"tag":123,"props":305,"children":306},{"style":281},[307],{"type":35,"value":284},{"type":29,"tag":123,"props":309,"children":310},{"style":240},[311],{"type":35,"value":312}," { onClickOutside } ",{"type":29,"tag":123,"props":314,"children":315},{"style":281},[316],{"type":35,"value":294},{"type":29,"tag":123,"props":318,"children":319},{"style":135},[320],{"type":35,"value":321}," '@vueuse\u002Fcore'\n",{"type":29,"tag":123,"props":323,"children":325},{"class":125,"line":324},4,[326,330,335,340,344],{"type":29,"tag":123,"props":327,"children":328},{"style":281},[329],{"type":35,"value":284},{"type":29,"tag":123,"props":331,"children":332},{"style":281},[333],{"type":35,"value":334}," type",{"type":29,"tag":123,"props":336,"children":337},{"style":240},[338],{"type":35,"value":339}," ToDo ",{"type":29,"tag":123,"props":341,"children":342},{"style":281},[343],{"type":35,"value":294},{"type":29,"tag":123,"props":345,"children":346},{"style":135},[347],{"type":35,"value":348}," '@\u002Fmodels\u002FToDoModel'\n",{"type":29,"tag":123,"props":350,"children":352},{"class":125,"line":351},5,[353],{"type":29,"tag":123,"props":354,"children":356},{"emptyLinePlaceholder":355},true,[357],{"type":35,"value":358},"\n",{"type":29,"tag":123,"props":360,"children":361},{"class":125,"line":20},[362,367,372,378,383,388],{"type":29,"tag":123,"props":363,"children":364},{"style":129},[365],{"type":35,"value":366},"defineProps",{"type":29,"tag":123,"props":368,"children":369},{"style":240},[370],{"type":35,"value":371},"\u003C{ ",{"type":29,"tag":123,"props":373,"children":375},{"style":374},"--shiki-default:#FFAB70",[376],{"type":35,"value":377},"todo",{"type":29,"tag":123,"props":379,"children":380},{"style":281},[381],{"type":35,"value":382},":",{"type":29,"tag":123,"props":384,"children":385},{"style":129},[386],{"type":35,"value":387}," ToDo",{"type":29,"tag":123,"props":389,"children":390},{"style":240},[391],{"type":35,"value":392}," }>()\n",{"type":29,"tag":123,"props":394,"children":396},{"class":125,"line":395},7,[397],{"type":29,"tag":123,"props":398,"children":399},{"emptyLinePlaceholder":355},[400],{"type":35,"value":358},{"type":29,"tag":123,"props":402,"children":403},{"class":125,"line":16},[404,409,415,420,425,429,434,439,444],{"type":29,"tag":123,"props":405,"children":406},{"style":281},[407],{"type":35,"value":408},"const",{"type":29,"tag":123,"props":410,"children":412},{"style":411},"--shiki-default:#79B8FF",[413],{"type":35,"value":414}," todoItem",{"type":29,"tag":123,"props":416,"children":417},{"style":281},[418],{"type":35,"value":419}," =",{"type":29,"tag":123,"props":421,"children":422},{"style":129},[423],{"type":35,"value":424}," useTemplateRef",{"type":29,"tag":123,"props":426,"children":427},{"style":240},[428],{"type":35,"value":243},{"type":29,"tag":123,"props":430,"children":431},{"style":129},[432],{"type":35,"value":433},"HTMLLIElement",{"type":29,"tag":123,"props":435,"children":436},{"style":240},[437],{"type":35,"value":438},">(",{"type":29,"tag":123,"props":440,"children":441},{"style":135},[442],{"type":35,"value":443},"'todoItem'",{"type":29,"tag":123,"props":445,"children":446},{"style":240},[447],{"type":35,"value":448},")\n",{"type":29,"tag":123,"props":450,"children":452},{"class":125,"line":451},9,[453,457,462,466,471,476,481],{"type":29,"tag":123,"props":454,"children":455},{"style":281},[456],{"type":35,"value":408},{"type":29,"tag":123,"props":458,"children":459},{"style":411},[460],{"type":35,"value":461}," editable",{"type":29,"tag":123,"props":463,"children":464},{"style":281},[465],{"type":35,"value":419},{"type":29,"tag":123,"props":467,"children":468},{"style":129},[469],{"type":35,"value":470}," ref",{"type":29,"tag":123,"props":472,"children":473},{"style":240},[474],{"type":35,"value":475},"(",{"type":29,"tag":123,"props":477,"children":478},{"style":411},[479],{"type":35,"value":480},"false",{"type":29,"tag":123,"props":482,"children":483},{"style":240},[484],{"type":35,"value":448},{"type":29,"tag":123,"props":486,"children":488},{"class":125,"line":487},10,[489],{"type":29,"tag":123,"props":490,"children":491},{"emptyLinePlaceholder":355},[492],{"type":35,"value":358},{"type":29,"tag":123,"props":494,"children":496},{"class":125,"line":495},11,[497,501,506,511],{"type":29,"tag":123,"props":498,"children":499},{"style":129},[500],{"type":35,"value":187},{"type":29,"tag":123,"props":502,"children":503},{"style":240},[504],{"type":35,"value":505},"(todoItem, () ",{"type":29,"tag":123,"props":507,"children":508},{"style":281},[509],{"type":35,"value":510},"=>",{"type":29,"tag":123,"props":512,"children":513},{"style":240},[514],{"type":35,"value":515}," {\n",{"type":29,"tag":123,"props":517,"children":519},{"class":125,"line":518},12,[520,525,529],{"type":29,"tag":123,"props":521,"children":522},{"style":240},[523],{"type":35,"value":524},"  editable.value ",{"type":29,"tag":123,"props":526,"children":527},{"style":281},[528],{"type":35,"value":264},{"type":29,"tag":123,"props":530,"children":531},{"style":411},[532],{"type":35,"value":533}," false\n",{"type":29,"tag":123,"props":535,"children":537},{"class":125,"line":536},13,[538],{"type":29,"tag":123,"props":539,"children":540},{"style":240},[541],{"type":35,"value":542},"})\n",{"type":29,"tag":123,"props":544,"children":546},{"class":125,"line":545},14,[547,552,556],{"type":29,"tag":123,"props":548,"children":549},{"style":240},[550],{"type":35,"value":551},"\u003C\u002F",{"type":29,"tag":123,"props":553,"children":554},{"style":246},[555],{"type":35,"value":249},{"type":29,"tag":123,"props":557,"children":558},{"style":240},[559],{"type":35,"value":274},{"type":29,"tag":123,"props":561,"children":563},{"class":125,"line":562},15,[564],{"type":29,"tag":123,"props":565,"children":566},{"emptyLinePlaceholder":355},[567],{"type":35,"value":358},{"type":29,"tag":123,"props":569,"children":571},{"class":125,"line":570},16,[572,576,581],{"type":29,"tag":123,"props":573,"children":574},{"style":240},[575],{"type":35,"value":243},{"type":29,"tag":123,"props":577,"children":578},{"style":246},[579],{"type":35,"value":580},"template",{"type":29,"tag":123,"props":582,"children":583},{"style":240},[584],{"type":35,"value":274},{"type":29,"tag":123,"props":586,"children":588},{"class":125,"line":587},17,[589,594,599,603,607,612],{"type":29,"tag":123,"props":590,"children":591},{"style":240},[592],{"type":35,"value":593},"  \u003C",{"type":29,"tag":123,"props":595,"children":596},{"style":246},[597],{"type":35,"value":598},"li",{"type":29,"tag":123,"props":600,"children":601},{"style":129},[602],{"type":35,"value":470},{"type":29,"tag":123,"props":604,"children":605},{"style":240},[606],{"type":35,"value":264},{"type":29,"tag":123,"props":608,"children":609},{"style":135},[610],{"type":35,"value":611},"\"todoItem\"",{"type":29,"tag":123,"props":613,"children":614},{"style":240},[615],{"type":35,"value":274},{"type":29,"tag":123,"props":617,"children":619},{"class":125,"line":618},18,[620,625,630,634,638,643],{"type":29,"tag":123,"props":621,"children":622},{"style":240},[623],{"type":35,"value":624},"    \u003C",{"type":29,"tag":123,"props":626,"children":627},{"style":246},[628],{"type":35,"value":629},"input",{"type":29,"tag":123,"props":631,"children":632},{"style":129},[633],{"type":35,"value":334},{"type":29,"tag":123,"props":635,"children":636},{"style":240},[637],{"type":35,"value":264},{"type":29,"tag":123,"props":639,"children":640},{"style":135},[641],{"type":35,"value":642},"\"checkbox\"",{"type":29,"tag":123,"props":644,"children":645},{"style":240},[646],{"type":35,"value":647}," \u002F>\n",{"type":29,"tag":123,"props":649,"children":651},{"class":125,"line":650},19,[652,656,660,665,669,674,679,683,688],{"type":29,"tag":123,"props":653,"children":654},{"style":240},[655],{"type":35,"value":624},{"type":29,"tag":123,"props":657,"children":658},{"style":246},[659],{"type":35,"value":123},{"type":29,"tag":123,"props":661,"children":662},{"style":129},[663],{"type":35,"value":664}," v-if",{"type":29,"tag":123,"props":666,"children":667},{"style":240},[668],{"type":35,"value":264},{"type":29,"tag":123,"props":670,"children":671},{"style":135},[672],{"type":35,"value":673},"\"!editable\"",{"type":29,"tag":123,"props":675,"children":676},{"style":129},[677],{"type":35,"value":678}," @click",{"type":29,"tag":123,"props":680,"children":681},{"style":240},[682],{"type":35,"value":264},{"type":29,"tag":123,"props":684,"children":685},{"style":135},[686],{"type":35,"value":687},"\"editable = true\"",{"type":29,"tag":123,"props":689,"children":690},{"style":240},[691],{"type":35,"value":274},{"type":29,"tag":123,"props":693,"children":695},{"class":125,"line":694},20,[696],{"type":29,"tag":123,"props":697,"children":698},{"style":240},[699],{"type":35,"value":700},"      {{ todo.text || 'Click to edit Todo' }}\n",{"type":29,"tag":123,"props":702,"children":704},{"class":125,"line":703},21,[705,710,714],{"type":29,"tag":123,"props":706,"children":707},{"style":240},[708],{"type":35,"value":709},"    \u003C\u002F",{"type":29,"tag":123,"props":711,"children":712},{"style":246},[713],{"type":35,"value":123},{"type":29,"tag":123,"props":715,"children":716},{"style":240},[717],{"type":35,"value":274},{"type":29,"tag":123,"props":719,"children":721},{"class":125,"line":720},22,[722,726],{"type":29,"tag":123,"props":723,"children":724},{"style":240},[725],{"type":35,"value":624},{"type":29,"tag":123,"props":727,"children":728},{"style":246},[729],{"type":35,"value":730},"input\n",{"type":29,"tag":123,"props":732,"children":734},{"class":125,"line":733},23,[735],{"type":29,"tag":123,"props":736,"children":737},{"style":129},[738],{"type":35,"value":739},"      v-else\n",{"type":29,"tag":123,"props":741,"children":743},{"class":125,"line":742},24,[744,749,753],{"type":29,"tag":123,"props":745,"children":746},{"style":129},[747],{"type":35,"value":748},"      type",{"type":29,"tag":123,"props":750,"children":751},{"style":240},[752],{"type":35,"value":264},{"type":29,"tag":123,"props":754,"children":755},{"style":135},[756],{"type":35,"value":757},"\"text\"\n",{"type":29,"tag":123,"props":759,"children":761},{"class":125,"line":760},25,[762,767,771],{"type":29,"tag":123,"props":763,"children":764},{"style":129},[765],{"type":35,"value":766},"      :value",{"type":29,"tag":123,"props":768,"children":769},{"style":240},[770],{"type":35,"value":264},{"type":29,"tag":123,"props":772,"children":773},{"style":135},[774],{"type":35,"value":775},"\"todo.text\"\n",{"type":29,"tag":123,"props":777,"children":779},{"class":125,"line":778},26,[780,785,789],{"type":29,"tag":123,"props":781,"children":782},{"style":129},[783],{"type":35,"value":784},"      @keyup.enter",{"type":29,"tag":123,"props":786,"children":787},{"style":240},[788],{"type":35,"value":264},{"type":29,"tag":123,"props":790,"children":791},{"style":135},[792],{"type":35,"value":793},"\"editable = false\"\n",{"type":29,"tag":123,"props":795,"children":797},{"class":125,"line":796},27,[798],{"type":29,"tag":123,"props":799,"children":800},{"style":240},[801],{"type":35,"value":802},"    \u002F>\n",{"type":29,"tag":123,"props":804,"children":806},{"class":125,"line":805},28,[807,812,816],{"type":29,"tag":123,"props":808,"children":809},{"style":240},[810],{"type":35,"value":811},"  \u003C\u002F",{"type":29,"tag":123,"props":813,"children":814},{"style":246},[815],{"type":35,"value":598},{"type":29,"tag":123,"props":817,"children":818},{"style":240},[819],{"type":35,"value":274},{"type":29,"tag":123,"props":821,"children":823},{"class":125,"line":822},29,[824,828,832],{"type":29,"tag":123,"props":825,"children":826},{"style":240},[827],{"type":35,"value":551},{"type":29,"tag":123,"props":829,"children":830},{"style":246},[831],{"type":35,"value":580},{"type":29,"tag":123,"props":833,"children":834},{"style":240},[835],{"type":35,"value":274},{"type":29,"tag":49,"props":837,"children":838},{},[839,841,847,849,855,857,863,865,870,872,877,879,884,886,891,893,898,900,905],{"type":35,"value":840},"I've trimmed unrelated code. We get a reference to the ",{"type":29,"tag":98,"props":842,"children":844},{"className":843},[],[845],{"type":35,"value":846},"\u003Cli>",{"type":35,"value":848}," element via ",{"type":29,"tag":98,"props":850,"children":852},{"className":851},[],[853],{"type":35,"value":854},"useTemplateRef",{"type":35,"value":856}," (available since Vue 3.5; in older versions use ",{"type":29,"tag":98,"props":858,"children":860},{"className":859},[],[861],{"type":35,"value":862},"const todoItem = ref(null)",{"type":35,"value":864},"), then pass it as the first argument to ",{"type":29,"tag":98,"props":866,"children":868},{"className":867},[],[869],{"type":35,"value":187},{"type":35,"value":871},". The second argument is the callback to run. Clicking the ",{"type":29,"tag":98,"props":873,"children":875},{"className":874},[],[876],{"type":35,"value":123},{"type":35,"value":878}," turns it into an ",{"type":29,"tag":98,"props":880,"children":882},{"className":881},[],[883],{"type":35,"value":629},{"type":35,"value":885},"; clicking anywhere outside the ",{"type":29,"tag":98,"props":887,"children":889},{"className":888},[],[890],{"type":35,"value":598},{"type":35,"value":892}," turns the ",{"type":29,"tag":98,"props":894,"children":896},{"className":895},[],[897],{"type":35,"value":629},{"type":35,"value":899}," back into a ",{"type":29,"tag":98,"props":901,"children":903},{"className":902},[],[904],{"type":35,"value":123},{"type":35,"value":105},{"type":29,"tag":171,"props":907,"children":909},{"id":908},"usestorage-and-createglobalstate-reactive-localstorage",[910],{"type":35,"value":911},"useStorage and createGlobalState — reactive localStorage",{"type":29,"tag":49,"props":913,"children":914},{},[915,917,923,925,931,933,939],{"type":35,"value":916},"Next up is ",{"type":29,"tag":98,"props":918,"children":920},{"className":919},[],[921],{"type":35,"value":922},"useStorage",{"type":35,"value":924},". It keeps data in ",{"type":29,"tag":98,"props":926,"children":928},{"className":927},[],[929],{"type":35,"value":930},"window.localStorage",{"type":35,"value":932}," (or another storage you pass in) and keeps it in sync reactively: data is saved, updated and removed automatically and survives page reloads. It works nicely together with ",{"type":29,"tag":98,"props":934,"children":936},{"className":935},[],[937],{"type":35,"value":938},"createGlobalState",{"type":35,"value":940},", which creates state shared across the whole app:",{"type":29,"tag":112,"props":942,"children":946},{"className":943,"code":944,"language":945,"meta":117,"style":117},"language-ts shiki shiki-themes github-dark","\u002F\u002F @\u002Fstore\u002Fnotes.ts\nimport { createGlobalState, useStorage } from '@vueuse\u002Fcore'\nimport type Note from '@\u002Fmodels\u002FNoteModel'\n\n\u002F\u002F state\nexport const useGlobalNotes = createGlobalState(\n  () => useStorage\u003CNote[]>('my-notes', []),\n)\n\n\u002F\u002F actions\nconst notes = useGlobalNotes()\n\nexport function addNote(note: Note) {\n  notes.value.push(note)\n}\n\nexport function deleteGlobalNote(noteId: number) {\n  notes.value = notes.value.filter(note => note.id !== noteId)\n}\n","ts",[947],{"type":29,"tag":98,"props":948,"children":949},{"__ignoreMap":117},[950,959,979,1004,1011,1019,1051,1092,1099,1106,1114,1139,1146,1186,1204,1212,1219,1257,1307],{"type":29,"tag":123,"props":951,"children":952},{"class":125,"line":17},[953],{"type":29,"tag":123,"props":954,"children":956},{"style":955},"--shiki-default:#6A737D",[957],{"type":35,"value":958},"\u002F\u002F @\u002Fstore\u002Fnotes.ts\n",{"type":29,"tag":123,"props":960,"children":961},{"class":125,"line":277},[962,966,971,975],{"type":29,"tag":123,"props":963,"children":964},{"style":281},[965],{"type":35,"value":284},{"type":29,"tag":123,"props":967,"children":968},{"style":240},[969],{"type":35,"value":970}," { createGlobalState, useStorage } ",{"type":29,"tag":123,"props":972,"children":973},{"style":281},[974],{"type":35,"value":294},{"type":29,"tag":123,"props":976,"children":977},{"style":135},[978],{"type":35,"value":321},{"type":29,"tag":123,"props":980,"children":981},{"class":125,"line":302},[982,986,990,995,999],{"type":29,"tag":123,"props":983,"children":984},{"style":281},[985],{"type":35,"value":284},{"type":29,"tag":123,"props":987,"children":988},{"style":281},[989],{"type":35,"value":334},{"type":29,"tag":123,"props":991,"children":992},{"style":240},[993],{"type":35,"value":994}," Note ",{"type":29,"tag":123,"props":996,"children":997},{"style":281},[998],{"type":35,"value":294},{"type":29,"tag":123,"props":1000,"children":1001},{"style":135},[1002],{"type":35,"value":1003}," '@\u002Fmodels\u002FNoteModel'\n",{"type":29,"tag":123,"props":1005,"children":1006},{"class":125,"line":324},[1007],{"type":29,"tag":123,"props":1008,"children":1009},{"emptyLinePlaceholder":355},[1010],{"type":35,"value":358},{"type":29,"tag":123,"props":1012,"children":1013},{"class":125,"line":351},[1014],{"type":29,"tag":123,"props":1015,"children":1016},{"style":955},[1017],{"type":35,"value":1018},"\u002F\u002F state\n",{"type":29,"tag":123,"props":1020,"children":1021},{"class":125,"line":20},[1022,1027,1032,1037,1041,1046],{"type":29,"tag":123,"props":1023,"children":1024},{"style":281},[1025],{"type":35,"value":1026},"export",{"type":29,"tag":123,"props":1028,"children":1029},{"style":281},[1030],{"type":35,"value":1031}," const",{"type":29,"tag":123,"props":1033,"children":1034},{"style":411},[1035],{"type":35,"value":1036}," useGlobalNotes",{"type":29,"tag":123,"props":1038,"children":1039},{"style":281},[1040],{"type":35,"value":419},{"type":29,"tag":123,"props":1042,"children":1043},{"style":129},[1044],{"type":35,"value":1045}," createGlobalState",{"type":29,"tag":123,"props":1047,"children":1048},{"style":240},[1049],{"type":35,"value":1050},"(\n",{"type":29,"tag":123,"props":1052,"children":1053},{"class":125,"line":395},[1054,1059,1063,1068,1072,1077,1082,1087],{"type":29,"tag":123,"props":1055,"children":1056},{"style":240},[1057],{"type":35,"value":1058},"  () ",{"type":29,"tag":123,"props":1060,"children":1061},{"style":281},[1062],{"type":35,"value":510},{"type":29,"tag":123,"props":1064,"children":1065},{"style":129},[1066],{"type":35,"value":1067}," useStorage",{"type":29,"tag":123,"props":1069,"children":1070},{"style":240},[1071],{"type":35,"value":243},{"type":29,"tag":123,"props":1073,"children":1074},{"style":129},[1075],{"type":35,"value":1076},"Note",{"type":29,"tag":123,"props":1078,"children":1079},{"style":240},[1080],{"type":35,"value":1081},"[]>(",{"type":29,"tag":123,"props":1083,"children":1084},{"style":135},[1085],{"type":35,"value":1086},"'my-notes'",{"type":29,"tag":123,"props":1088,"children":1089},{"style":240},[1090],{"type":35,"value":1091},", []),\n",{"type":29,"tag":123,"props":1093,"children":1094},{"class":125,"line":16},[1095],{"type":29,"tag":123,"props":1096,"children":1097},{"style":240},[1098],{"type":35,"value":448},{"type":29,"tag":123,"props":1100,"children":1101},{"class":125,"line":451},[1102],{"type":29,"tag":123,"props":1103,"children":1104},{"emptyLinePlaceholder":355},[1105],{"type":35,"value":358},{"type":29,"tag":123,"props":1107,"children":1108},{"class":125,"line":487},[1109],{"type":29,"tag":123,"props":1110,"children":1111},{"style":955},[1112],{"type":35,"value":1113},"\u002F\u002F actions\n",{"type":29,"tag":123,"props":1115,"children":1116},{"class":125,"line":495},[1117,1121,1126,1130,1134],{"type":29,"tag":123,"props":1118,"children":1119},{"style":281},[1120],{"type":35,"value":408},{"type":29,"tag":123,"props":1122,"children":1123},{"style":411},[1124],{"type":35,"value":1125}," notes",{"type":29,"tag":123,"props":1127,"children":1128},{"style":281},[1129],{"type":35,"value":419},{"type":29,"tag":123,"props":1131,"children":1132},{"style":129},[1133],{"type":35,"value":1036},{"type":29,"tag":123,"props":1135,"children":1136},{"style":240},[1137],{"type":35,"value":1138},"()\n",{"type":29,"tag":123,"props":1140,"children":1141},{"class":125,"line":518},[1142],{"type":29,"tag":123,"props":1143,"children":1144},{"emptyLinePlaceholder":355},[1145],{"type":35,"value":358},{"type":29,"tag":123,"props":1147,"children":1148},{"class":125,"line":536},[1149,1153,1158,1163,1167,1172,1176,1181],{"type":29,"tag":123,"props":1150,"children":1151},{"style":281},[1152],{"type":35,"value":1026},{"type":29,"tag":123,"props":1154,"children":1155},{"style":281},[1156],{"type":35,"value":1157}," function",{"type":29,"tag":123,"props":1159,"children":1160},{"style":129},[1161],{"type":35,"value":1162}," addNote",{"type":29,"tag":123,"props":1164,"children":1165},{"style":240},[1166],{"type":35,"value":475},{"type":29,"tag":123,"props":1168,"children":1169},{"style":374},[1170],{"type":35,"value":1171},"note",{"type":29,"tag":123,"props":1173,"children":1174},{"style":281},[1175],{"type":35,"value":382},{"type":29,"tag":123,"props":1177,"children":1178},{"style":129},[1179],{"type":35,"value":1180}," Note",{"type":29,"tag":123,"props":1182,"children":1183},{"style":240},[1184],{"type":35,"value":1185},") {\n",{"type":29,"tag":123,"props":1187,"children":1188},{"class":125,"line":545},[1189,1194,1199],{"type":29,"tag":123,"props":1190,"children":1191},{"style":240},[1192],{"type":35,"value":1193},"  notes.value.",{"type":29,"tag":123,"props":1195,"children":1196},{"style":129},[1197],{"type":35,"value":1198},"push",{"type":29,"tag":123,"props":1200,"children":1201},{"style":240},[1202],{"type":35,"value":1203},"(note)\n",{"type":29,"tag":123,"props":1205,"children":1206},{"class":125,"line":562},[1207],{"type":29,"tag":123,"props":1208,"children":1209},{"style":240},[1210],{"type":35,"value":1211},"}\n",{"type":29,"tag":123,"props":1213,"children":1214},{"class":125,"line":570},[1215],{"type":29,"tag":123,"props":1216,"children":1217},{"emptyLinePlaceholder":355},[1218],{"type":35,"value":358},{"type":29,"tag":123,"props":1220,"children":1221},{"class":125,"line":587},[1222,1226,1230,1235,1239,1244,1248,1253],{"type":29,"tag":123,"props":1223,"children":1224},{"style":281},[1225],{"type":35,"value":1026},{"type":29,"tag":123,"props":1227,"children":1228},{"style":281},[1229],{"type":35,"value":1157},{"type":29,"tag":123,"props":1231,"children":1232},{"style":129},[1233],{"type":35,"value":1234}," deleteGlobalNote",{"type":29,"tag":123,"props":1236,"children":1237},{"style":240},[1238],{"type":35,"value":475},{"type":29,"tag":123,"props":1240,"children":1241},{"style":374},[1242],{"type":35,"value":1243},"noteId",{"type":29,"tag":123,"props":1245,"children":1246},{"style":281},[1247],{"type":35,"value":382},{"type":29,"tag":123,"props":1249,"children":1250},{"style":411},[1251],{"type":35,"value":1252}," number",{"type":29,"tag":123,"props":1254,"children":1255},{"style":240},[1256],{"type":35,"value":1185},{"type":29,"tag":123,"props":1258,"children":1259},{"class":125,"line":618},[1260,1265,1269,1274,1279,1283,1287,1292,1297,1302],{"type":29,"tag":123,"props":1261,"children":1262},{"style":240},[1263],{"type":35,"value":1264},"  notes.value ",{"type":29,"tag":123,"props":1266,"children":1267},{"style":281},[1268],{"type":35,"value":264},{"type":29,"tag":123,"props":1270,"children":1271},{"style":240},[1272],{"type":35,"value":1273}," notes.value.",{"type":29,"tag":123,"props":1275,"children":1276},{"style":129},[1277],{"type":35,"value":1278},"filter",{"type":29,"tag":123,"props":1280,"children":1281},{"style":240},[1282],{"type":35,"value":475},{"type":29,"tag":123,"props":1284,"children":1285},{"style":374},[1286],{"type":35,"value":1171},{"type":29,"tag":123,"props":1288,"children":1289},{"style":281},[1290],{"type":35,"value":1291}," =>",{"type":29,"tag":123,"props":1293,"children":1294},{"style":240},[1295],{"type":35,"value":1296}," note.id ",{"type":29,"tag":123,"props":1298,"children":1299},{"style":281},[1300],{"type":35,"value":1301},"!==",{"type":29,"tag":123,"props":1303,"children":1304},{"style":240},[1305],{"type":35,"value":1306}," noteId)\n",{"type":29,"tag":123,"props":1308,"children":1309},{"class":125,"line":650},[1310],{"type":29,"tag":123,"props":1311,"children":1312},{"style":240},[1313],{"type":35,"value":1211},{"type":29,"tag":49,"props":1315,"children":1316},{},[1317,1319,1324,1326,1332,1334,1340,1342,1347,1349,1355],{"type":35,"value":1318},"The first argument of ",{"type":29,"tag":98,"props":1320,"children":1322},{"className":1321},[],[1323],{"type":35,"value":922},{"type":35,"value":1325}," is the key under which the data is stored in ",{"type":29,"tag":98,"props":1327,"children":1329},{"className":1328},[],[1330],{"type":35,"value":1331},"localStorage",{"type":35,"value":1333},"; the second is the initial value. Objects and arrays are serialized to JSON automatically and watched deeply, so ",{"type":29,"tag":98,"props":1335,"children":1337},{"className":1336},[],[1338],{"type":35,"value":1339},"notes.value.push(...)",{"type":35,"value":1341}," is persisted without any extra code. If you only need ",{"type":29,"tag":98,"props":1343,"children":1345},{"className":1344},[],[1346],{"type":35,"value":1331},{"type":35,"value":1348},", there is also the shorthand ",{"type":29,"tag":98,"props":1350,"children":1352},{"className":1351},[],[1353],{"type":35,"value":1354},"useLocalStorage",{"type":35,"value":105},{"type":29,"tag":49,"props":1357,"children":1358},{},[1359,1364,1366,1372,1374,1380,1382,1388,1390,1395],{"type":29,"tag":98,"props":1360,"children":1362},{"className":1361},[],[1363],{"type":35,"value":938},{"type":35,"value":1365}," wraps the state factory so that every call returns the same instance. By calling ",{"type":29,"tag":98,"props":1367,"children":1369},{"className":1368},[],[1370],{"type":35,"value":1371},"useGlobalNotes()",{"type":35,"value":1373}," in any component (or right in this file, as above) you get the same reactive list of notes. In ",{"type":29,"tag":98,"props":1375,"children":1377},{"className":1376},[],[1378],{"type":35,"value":1379},"\u003Cscript>",{"type":35,"value":1381}," you work with it through ",{"type":29,"tag":98,"props":1383,"children":1385},{"className":1384},[],[1386],{"type":35,"value":1387},".value",{"type":35,"value":1389},"; in templates refs are unwrapped automatically, so no ",{"type":29,"tag":98,"props":1391,"children":1393},{"className":1392},[],[1394],{"type":35,"value":1387},{"type":35,"value":1396}," is needed there.",{"type":29,"tag":49,"props":1398,"children":1399},{},[1400],{"type":35,"value":1401},"A couple of practical notes:",{"type":29,"tag":1403,"props":1404,"children":1405},"ul",{},[1406,1439],{"type":29,"tag":598,"props":1407,"children":1408},{},[1409,1414,1416,1423,1425,1430,1432,1437],{"type":29,"tag":98,"props":1410,"children":1412},{"className":1411},[],[1413],{"type":35,"value":938},{"type":35,"value":1415}," is great for small apps and simple shared state. For anything larger, the officially recommended store is ",{"type":29,"tag":38,"props":1417,"children":1420},{"href":1418,"rel":1419},"https:\u002F\u002Fpinia.vuejs.org",[42],[1421],{"type":35,"value":1422},"Pinia",{"type":35,"value":1424},", and ",{"type":29,"tag":98,"props":1426,"children":1428},{"className":1427},[],[1429],{"type":35,"value":922},{"type":35,"value":1431},"\u002F",{"type":29,"tag":98,"props":1433,"children":1435},{"className":1434},[],[1436],{"type":35,"value":1354},{"type":35,"value":1438}," can be used inside a Pinia store as well.",{"type":29,"tag":598,"props":1440,"children":1441},{},[1442,1444,1449,1451,1457],{"type":35,"value":1443},"In Nuxt, ",{"type":29,"tag":98,"props":1445,"children":1447},{"className":1446},[],[1448],{"type":35,"value":922},{"type":35,"value":1450}," is excluded from auto-imports to avoid a name clash with Nuxt's own utility, so import it explicitly from ",{"type":29,"tag":98,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":35,"value":1456},"@vueuse\u002Fcore",{"type":35,"value":105},{"type":29,"tag":49,"props":1459,"children":1460},{},[1461,1463,1475],{"type":35,"value":1462},"For comparison, check out the ",{"type":29,"tag":38,"props":1464,"children":1467},{"href":1465,"rel":1466},"https:\u002F\u002Fvueuse.org\u002Fcore\u002FuseStorage\u002F",[42],[1468,1473],{"type":29,"tag":98,"props":1469,"children":1471},{"className":1470},[],[1472],{"type":35,"value":922},{"type":35,"value":1474}," example",{"type":35,"value":1476}," in the official docs.",{"type":29,"tag":171,"props":1478,"children":1480},{"id":1479},"userefhistory-change-history-with-undoredo",[1481],{"type":35,"value":1482},"useRefHistory — change history with undo\u002Fredo",{"type":29,"tag":49,"props":1484,"children":1485},{},[1486,1492],{"type":29,"tag":98,"props":1487,"children":1489},{"className":1488},[],[1490],{"type":35,"value":1491},"useRefHistory",{"type":35,"value":1493}," records the history of a ref's changes and gives you undo\u002Fredo out of the box. I used it to add Undo and Redo buttons to the note editing page:",{"type":29,"tag":112,"props":1495,"children":1497},{"className":229,"code":1496,"language":10,"meta":117,"style":117},"\u003C!-- Note.vue -->\n\u003Cscript setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { useRefHistory } from '@vueuse\u002Fcore'\nimport type ToDo from '@\u002Fmodels\u002FToDoModel'\n\nconst note = ref({\n  title: '',\n  todos: [] as ToDo[],\n})\n\nconst { undo, redo, canUndo, canRedo, clear } = useRefHistory(note, {\n  deep: true,\n})\n\nfunction updateTitle(title: string) {\n  note.value.title = title\n}\n\nfunction addNewTodo() {\n  note.value.todos.push({} as ToDo)\n}\n\nfunction onRemoveTodo(index: number) {\n  note.value.todos.splice(index, 1)\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003C!-- ... -->\n  \u003Cdiv>\n    \u003Cbutton type=\"button\" :disabled=\"!canUndo\" @click=\"undo()\">Undo\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\" :disabled=\"!canRedo\" @click=\"redo()\">Redo\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003C!-- ... -->\n\u003C\u002Ftemplate>\n",[1498],{"type":29,"tag":98,"props":1499,"children":1500},{"__ignoreMap":117},[1501,1509,1540,1560,1580,1603,1610,1635,1653,1675,1682,1689,1762,1779,1786,1793,1828,1845,1852,1859,1876,1905,1912,1919,1952,1978,1985,2000,2007,2022,2031,2048,2114,2177,2193,2201],{"type":29,"tag":123,"props":1502,"children":1503},{"class":125,"line":17},[1504],{"type":29,"tag":123,"props":1505,"children":1506},{"style":955},[1507],{"type":35,"value":1508},"\u003C!-- Note.vue -->\n",{"type":29,"tag":123,"props":1510,"children":1511},{"class":125,"line":277},[1512,1516,1520,1524,1528,1532,1536],{"type":29,"tag":123,"props":1513,"children":1514},{"style":240},[1515],{"type":35,"value":243},{"type":29,"tag":123,"props":1517,"children":1518},{"style":246},[1519],{"type":35,"value":249},{"type":29,"tag":123,"props":1521,"children":1522},{"style":129},[1523],{"type":35,"value":254},{"type":29,"tag":123,"props":1525,"children":1526},{"style":129},[1527],{"type":35,"value":259},{"type":29,"tag":123,"props":1529,"children":1530},{"style":240},[1531],{"type":35,"value":264},{"type":29,"tag":123,"props":1533,"children":1534},{"style":135},[1535],{"type":35,"value":269},{"type":29,"tag":123,"props":1537,"children":1538},{"style":240},[1539],{"type":35,"value":274},{"type":29,"tag":123,"props":1541,"children":1542},{"class":125,"line":302},[1543,1547,1552,1556],{"type":29,"tag":123,"props":1544,"children":1545},{"style":281},[1546],{"type":35,"value":284},{"type":29,"tag":123,"props":1548,"children":1549},{"style":240},[1550],{"type":35,"value":1551}," { ref } ",{"type":29,"tag":123,"props":1553,"children":1554},{"style":281},[1555],{"type":35,"value":294},{"type":29,"tag":123,"props":1557,"children":1558},{"style":135},[1559],{"type":35,"value":299},{"type":29,"tag":123,"props":1561,"children":1562},{"class":125,"line":324},[1563,1567,1572,1576],{"type":29,"tag":123,"props":1564,"children":1565},{"style":281},[1566],{"type":35,"value":284},{"type":29,"tag":123,"props":1568,"children":1569},{"style":240},[1570],{"type":35,"value":1571}," { useRefHistory } ",{"type":29,"tag":123,"props":1573,"children":1574},{"style":281},[1575],{"type":35,"value":294},{"type":29,"tag":123,"props":1577,"children":1578},{"style":135},[1579],{"type":35,"value":321},{"type":29,"tag":123,"props":1581,"children":1582},{"class":125,"line":351},[1583,1587,1591,1595,1599],{"type":29,"tag":123,"props":1584,"children":1585},{"style":281},[1586],{"type":35,"value":284},{"type":29,"tag":123,"props":1588,"children":1589},{"style":281},[1590],{"type":35,"value":334},{"type":29,"tag":123,"props":1592,"children":1593},{"style":240},[1594],{"type":35,"value":339},{"type":29,"tag":123,"props":1596,"children":1597},{"style":281},[1598],{"type":35,"value":294},{"type":29,"tag":123,"props":1600,"children":1601},{"style":135},[1602],{"type":35,"value":348},{"type":29,"tag":123,"props":1604,"children":1605},{"class":125,"line":20},[1606],{"type":29,"tag":123,"props":1607,"children":1608},{"emptyLinePlaceholder":355},[1609],{"type":35,"value":358},{"type":29,"tag":123,"props":1611,"children":1612},{"class":125,"line":395},[1613,1617,1622,1626,1630],{"type":29,"tag":123,"props":1614,"children":1615},{"style":281},[1616],{"type":35,"value":408},{"type":29,"tag":123,"props":1618,"children":1619},{"style":411},[1620],{"type":35,"value":1621}," note",{"type":29,"tag":123,"props":1623,"children":1624},{"style":281},[1625],{"type":35,"value":419},{"type":29,"tag":123,"props":1627,"children":1628},{"style":129},[1629],{"type":35,"value":470},{"type":29,"tag":123,"props":1631,"children":1632},{"style":240},[1633],{"type":35,"value":1634},"({\n",{"type":29,"tag":123,"props":1636,"children":1637},{"class":125,"line":16},[1638,1643,1648],{"type":29,"tag":123,"props":1639,"children":1640},{"style":240},[1641],{"type":35,"value":1642},"  title: ",{"type":29,"tag":123,"props":1644,"children":1645},{"style":135},[1646],{"type":35,"value":1647},"''",{"type":29,"tag":123,"props":1649,"children":1650},{"style":240},[1651],{"type":35,"value":1652},",\n",{"type":29,"tag":123,"props":1654,"children":1655},{"class":125,"line":451},[1656,1661,1666,1670],{"type":29,"tag":123,"props":1657,"children":1658},{"style":240},[1659],{"type":35,"value":1660},"  todos: [] ",{"type":29,"tag":123,"props":1662,"children":1663},{"style":281},[1664],{"type":35,"value":1665},"as",{"type":29,"tag":123,"props":1667,"children":1668},{"style":129},[1669],{"type":35,"value":387},{"type":29,"tag":123,"props":1671,"children":1672},{"style":240},[1673],{"type":35,"value":1674},"[],\n",{"type":29,"tag":123,"props":1676,"children":1677},{"class":125,"line":487},[1678],{"type":29,"tag":123,"props":1679,"children":1680},{"style":240},[1681],{"type":35,"value":542},{"type":29,"tag":123,"props":1683,"children":1684},{"class":125,"line":495},[1685],{"type":29,"tag":123,"props":1686,"children":1687},{"emptyLinePlaceholder":355},[1688],{"type":35,"value":358},{"type":29,"tag":123,"props":1690,"children":1691},{"class":125,"line":518},[1692,1696,1701,1706,1711,1716,1720,1725,1729,1734,1738,1743,1748,1752,1757],{"type":29,"tag":123,"props":1693,"children":1694},{"style":281},[1695],{"type":35,"value":408},{"type":29,"tag":123,"props":1697,"children":1698},{"style":240},[1699],{"type":35,"value":1700}," { ",{"type":29,"tag":123,"props":1702,"children":1703},{"style":411},[1704],{"type":35,"value":1705},"undo",{"type":29,"tag":123,"props":1707,"children":1708},{"style":240},[1709],{"type":35,"value":1710},", ",{"type":29,"tag":123,"props":1712,"children":1713},{"style":411},[1714],{"type":35,"value":1715},"redo",{"type":29,"tag":123,"props":1717,"children":1718},{"style":240},[1719],{"type":35,"value":1710},{"type":29,"tag":123,"props":1721,"children":1722},{"style":411},[1723],{"type":35,"value":1724},"canUndo",{"type":29,"tag":123,"props":1726,"children":1727},{"style":240},[1728],{"type":35,"value":1710},{"type":29,"tag":123,"props":1730,"children":1731},{"style":411},[1732],{"type":35,"value":1733},"canRedo",{"type":29,"tag":123,"props":1735,"children":1736},{"style":240},[1737],{"type":35,"value":1710},{"type":29,"tag":123,"props":1739,"children":1740},{"style":411},[1741],{"type":35,"value":1742},"clear",{"type":29,"tag":123,"props":1744,"children":1745},{"style":240},[1746],{"type":35,"value":1747}," } ",{"type":29,"tag":123,"props":1749,"children":1750},{"style":281},[1751],{"type":35,"value":264},{"type":29,"tag":123,"props":1753,"children":1754},{"style":129},[1755],{"type":35,"value":1756}," useRefHistory",{"type":29,"tag":123,"props":1758,"children":1759},{"style":240},[1760],{"type":35,"value":1761},"(note, {\n",{"type":29,"tag":123,"props":1763,"children":1764},{"class":125,"line":536},[1765,1770,1775],{"type":29,"tag":123,"props":1766,"children":1767},{"style":240},[1768],{"type":35,"value":1769},"  deep: ",{"type":29,"tag":123,"props":1771,"children":1772},{"style":411},[1773],{"type":35,"value":1774},"true",{"type":29,"tag":123,"props":1776,"children":1777},{"style":240},[1778],{"type":35,"value":1652},{"type":29,"tag":123,"props":1780,"children":1781},{"class":125,"line":545},[1782],{"type":29,"tag":123,"props":1783,"children":1784},{"style":240},[1785],{"type":35,"value":542},{"type":29,"tag":123,"props":1787,"children":1788},{"class":125,"line":562},[1789],{"type":29,"tag":123,"props":1790,"children":1791},{"emptyLinePlaceholder":355},[1792],{"type":35,"value":358},{"type":29,"tag":123,"props":1794,"children":1795},{"class":125,"line":570},[1796,1801,1806,1810,1815,1819,1824],{"type":29,"tag":123,"props":1797,"children":1798},{"style":281},[1799],{"type":35,"value":1800},"function",{"type":29,"tag":123,"props":1802,"children":1803},{"style":129},[1804],{"type":35,"value":1805}," updateTitle",{"type":29,"tag":123,"props":1807,"children":1808},{"style":240},[1809],{"type":35,"value":475},{"type":29,"tag":123,"props":1811,"children":1812},{"style":374},[1813],{"type":35,"value":1814},"title",{"type":29,"tag":123,"props":1816,"children":1817},{"style":281},[1818],{"type":35,"value":382},{"type":29,"tag":123,"props":1820,"children":1821},{"style":411},[1822],{"type":35,"value":1823}," string",{"type":29,"tag":123,"props":1825,"children":1826},{"style":240},[1827],{"type":35,"value":1185},{"type":29,"tag":123,"props":1829,"children":1830},{"class":125,"line":587},[1831,1836,1840],{"type":29,"tag":123,"props":1832,"children":1833},{"style":240},[1834],{"type":35,"value":1835},"  note.value.title ",{"type":29,"tag":123,"props":1837,"children":1838},{"style":281},[1839],{"type":35,"value":264},{"type":29,"tag":123,"props":1841,"children":1842},{"style":240},[1843],{"type":35,"value":1844}," title\n",{"type":29,"tag":123,"props":1846,"children":1847},{"class":125,"line":618},[1848],{"type":29,"tag":123,"props":1849,"children":1850},{"style":240},[1851],{"type":35,"value":1211},{"type":29,"tag":123,"props":1853,"children":1854},{"class":125,"line":650},[1855],{"type":29,"tag":123,"props":1856,"children":1857},{"emptyLinePlaceholder":355},[1858],{"type":35,"value":358},{"type":29,"tag":123,"props":1860,"children":1861},{"class":125,"line":694},[1862,1866,1871],{"type":29,"tag":123,"props":1863,"children":1864},{"style":281},[1865],{"type":35,"value":1800},{"type":29,"tag":123,"props":1867,"children":1868},{"style":129},[1869],{"type":35,"value":1870}," addNewTodo",{"type":29,"tag":123,"props":1872,"children":1873},{"style":240},[1874],{"type":35,"value":1875},"() {\n",{"type":29,"tag":123,"props":1877,"children":1878},{"class":125,"line":703},[1879,1884,1888,1893,1897,1901],{"type":29,"tag":123,"props":1880,"children":1881},{"style":240},[1882],{"type":35,"value":1883},"  note.value.todos.",{"type":29,"tag":123,"props":1885,"children":1886},{"style":129},[1887],{"type":35,"value":1198},{"type":29,"tag":123,"props":1889,"children":1890},{"style":240},[1891],{"type":35,"value":1892},"({} ",{"type":29,"tag":123,"props":1894,"children":1895},{"style":281},[1896],{"type":35,"value":1665},{"type":29,"tag":123,"props":1898,"children":1899},{"style":129},[1900],{"type":35,"value":387},{"type":29,"tag":123,"props":1902,"children":1903},{"style":240},[1904],{"type":35,"value":448},{"type":29,"tag":123,"props":1906,"children":1907},{"class":125,"line":720},[1908],{"type":29,"tag":123,"props":1909,"children":1910},{"style":240},[1911],{"type":35,"value":1211},{"type":29,"tag":123,"props":1913,"children":1914},{"class":125,"line":733},[1915],{"type":29,"tag":123,"props":1916,"children":1917},{"emptyLinePlaceholder":355},[1918],{"type":35,"value":358},{"type":29,"tag":123,"props":1920,"children":1921},{"class":125,"line":742},[1922,1926,1931,1935,1940,1944,1948],{"type":29,"tag":123,"props":1923,"children":1924},{"style":281},[1925],{"type":35,"value":1800},{"type":29,"tag":123,"props":1927,"children":1928},{"style":129},[1929],{"type":35,"value":1930}," onRemoveTodo",{"type":29,"tag":123,"props":1932,"children":1933},{"style":240},[1934],{"type":35,"value":475},{"type":29,"tag":123,"props":1936,"children":1937},{"style":374},[1938],{"type":35,"value":1939},"index",{"type":29,"tag":123,"props":1941,"children":1942},{"style":281},[1943],{"type":35,"value":382},{"type":29,"tag":123,"props":1945,"children":1946},{"style":411},[1947],{"type":35,"value":1252},{"type":29,"tag":123,"props":1949,"children":1950},{"style":240},[1951],{"type":35,"value":1185},{"type":29,"tag":123,"props":1953,"children":1954},{"class":125,"line":760},[1955,1959,1964,1969,1974],{"type":29,"tag":123,"props":1956,"children":1957},{"style":240},[1958],{"type":35,"value":1883},{"type":29,"tag":123,"props":1960,"children":1961},{"style":129},[1962],{"type":35,"value":1963},"splice",{"type":29,"tag":123,"props":1965,"children":1966},{"style":240},[1967],{"type":35,"value":1968},"(index, ",{"type":29,"tag":123,"props":1970,"children":1971},{"style":411},[1972],{"type":35,"value":1973},"1",{"type":29,"tag":123,"props":1975,"children":1976},{"style":240},[1977],{"type":35,"value":448},{"type":29,"tag":123,"props":1979,"children":1980},{"class":125,"line":778},[1981],{"type":29,"tag":123,"props":1982,"children":1983},{"style":240},[1984],{"type":35,"value":1211},{"type":29,"tag":123,"props":1986,"children":1987},{"class":125,"line":796},[1988,1992,1996],{"type":29,"tag":123,"props":1989,"children":1990},{"style":240},[1991],{"type":35,"value":551},{"type":29,"tag":123,"props":1993,"children":1994},{"style":246},[1995],{"type":35,"value":249},{"type":29,"tag":123,"props":1997,"children":1998},{"style":240},[1999],{"type":35,"value":274},{"type":29,"tag":123,"props":2001,"children":2002},{"class":125,"line":805},[2003],{"type":29,"tag":123,"props":2004,"children":2005},{"emptyLinePlaceholder":355},[2006],{"type":35,"value":358},{"type":29,"tag":123,"props":2008,"children":2009},{"class":125,"line":822},[2010,2014,2018],{"type":29,"tag":123,"props":2011,"children":2012},{"style":240},[2013],{"type":35,"value":243},{"type":29,"tag":123,"props":2015,"children":2016},{"style":246},[2017],{"type":35,"value":580},{"type":29,"tag":123,"props":2019,"children":2020},{"style":240},[2021],{"type":35,"value":274},{"type":29,"tag":123,"props":2023,"children":2025},{"class":125,"line":2024},30,[2026],{"type":29,"tag":123,"props":2027,"children":2028},{"style":955},[2029],{"type":35,"value":2030},"  \u003C!-- ... -->\n",{"type":29,"tag":123,"props":2032,"children":2034},{"class":125,"line":2033},31,[2035,2039,2044],{"type":29,"tag":123,"props":2036,"children":2037},{"style":240},[2038],{"type":35,"value":593},{"type":29,"tag":123,"props":2040,"children":2041},{"style":246},[2042],{"type":35,"value":2043},"div",{"type":29,"tag":123,"props":2045,"children":2046},{"style":240},[2047],{"type":35,"value":274},{"type":29,"tag":123,"props":2049,"children":2051},{"class":125,"line":2050},32,[2052,2056,2061,2065,2069,2074,2079,2083,2088,2092,2096,2101,2106,2110],{"type":29,"tag":123,"props":2053,"children":2054},{"style":240},[2055],{"type":35,"value":624},{"type":29,"tag":123,"props":2057,"children":2058},{"style":246},[2059],{"type":35,"value":2060},"button",{"type":29,"tag":123,"props":2062,"children":2063},{"style":129},[2064],{"type":35,"value":334},{"type":29,"tag":123,"props":2066,"children":2067},{"style":240},[2068],{"type":35,"value":264},{"type":29,"tag":123,"props":2070,"children":2071},{"style":135},[2072],{"type":35,"value":2073},"\"button\"",{"type":29,"tag":123,"props":2075,"children":2076},{"style":129},[2077],{"type":35,"value":2078}," :disabled",{"type":29,"tag":123,"props":2080,"children":2081},{"style":240},[2082],{"type":35,"value":264},{"type":29,"tag":123,"props":2084,"children":2085},{"style":135},[2086],{"type":35,"value":2087},"\"!canUndo\"",{"type":29,"tag":123,"props":2089,"children":2090},{"style":129},[2091],{"type":35,"value":678},{"type":29,"tag":123,"props":2093,"children":2094},{"style":240},[2095],{"type":35,"value":264},{"type":29,"tag":123,"props":2097,"children":2098},{"style":135},[2099],{"type":35,"value":2100},"\"undo()\"",{"type":29,"tag":123,"props":2102,"children":2103},{"style":240},[2104],{"type":35,"value":2105},">Undo\u003C\u002F",{"type":29,"tag":123,"props":2107,"children":2108},{"style":246},[2109],{"type":35,"value":2060},{"type":29,"tag":123,"props":2111,"children":2112},{"style":240},[2113],{"type":35,"value":274},{"type":29,"tag":123,"props":2115,"children":2117},{"class":125,"line":2116},33,[2118,2122,2126,2130,2134,2138,2142,2146,2151,2155,2159,2164,2169,2173],{"type":29,"tag":123,"props":2119,"children":2120},{"style":240},[2121],{"type":35,"value":624},{"type":29,"tag":123,"props":2123,"children":2124},{"style":246},[2125],{"type":35,"value":2060},{"type":29,"tag":123,"props":2127,"children":2128},{"style":129},[2129],{"type":35,"value":334},{"type":29,"tag":123,"props":2131,"children":2132},{"style":240},[2133],{"type":35,"value":264},{"type":29,"tag":123,"props":2135,"children":2136},{"style":135},[2137],{"type":35,"value":2073},{"type":29,"tag":123,"props":2139,"children":2140},{"style":129},[2141],{"type":35,"value":2078},{"type":29,"tag":123,"props":2143,"children":2144},{"style":240},[2145],{"type":35,"value":264},{"type":29,"tag":123,"props":2147,"children":2148},{"style":135},[2149],{"type":35,"value":2150},"\"!canRedo\"",{"type":29,"tag":123,"props":2152,"children":2153},{"style":129},[2154],{"type":35,"value":678},{"type":29,"tag":123,"props":2156,"children":2157},{"style":240},[2158],{"type":35,"value":264},{"type":29,"tag":123,"props":2160,"children":2161},{"style":135},[2162],{"type":35,"value":2163},"\"redo()\"",{"type":29,"tag":123,"props":2165,"children":2166},{"style":240},[2167],{"type":35,"value":2168},">Redo\u003C\u002F",{"type":29,"tag":123,"props":2170,"children":2171},{"style":246},[2172],{"type":35,"value":2060},{"type":29,"tag":123,"props":2174,"children":2175},{"style":240},[2176],{"type":35,"value":274},{"type":29,"tag":123,"props":2178,"children":2180},{"class":125,"line":2179},34,[2181,2185,2189],{"type":29,"tag":123,"props":2182,"children":2183},{"style":240},[2184],{"type":35,"value":811},{"type":29,"tag":123,"props":2186,"children":2187},{"style":246},[2188],{"type":35,"value":2043},{"type":29,"tag":123,"props":2190,"children":2191},{"style":240},[2192],{"type":35,"value":274},{"type":29,"tag":123,"props":2194,"children":2196},{"class":125,"line":2195},35,[2197],{"type":29,"tag":123,"props":2198,"children":2199},{"style":955},[2200],{"type":35,"value":2030},{"type":29,"tag":123,"props":2202,"children":2204},{"class":125,"line":2203},36,[2205,2209,2213],{"type":29,"tag":123,"props":2206,"children":2207},{"style":240},[2208],{"type":35,"value":551},{"type":29,"tag":123,"props":2210,"children":2211},{"style":246},[2212],{"type":35,"value":580},{"type":29,"tag":123,"props":2214,"children":2215},{"style":240},[2216],{"type":35,"value":274},{"type":29,"tag":49,"props":2218,"children":2219},{},[2220,2222,2227,2229,2235,2237,2242,2244,2250],{"type":35,"value":2221},"We create a reactive ",{"type":29,"tag":98,"props":2223,"children":2225},{"className":2224},[],[2226],{"type":35,"value":1171},{"type":35,"value":2228}," with ",{"type":29,"tag":98,"props":2230,"children":2232},{"className":2231},[],[2233],{"type":35,"value":2234},"ref",{"type":35,"value":2236}," and pass it to ",{"type":29,"tag":98,"props":2238,"children":2240},{"className":2239},[],[2241],{"type":35,"value":1491},{"type":35,"value":2243},". The ",{"type":29,"tag":98,"props":2245,"children":2247},{"className":2246},[],[2248],{"type":35,"value":2249},"deep: true",{"type":35,"value":2251}," option is needed because we mutate nested properties of the object; with it, snapshots are also cloned, so each history entry is independent.",{"type":29,"tag":49,"props":2253,"children":2254},{},[2255,2257,2262,2263,2268,2269,2274,2275,2280,2282,2287,2289,2294,2295,2300,2302,2308,2310,2315,2317,2323,2325,2331,2332,2338,2339,2345,2346,2352,2354,2360],{"type":35,"value":2256},"From the returned object we take ",{"type":29,"tag":98,"props":2258,"children":2260},{"className":2259},[],[2261],{"type":35,"value":1705},{"type":35,"value":1710},{"type":29,"tag":98,"props":2264,"children":2266},{"className":2265},[],[2267],{"type":35,"value":1715},{"type":35,"value":1710},{"type":29,"tag":98,"props":2270,"children":2272},{"className":2271},[],[2273],{"type":35,"value":1724},{"type":35,"value":1710},{"type":29,"tag":98,"props":2276,"children":2278},{"className":2277},[],[2279],{"type":35,"value":1733},{"type":35,"value":2281}," and ",{"type":29,"tag":98,"props":2283,"children":2285},{"className":2284},[],[2286],{"type":35,"value":1742},{"type":35,"value":2288},". ",{"type":29,"tag":98,"props":2290,"children":2292},{"className":2291},[],[2293],{"type":35,"value":1724},{"type":35,"value":2281},{"type":29,"tag":98,"props":2296,"children":2298},{"className":2297},[],[2299],{"type":35,"value":1733},{"type":35,"value":2301}," are bound to the buttons' ",{"type":29,"tag":98,"props":2303,"children":2305},{"className":2304},[],[2306],{"type":35,"value":2307},"disabled",{"type":35,"value":2309}," attributes, and ",{"type":29,"tag":98,"props":2311,"children":2313},{"className":2312},[],[2314],{"type":35,"value":1742},{"type":35,"value":2316}," resets the history, for example after the user finishes editing. The return value has more to offer: ",{"type":29,"tag":98,"props":2318,"children":2320},{"className":2319},[],[2321],{"type":35,"value":2322},"history",{"type":35,"value":2324}," (the list of snapshots), ",{"type":29,"tag":98,"props":2326,"children":2328},{"className":2327},[],[2329],{"type":35,"value":2330},"commit",{"type":35,"value":1710},{"type":29,"tag":98,"props":2333,"children":2335},{"className":2334},[],[2336],{"type":35,"value":2337},"reset",{"type":35,"value":1710},{"type":29,"tag":98,"props":2340,"children":2342},{"className":2341},[],[2343],{"type":35,"value":2344},"pause",{"type":35,"value":1431},{"type":29,"tag":98,"props":2347,"children":2349},{"className":2348},[],[2350],{"type":35,"value":2351},"resume",{"type":35,"value":2353}," and others. You can also limit the number of stored entries with the ",{"type":29,"tag":98,"props":2355,"children":2357},{"className":2356},[],[2358],{"type":35,"value":2359},"capacity",{"type":35,"value":2361}," option.",{"type":29,"tag":49,"props":2363,"children":2364},{},[2365,2367,2373,2375,2381],{"type":35,"value":2366},"If you'd rather decide yourself when a snapshot is taken, use ",{"type":29,"tag":98,"props":2368,"children":2370},{"className":2369},[],[2371],{"type":35,"value":2372},"useManualRefHistory",{"type":35,"value":2374},": it works the same way, but saves to history only when you call ",{"type":29,"tag":98,"props":2376,"children":2378},{"className":2377},[],[2379],{"type":35,"value":2380},"commit()",{"type":35,"value":105},{"type":29,"tag":171,"props":2383,"children":2385},{"id":2384},"conclusion",[2386],{"type":35,"value":2387},"Conclusion",{"type":29,"tag":49,"props":2389,"children":2390},{},[2391,2393,2399],{"type":35,"value":2392},"I've covered only four functions from VueUse's large toolbox. To dig deeper, visit the ",{"type":29,"tag":38,"props":2394,"children":2396},{"href":56,"rel":2395},[42],[2397],{"type":35,"value":2398},"library's website",{"type":35,"value":2400},": every function comes with an interactive demo, a description of its options and TypeScript types, and both the docs and the library itself are updated regularly.",{"type":29,"tag":49,"props":2402,"children":2403},{},[2404,2406,2415],{"type":35,"value":2405},"The full code of the sandbox project where I tried out the library is available here: ",{"type":29,"tag":2407,"props":2408,"children":2409},"em",{},[2410],{"type":29,"tag":123,"props":2411,"children":2412},{},[2413],{"type":35,"value":2414},"link to repository",{"type":35,"value":105},{"type":29,"tag":171,"props":2417,"children":2419},{"id":2418},"thanks-to-readers-of-the-first-version",[2420],{"type":35,"value":2421},"Thanks to readers of the first version",{"type":29,"tag":49,"props":2423,"children":2424},{},[2425,2427,2433],{"type":35,"value":2426},"Many thanks to everyone who commented on the ",{"type":29,"tag":38,"props":2428,"children":2430},{"href":40,"rel":2429},[42],[2431],{"type":35,"value":2432},"original article",{"type":35,"value":2434}," — your feedback shaped this update:",{"type":29,"tag":1403,"props":2436,"children":2437},{},[2438,2457,2469,2481],{"type":29,"tag":598,"props":2439,"children":2440},{},[2441,2448,2450,2455],{"type":29,"tag":38,"props":2442,"children":2445},{"href":2443,"rel":2444},"https:\u002F\u002Fdev.to\u002Fwheatjs",[42],[2446],{"type":35,"value":2447},"wheat",{"type":35,"value":2449}," from the VueUse team pointed me to the library's renderless components, which is why this version mentions ",{"type":29,"tag":98,"props":2451,"children":2453},{"className":2452},[],[2454],{"type":35,"value":211},{"type":35,"value":2456}," alongside the composable.",{"type":29,"tag":598,"props":2458,"children":2459},{},[2460,2467],{"type":29,"tag":38,"props":2461,"children":2464},{"href":2462,"rel":2463},"https:\u002F\u002Fdev.to\u002Fpawelmiczka",[42],[2465],{"type":35,"value":2466},"Paweł Miczka",{"type":35,"value":2468}," noted that thanks to tree-shaking you don't have to worry much about bundle size, and that still holds true today.",{"type":29,"tag":598,"props":2470,"children":2471},{},[2472,2479],{"type":29,"tag":38,"props":2473,"children":2476},{"href":2474,"rel":2475},"https:\u002F\u002Fdev.to\u002Feshimischi",[42],[2477],{"type":35,"value":2478},"eshimischi",{"type":35,"value":2480}," reminded us that the library's author, Anthony Fu, is a member of the Vue core team and the creator of many other useful projects, such as Vitesse.",{"type":29,"tag":598,"props":2482,"children":2483},{},[2484,2491],{"type":29,"tag":38,"props":2485,"children":2488},{"href":2486,"rel":2487},"https:\u002F\u002Fdev.to\u002Fjonghunbok",[42],[2489],{"type":35,"value":2490},"박종훈 (Jonghun Park)",{"type":35,"value":2492}," translated the article into Korean for the Korean FE Article newsletter.",{"type":29,"tag":2494,"props":2495,"children":2496},"style",{},[2497],{"type":35,"value":2498},"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);}"]