rubystarashe / nuxt-vuex-localstorage

MIT License
161 stars 18 forks source link

Can hydration be synchronous? #6

Open imShara opened 5 years ago

imShara commented 5 years ago

It's impossible to use one-way binding in component through data() with asyncronous store hydration

// LocalStorage
setting = 2

// ~/store/settings.js
export const state = () => ({
  setting: 1
})

// ~/pages/settings.vue
data() {
  return {
    setting: this.$store.state.settings.setting // setting = 1
  }
}

created() {
  window.console.log(this.$store.state.settings.cardsNumber) // setting = 1
  setTimeout(() => {
    window.console.log(this.$store.state.settings.cardsNumber) // setting = 2 (!)
  }, 1000)
}
rubystarashe commented 5 years ago

How about this

data() {
  return {
    store: eval({ setting: this.$store.state.settings.setting })
  }
}
imShara commented 5 years ago

Terrible. Because eval. Because hack.

My non-lib temporary solution:

export function getLocal(path, fallback) {
  if (!window && !window.localStorage) return fallback
  const item = localStorage.getItem(path)
  if (item !== null) return JSON.parse(item)
  return fallback
}

function setLocal(state, prefix, key, value) {
  state[key] = value
  if (!window && !window.localStorage) return
  localStorage.setItem(`${prefix}.${key}`, JSON.stringify(value))
}

export const state = () => ({
  setting: getLocal('settings.setting', 1)
})

export const mutations = {
  update(state, settings) {
    for (let s = 0; s < settings.length; s++) {
      setLocal(state, 'settings', settings[s][0], settings[s][1])
    }
  }
}
rubystarashe commented 5 years ago

ahhhhhhhhhhhhhh omg I got wrong. misunderstood. I didn't get enough sleep.

Okay I will add new functions & options for that. Thank you

drewbaker commented 5 years ago

+1 to this.

I use this for showing GDPR notices, and it will show a flash of the notice on load currently.

rubystarashe commented 3 years ago

I'm testing some designs for this function. please wait for it <3