• vue3使用pinia管理状态


    Pinia

    pinia 是一款新的vue3的状态管理库,完整的typescript支持。

    安装

    yarn add pinia
    # or npm
    npm install pinia
    

    创建根store并且引用到app上

    import { createPinia } from 'pinia'
    
    app.use(createPinia())
    

    定义Store

    使用defineStore定义store,第一个参数必须是全局唯一的id,可以使用Symbol

    import { defineStore } from 'pinia'
    
    // 第一个参数必须是全局唯一,可以是哟
    export const useStore = defineStore('main', {
      
    })
    

    使用store

    setup中使用useStore创建store实例

    <script setup>
    import {useStore} from '@/stores/counter'
      
    const store = useStore()
    
    ....
    </script>
      
    

    状态State

    定义状态

    import { defineStore } from 'pinia',
    
    const useCounterStore = defineStore('counterStore', {
      state: () => ({
        counter: 0
      })
    })
    

    定义强状态

    import { defineStore } from 'pinia',
    
    interface ICounterStoreState{
      counter: number
    }
      
    const useCounterStore = defineStore('counterStore', {
      state: ():ICounterStoreState => ({
        counter: 0
      })
    })
    

    使用和重置状态

    const store = useCounterStore()
    
    // 使用
    store.counter++
    
    // 重置
    store.$reset()
    

    改变状态

    store.$patch({
      counter: store.counter + 1,
      name: 'Abalam',
    })
    

    替换状态

    store.$state = { counter: 666, name: 'Paimon' }
    

    计算属性Getters

    Getter 完全等同于 Store 状态的计算值,可以用 defineStore() 中的 getters 属性定义

    export const useStore = defineStore('main', {
      state: () => ({
        counter: 0,
      }),
      getters: {
        doubleCount: (state) => state.counter * 2,
      },
    })
    

    传递参数到getters

    Getter 是计算属性,也可叫只读属性,因此不可能将任何参数传递给它们。但是可以从 getter 返回一个函数以接受任何参数

    export const useStore = defineStore('main', {
      getters: {
        getUserById: (state) => {
          return (userId) => state.users.find((user) => user.id === userId)
        },
      },
    })
    

    访问其他store的getters

    import { useOtherStore } from './other-store'
    
    export const useStore = defineStore('main', {
      state: () => ({
        // ...
      }),
      getters: {
        otherGetter(state) {
          const otherStore = useOtherStore()
          return state.localData + otherStore.data
        },
      },
    })
    

    动作Actions

    动作相当于组件中的方法,可以使用 defineStore() 中的 actions 属性来定义,它们非常适合定义业务逻辑

    import { mande } from 'mande'
    
    const api = mande('/api/users')
    
    export const useUsers = defineStore('users', {
      state: () => ({
        userData: null,
        // ...
      }),
    
      actions: {
        async registerUser(login, password) {
          try {
            this.userData = await api.post({ login, password })
            showTooltip(`Welcome back ${this.userData.name}!`)
          } catch (error) {
            showTooltip(error)
            // let the form component display the error
            return error
          }
        },
      },
    })
    

    访问其他store的actions

    import { useAuthStore } from './auth-store'
    
    export const useSettingsStore = defineStore('settings', {
      state: () => ({
        preferences: null,
        // ...
      }),
      actions: {
        async fetchUserPreferences() {
          const auth = useAuthStore()
          if (auth.isAuthenticated) {
            this.preferences = await fetchPreferences()
          } else {
            throw new Error('User must be authenticated')
          }
        },
      },
    })
    

    插件

    假设需要在stroe中使用router,就需要使用到pinia的插件机制扩展store的api

    pinia.d.ts

    import 'pinia'
    
    import { Router} from 'vue-router'
    
    declare module 'pinia' {
      export interface PiniaCustomProperties {
        $router: Router,
      }
    }
    

    定义插件

    import { createPinia } from 'pinia'
    import { App} from "vue";
    
    import { router } from '@/routers'
    
    const pinia = createPinia()
    pinia.use(({ store }) => {
        store.$router = router
      })
    app.use(pinia)
    
    

    在action中使用插件定义的pai

    import { defineStore } from 'pinia'
    import { RouteLocationNormalized } from 'vue-router'
    export const useApplicationStore = defineStore('application', {
      state: () => (
        ...
      ),
      actions:{
        toHome(){
          this.$router.push('/home')
        }
      }
    })
    

    推荐结构

    stores
    index.ts
    use.store.ts
    app.store.ts
    ...

    stores/index.ts

    import { createPinia } from 'pinia'
    import { App} from "vue";
    
    const pinia = createPinia()
    
    export function setupPinia(app: App){
        pinia.use(({ store }) => {
            ... 这里安装插件
          })
        app.use(pinia)
    }
    
    export * from './use.store.ts'
    export * from './app.store.ts'
    

    何时使用状态管理器

    全局都会使用到的状态使用状态管理器,比如用户信息、主题、权限等等

  • 相关阅读:
    碰撞检测 :Polygon
    碰撞检测 :Line
    碰撞检测 :Rectangle
    碰撞检测:Point
    Canvas 绘制 1 px 直线模糊(非高清屏)的问题
    threading之线程的开始,暂停和退出
    win10利用hexo+gitee搭建博客
    Fullscreen API与DOM监听API
    <el-input>只能输入数字,保留两位小数
    谷歌浏览器查看gitee和github代码的插件
  • 原文地址:https://www.cnblogs.com/zhaord/p/16187429.html
Copyright © 2020-2023  润新知