Skip to content

Commit

Permalink
task 23 done
Browse files Browse the repository at this point in the history
  • Loading branch information
Serhii Chernenko committed Sep 10, 2024
1 parent cdd3796 commit f3ffc75
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
30 changes: 28 additions & 2 deletions src/composables/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
export function useLocalStorage(key, defaultValue) {
return defaultValue
import type { Ref } from 'vue'
import { shallowRef, watchEffect, toValue, onMounted, onUnmounted } from 'vue'

export const useLocalStorage = (
key: string,
defaultValue: string,
): Ref<string> => {
const value = shallowRef<string>(localStorage.getItem(key) ?? defaultValue)

watchEffect(() => localStorage.setItem(key, toValue(value)))

const listener = (event: StorageEvent) => {
if (event.key !== key) {
return
}

value.value = event.newValue ?? defaultValue
}

onMounted(() => {
window.addEventListener('storage', listener)
})

onUnmounted(() => {
window.removeEventListener('storage', listener)
})

return value
}
36 changes: 31 additions & 5 deletions tests/useLocalStorage.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
import { describe, it, expect, beforeEach } from 'vitest'
import { createApp } from 'vue'
import { useLocalStorage } from '../src/composables/useLocalStorage'

const storageKey = 'test'

describe('useLocalStorage', () => {
beforeEach(function () {
localStorage.clear()
const withSetup = (composable) => {
let result
const app = createApp({
setup() {
result = composable()

return () => {}
},
})

app.mount(document.createElement('div'))

return [result, app]
}

beforeEach(() => localStorage.clear())

describe('useLocalStorage', () => {
it('should work w/ default value', () => {
const storage = useLocalStorage(storageKey, 'default')
const [storage, app] = withSetup(() => {
return useLocalStorage(storageKey, 'default')
})

expect(storage.value).toBe('default')
expect(localStorage.getItem(storageKey)).toBe('default')

app.unmount()
})

it('should work w/ storage event', () => {
const storage = useLocalStorage(storageKey, 'default')
const [storage, app] = withSetup(() => {
return useLocalStorage(storageKey, 'default')
})
const storageEvent = new StorageEvent('storage', {
key: storageKey,
newValue: 'new value',
})

window.dispatchEvent(storageEvent)

expect(storage.value).toBe('new value')

app.unmount()
})
})

0 comments on commit f3ffc75

Please sign in to comment.