A Ref That Saves Itself
Saving in localStorage always takes the same lines: read what's saved when the ref is created, and save it with watch whenever it changes. With a composable, you write them only once:
import { ref, watch } from "vue";
export function useLocalStorage(key, initial) {
const saved = localStorage.getItem(key);
const value = ref(saved === null ? initial : JSON.parse(saved));
watch(
value,
(newValue) => {
localStorage.setItem(key, JSON.stringify(newValue));
},
{ deep: true },
);
return value;
}Then each value that should stay takes one line:
const name = useLocalStorage("name", "");
const order = useLocalStorage("order", []);How it works:
- The composable has two parameters:
key, the name under which it saves, andinitial, the value to start with when nothing has been saved yet. Thanks to them, the same function saves a name under"name"and an order under"order". - It returns a single ref, not an object, so there's nothing to take apart: after
const name = useLocalStorage("name", "");,nameis a ref, ready forv-modelor{{ name }}. - The
watchinside belongs to the call: each call watches its own ref and saves it under its own key.{ deep: true }is there so that apush()into an array is saved too, as you know from Computed Values and Watchers. JSON.stringify()andJSON.parse()work for text, numbers,trueandfalsetoo, so the composable can save anything.
The component doesn't see any of it. It works with name and order as with any other ref, and they save themselves.
Instructions
- 1
In
useLocalStorage.js, writeuseLocalStorage(key, initial)as shown above. InApp.vue, import it, and use it for the name:const name = useLocalStorage("name", "");. Try it: type your name and click Run. The name stays. - 2
Use it for the order too, with the key
orderand an empty array to start with. Order something and click Run: the order stays. AndClear the orderempties it for good.