Vue3 - 自定义useLocalStorage

目录

  • 1,需求
  • 2,实现
  • 3,使用

1,需求

在多页面应用中,因为每个页面都是独立的,所以页面之间的通信无法使用 Vuex 这样的状态管理器,只能使用 url 传参或 localStorage

需求:项目相关的全局配置项,会在主页通过接口获取,同时其他页面会用到。

如果只是简单的在接口数据获取后使用 localStorage.setItem();,这样虽然可以在除主页之外的其他页面中使用 localStorage.getItem(); 获取数据,但主页不行,因为数据不是响应式的。

所以,一种解决办法是主页使用 Vuex 来管理配置项 + 其他页面使用 localStorage

既然已经选型为多页面应用了,所以大多情况下页面之间的通信也不会很多,可以将 Vuex 替换为更简单的单一状态管理,也就是一个全局的响应式对象。

最后为了统一管理,将单一状态管理 + localStorage 结合,就是要实现的 useLocalStorage

2,实现

整体思路:

  1. 调用 useLocalStorage() 始终返回的是一个响应式对象 data
  2. 每次修改 data 时,会同步更新 localStorage
  3. 必须传递 name 才能获取对应的 value。因为 data 一开始并没有值,所以需要传递 name 才能获取本地的。
  4. 获取指定数据时,先判断 data 中时候存在,再判断 localStorage ,否则为''
import { ref, watchEffect } from 'vue'

let data = ref({})

/**
 * @param {String | String[]} name
 * @param {Object} value
 * @returns
 */
export const useLocalStorage = (name, value) => {
  // name 是数组时,只读取
  if (Array.isArray(name)) {
    name.forEach((n) => {
      if (!data.value[n]) {
        setItem(n)
      }
    })
  } else if (name) {
    if (value) {
      data.value[name] = value
    } else if (!data.value[name]) {
      setItem(name)
    }
    watchEffect(() => {
      localStorage.setItem(name, JSON.stringify(data.value[name]))
    })
  }
  return data
}

function setItem(name) {
  let tempValue = localStorage.getItem(name)
  try {
    tempValue = tempValue ? JSON.parse(tempValue) : ''
  } catch (error) {
    console.log('JSON 解析失败,请检查')
  }
  data.value[name] = tempValue
}

3,使用

设置数据

useLocalStorage('publicPath', './')
useLocalStorage('homeConfig', {color: '#000'})

获取单个数据

const storageRef = useLocalStorage('publicPath')
const publicPath = computed(() => storageRef.value.publicPath)

获取多个数据

const storageRef = useLocalStorage(['publicPath', 'homeConfig'])
const publicPath = computed(() => storageRef.value.publicPath)

以上

你可能感兴趣的:(vue3,问题解决,javascript,vue.js,前端,vue3)