您好,欢迎来到伴沃教育。
搜索
您的当前位置:首页详细讲一下Pinia的用法,和pinia持久化的用法

详细讲一下Pinia的用法,和pinia持久化的用法

来源:伴沃教育

1. 基础设置

// main.js
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
// 使用持久化插件
pinia.use(piniaPluginPersistedstate)

app.use(pinia)

2. 定义 Store

// store/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
    // 1. state
    state: () => ({
        count: 0,
        name: 'Eduardo',
        items: []
    }),

    // 2. getters
    getters: {
        doubleCount: (state) => state.count * 2,
        // 使用 this 访问 state
        doubleCountPlusOne() {
            return this.doubleCount + 1
        }
    },

    // 3. actions
    actions: {
        increment() {
            this.count++
        },
        async fetchItems() {
            const items = await api.getItems()
            this.items = items
        }
    },

    // 4. 持久化配置
    persist: {
        // 持久化的key
        key: 'counter-store',
        // 持久化的位置
        storage: window.localStorage,
        // 指定要持久化的数据,默认所有 state 都会持久化
        paths: ['count', 'name']
    }
})

3. 组合式 API 写法

// store/user.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', () => {
    // state
    const user = ref(null)
    const token = ref('')

    // getters
    const isLoggedIn = computed(() => !!token.value)

    // actions
    function login(credentials) {
        // 登录逻辑
    }

    function logout() {
        user.value = null
        token.value = ''
    }

    return {
        user,
        token,
        isLoggedIn,
        login,
        logout
    }
}, {
    persist: true  // 开启持久化
})

4. 在组件中使用

<script setup>
import { useCounterStore } from '../stores/counter'
import { useUserStore } from '../stores/user'
import { storeToRefs } from 'pinia'

// 获取 store 实例
const counter = useCounterStore()
const user = useUserStore()

// 解构(使用 storeToRefs 保持响应性)
const { count, name } = storeToRefs(counter)
const { isLoggedIn } = storeToRefs(user)

// 使用 actions
const handleIncrement = () => {
    counter.increment()
}

// 修改状态
counter.count++
// 或者
counter.$patch({
    count: counter.count + 1,
    name: 'Tom'
})
</script>

5. Store 之间的交互

// store/cart.js
import { defineStore } from 'pinia'
import { useUserStore } from './user'

export const useCartStore = defineStore('cart', {
    state: () => ({
        items: []
    }),
    actions: {
        async checkout() {
            const userStore = useUserStore()
            if (!userStore.isLoggedIn) {
                throw new Error('请先登录')
            }
            // 结账逻辑
        }
    }
})

6. 持久化存储的高级配置        

// store/theme.js
import { defineStore } from 'pinia'

export const useThemeStore = defineStore('theme', {
    state: () => ({
        theme: 'light',
        settings: {
            fontSize: 14,
            language: 'zh'
        }
    }),
    persist: {
        key: 'theme-store',
        storage: window.localStorage,
        // 自定义序列化
        serializer: {
            deserialize: JSON.parse,
            serialize: JSON.stringify
        },
        // 持久化前的钩子
        beforeRestore: (context) => {
            console.log('即将恢复数据', context)
        },
        // 持久化后的钩子
        afterRestore: (context) => {
            console.log('数据恢复完成', context)
        }
    }
})

7. 订阅 Store 的变化

// 监听 state 变化
const unsubscribe = store.$subscribe((mutation, state) => {
    console.log('变化类型:', mutation.type)
    console.log('变化数据:', mutation.payload)
    console.log('当前状态:', state)
}, { detached: true })

// 监听 actions
store.$onAction(({
    name, // action 名称
    store, // store 实例
    args, // 传入的参数
    after, // 在 action 完成后触发
    onError // 在 action 报错时触发
}) => {
    console.log(`Action ${name} 被调用`)

    after((result) => {
        console.log(`Action ${name} 完成,结果:`, result)
    })

    onError((error) => {
        console.error(`Action ${name} 出错:`, error)
    })
})

8. 实际应用示例

// store/app.js
import { defineStore } from 'pinia'

export const useAppStore = defineStore('app', {
    state: () => ({
        loading: false,
        error: null,
        notifications: []
    }),
    actions: {
        startLoading() {
            this.loading = true
        },
        stopLoading() {
            this.loading = false
        },
        setError(error) {
            this.error = error
        },
        addNotification(notification) {
            this.notifications.push(notification)
        },
        clearNotifications() {
            this.notifications = []
        }
    },
    persist: {
        paths: ['notifications']
    }
})

使用这个 store:

<script setup>
import { useAppStore } from '../stores/app'
import { storeToRefs } from 'pinia'

const app = useAppStore()
const { loading, error, notifications } = storeToRefs(app)

const fetchData = async () => {
    try {
        app.startLoading()
        await api.getData()
        app.addNotification({
            type: 'success',
            message: '数据加载成功'
        })
    } catch (err) {
        app.setError(err)
        app.addNotification({
            type: 'error',
            message: '数据加载失败'
        })
    } finally {
        app.stopLoading()
    }
}
</script>

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务