vueuse state

376 阅读3分钟

这里介绍一下vueuse的State相关的Api和具体用法

一、State相关

createGlobalState

将状态保存全局作用域中,以便跨Vue实例复用,使用场景:存储全局状态,任何组件都能拿到

state-store.ts

import { ref } from 'vue' 
import { createGlobalState } from '@vueuse/core' 
export const useGlobalState = createGlobalState( () => { 
   const count = ref(0)
   return { count }
})

组件中使用:

import { useGlobalCountState } from '@/stores/state-store'
const count = useGlobalCountState().count;
createInjectionState

创建可以注入到组件中的全局状态,使用场景:存储该组件需要的状态,只能用于该组件及其子组件

state-store.ts

const [useProvideCounterStore, useCounterStore] = createInjectionState((initialValue: number) => {
  // state
  const count = ref(initialValue)

  // getters
  const double = computed(() => count.value * 2)

  // actions
  function increment() {
    count.value++
  }

  return { count, double, increment }
})

父组件:

import { useProvideCounterStore } from '@/stores/state-store'
useProvideCounterStore(3);

子组件:

import { useCounterStore } from '@/stores/state-store'
const count = useCounterStore().count; // 3
const double = useCounterStore().double; // 6
createSharedComposable

让一个钩子函数可用于多个Vue实例中

// state-store.ts
import { createSharedComposable, useMouse } from '@vueuse/core'

const useSharedMouse = createSharedComposable(useMouse)

// StateA.vue
const { x, y } = useSharedMouse()

// StateB.vue 因为useMouse是需要监听鼠标事件的,使用createSharedComposable 可以让两个组件共用一个监听事件,减少多个监听
const { x, y } = useSharedMouse()

useAsyncState

响应式获取异步状态。不会阻塞setup 函数,在promise完成后,将自动触发

// state-store.ts
import { useAsyncState } from '@vueuse/core'
import axios from 'axios'

export const asyncState = () => {
  return useAsyncState(
    (args) => {
      const id = args?.id || 1
      return axios.get(`https://jsonplaceholder.typicode.com/todos/${id}`).then((t) => t.data)
    },
    {},
    {
      immediate: false, // 初次不执行
      delay: 2000,
      resetOnExecute: true // 在执行promise之前,将状态设置为initialState
    }
  )

组件中:

const { isLoading, state, isReady, execute } = asyncState()

const loadData = () => {
  execute(2000, { id: 2 })
}

// template
  <a-button @click="loadData">获取异步数据</a-button>
  <note>Ready: {{ isReady }}</note>
  <note>Loading: {{ isLoading }}</note>
  <pre lang="json" class="ml-2">{{ state }}</pre>

一、Ref相关

useRefHistory

跟踪 ref 的更改历史,提供撤销和重做功能,适用于需要提供上一步,下一步场景的需求

import { useRefHistory } from '@vueuse/core';

const counter = ref(0)
const { history, undo, redo } = useRefHistory(counter);

// 如过ref是个对象或者数组,需要加上{ deep: true }
const state = ref({
  a: 0,
  b: 0
})
const { history, undo, redo } = useRefHistory(state, { deep: true });

useManualRefHistory

调用 commit() 时,手动跟踪ref的更改历史,提供撤消和重做功能,和useRefHistory的区别是执行了commit方法才开始跟踪

import { useManualRefHistory } from '@vueuse/core';

const counter = ref(0)
const { history, commit, undo, redo } = useManualRefHistory(counter);

// 需要的时候调用
const commitHistory = () => {
   commit();
}

useDebouncedRefHistory

带有防抖功能的useRefHistory

import { useDebouncedRefHistory } from '@vueuse/core';

const counter = ref(0)
const { history, undo, redo } = useDebouncedRefHistory(counter, { deep: true, debounce: 1000 })

useThrottledRefHistory

带有节流功能的useRefHistory

import { useThrottledRefHistory } from '@vueuse/core';

const counter = ref(0)
const { history, undo, redo } = useThrottledRefHistory(counter, { deep: true, throttle: 1000 })

useLastChanged

记录最后一次更改的时间戳

import { useLastChanged } from '@vueuse/core'

const counter = ref(0)
const lastChanged = useLastChanged(counter) // counter每次变化后都会更新

一、Storage相关

useStorage

响应式的LocalStorage或者SessionStorage

import { useStorage } from '@vueuse/core'

// 默认是LocalStorage
const l_state = useStorage('my-l-store', { hello: 'hi', greeting: 'hello' })
// SessionStorage存法
const s_state = useStorage('my-s-store', { hello: 'hi', greeting: 'hello' }, sessionStorage)

// 修改store
const changeStore = () => {
    l_state.value = { hello: 'hihh', greeting: 'hellohello' }
    s_state.value = { hello: 'hihh', greeting: 'hellohello' }
}

// 清除store
const clearStore = () => {
    l_state.value = null;
    s_state.value = null;
}

useLocalStorage

响应式的LocalStorage,同useStorage

useSessionStorage

响应式的SessionStorage,同useStorage,用useStorage的需要设置第三个参数为sessionStorage

useStorageAsync

支持异步的响应式Storage

import { useStorageAsync, type StorageLikeAsync } from '@vueuse/core'

const initialValue = '初始值'

// 定义一个异步store
const storeAsync: StorageLikeAsync = {
  getItem: () => {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('异步值')
      }, 2000)
    })
  },
  setItem: () => {},
  removeItem: () => {}
}

const async_state = useStorageAsync('my-async-store', initialValue, storeAsync)

// template 刚开始展示【初始值】,2s后展示【异步值】
<div>{{ async_state }}</div>