认识pinia

认识pinia

介绍pinia

介绍pinia

pinia是新一代的vue状态管理工具,具有如下特点

  • 完整的 ts 的支持;
  • 足够轻量,压缩后的体积只有1kb左右;
  • 去除 mutations,只有 state,getters,actions;
  • actions 支持同步和异步;
  • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
  • 无需手动添加 store,store 一旦创建便会自动添加;
  • 支持Vue3 和 Vue2

安装pinia

yarn add pinia
 
npm install pinia

引入pinia

import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
 
const store = createPinia()
let app = createApp(App)
 
 
app.use(store)
 
app.mount('#app')

初始化pinia

在src目录下新建store文件夹

新建文件 [name].js

定义store(仓库)

import { defineStore } from 'pinia'

第一个store文件

import { defineStore } from 'pinia'
//传入两个参数  第一个参数是id 可以在devtool中通过id来查看
//第二个是配置项 state 为数据 getter类似计算属性 action 修改数据的方法 支持同步异步
export const useUserStore = defineStore('user', {
     state:()=>{
         return {
             num: 1
         }
     },
     //类似于computed 可以帮我们去修饰我们的值
     getters:{
 
     },
     //可以操作异步 和 同步提交state
     actions:{
 
     }
})

State

state 是允许直接修改值的 例如num++

<template>
    <el-button @click="addFn">+1</el-button>
    <div>{{ user.num }}</div>
</template>

<script setup>
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
const addFn = () => {
    user.num++
}
</script>
<style scoped lang='less'>
</style>

批量修改store的值

<template>
    <el-button @click="addFn">+1</el-button>
    <div>num:{{ user.num }}</div>
    <div>age:{{ user.age }}</div>
</template>

<script setup>
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
const addFn = () => {
    user.$patch({
        num: 100,
        age: 300
    })
}
</script>
<style scoped lang='less'>
</style>

批量修改函数形式

<template>
    <el-button @click="addFn">+1</el-button>
    <div>num:{{ user.num }}</div>
    <div>age:{{ user.age }}</div>
</template>

<script setup>
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
const addFn = () => {
    //推荐使用
    user.$patch((state) => {
        state.num++;
        state.age = 40
    })

}
</script>
<style scoped lang='less'>
</style>

通过原始对象修改整个实例

  • $state您可以通过将store的属性设置为新对象来替换store的整个状态
  • 缺点就是必须修改整个对象的所有属性
<template>
    <el-button @click="addFn">+1</el-button>
    <div>num:{{ user.num }}</div>
    <div>age:{{ user.age }}</div>
</template>

<script setup>
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
const addFn = () => {
    user.$state = {
        num: 10,
        age: 30
    }

}
</script>
<style scoped lang='less'>
</style>

通过actions修改

state.js

import { defineStore } from 'pinia'
//user为id是必传的
export const useUserStore = defineStore('user', {
    state: () => {
        return {
            num: 1,
            age: 18
        }
    },
    getters: {},
    actions: {
        updataUser() {
            this.num++
            this.age = 10
        }
    }
})

<template>
    <el-button @click="addFn">+1</el-button>
    <div>num:{{ user.num }}</div>
    <div>age:{{ user.age }}</div>
</template>

<script setup>
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
const addFn = () => {
    user.updataUser()
}
</script>
<style scoped lang='less'>
</style>

解构state

  • 在Pinia是不允许直接解构是会失去响应性的

  • 修改 解构完之后的数据不会变,而源数据是会改变的

  • 解决方案可以使用 storeToRefs

    <template>
        <el-button @click="addFn">+1</el-button>
        <div>num:{{ num }}</div>
        <div>age:{{ age }}</div>
    </template>
    
    <script setup>
    import { storeToRefs } from 'pinia'
    import { useUserStore } from '_store/useUser.js'
    const user = useUserStore()
    const { num, age } = storeToRefs(user)
    console.log(num, age);
    const addFn = () => {
        user.num++
    } 
    </script>
    <style scoped lang='less'>
    </style>
    

action

同步 直接调用即可

import { defineStore } from 'pinia'
//user为id是必传的
export const useUserStore = defineStore('user', {
    state: () => {
        return {
            num: 1,
            age: 18
        }
    },
    getters: {},
    actions: {
        updataUser() {
            this.num++
            this.age = 10
        }
    }
})

<template>
    <el-button @click="addFn">+1</el-button>
    <div>num:{{ num }}</div>
    <div>age:{{ age }}</div>
</template>

<script setup>
import { storeToRefs } from 'pinia'
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
console.log(num, age);
const addFn = () => {
    user.updataUser()
} 
</script>
<style scoped lang='less'>
</style>

异步

import { defineStore } from 'pinia'
//user为id是必传的
const asyncFn = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('info')
        }, 3000)
    })
}
export const useUserStore = defineStore('user', {
    state: () => {
        return {
            num: 1,
            age: 18,
            info: ''
        }
    },
    getters: {},
    actions: {
        async getInfo() {
            const res = await asyncFn()
            console.log(res)
            this.info = res
        }
    }
})

<template>
    <el-button @click="addFn">+1</el-button>
    <div>num:{{ user.num }}</div>
    <div>age:{{ user.age }}</div>
    <div>info:{{ user.info }}</div>
</template>

<script setup>
import { useUserStore } from '_store/useUser.js'
const user = useUserStore()
const addFn = () => {
    user.getInfo()
} 
</script>
<style scoped lang='less'>
</style>

getter

  • 1.使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state

     getters: {
            sub: (state) => state.num + state.age
     }
    
  • 2.普通函数形式可以使用this

     sub() {
                return this.num + this.age
     }
    
  • 3.getters 互相调用

    ```js
    

    sub: (state) => state.num + state.age,
    sub1() {
    return this.num - this.age
    },
    number() {
    return this.sub + this.sub1
    }
    ```

持久化插件

  • 下载插件pinia-plugin-persist

     yarn add  pinia-plugin-persist
    
  • store下的index.js

    import { createPinia } from 'pinia'
    //pinia 持久化插件
    import piniaPluginPersist from 'pinia-plugin-persist'
    const store = createPinia()
    store.use(piniaPluginPersist)
    export default store
    
  • 在写的store.js文件下增加配置项 默认为sessionStorage

    import { defineStore } from 'pinia'
    //user为id是必传的
    const asyncFn = () => {
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve('info')
            }, 3000)
        })
    }
    export const useUserStore = defineStore('user', {
        state: () => {
            return {
                num: 1,
                age: 18,
                info: ''
            }
        },
        getters: {
            sub: (state) => state.num + state.age,
            sub1() {
                return this.num - this.age
            },
            number() {
                return this.sub + this.sub1
            }
        },
        persist: {
            enabled: true,
            strategies: [
                {
                    key: 'user',
                    storage: localStorage, //可选session
                    path: [] //可以选择保存的字段  其余的不保存
                }
            ]
        }
    })
    
    
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值