实习闲余——对Pinia的整理和学习

Pinia学习
1.什么是pinia
  • Pinia 是一个用于 Vue 的状态管理库,类似 Vuex, 是 Vue 的另一种状态管理方案。
2.pinia的特点
  • 完整的 ts 的支持;
  • 足够轻量,压缩后的体积只有1kb左右;
  • 去除 mutations,只有 state,getters,actions;
  • actions 支持同步和异步;
  • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
  • 无需手动添加 store,store 一旦创建便会自动添加;
  • 支持Vue3 和 Vue2

官方文档:Pinia

3.安装
yarn add pinia

npm install pinia --save
4.引入注册Vue3
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')
初始化仓库Store
1.新建一个文件夹Store
2.在文件夹中新建index.ts
3.定义store仓库
  • 首先,import { defineStore } from ‘pinia’
  • 我们需要知道存储是使用定义的defineStore(),并且它需要一个唯一的名称,作为第一个参数传递。
  • 所以我们需要新建文件store-namespace.ts
export const enum Names {
Test = 'TEST'
}

store引入

import { defineStore } from 'pinia'
import { Names } from './store-namespce'
 
export const useTestStore = defineStore(Names.Test, {
})
4.定义值

State 是个箭头函数 返回一个对象 在对象里面定义值

import { defineStore } from 'pinia'
import { Names } from './store-namespce'
 
export const useTestStore = defineStore(Names.Test, {
     state:()=>{
         return {
             current:1
         }
     }
})

其他的属性:

import { defineStore } from 'pinia'
import { Names } from './store-namespce'
 
export const useTestStore = defineStore(Names.Test, {
     state:()=>{
         return {
             current:1
         }
     },
     //类似于computed 可以帮我们去修饰我们的值
     getters:{
 
     },
     //可以操作异步 和 同步提交state
     actions:{
 
     }
})
修改state的五种方法

App.vue:

<template>
    <div>
        pinia---{{ Test.current }}-----{{ Test.name }}
        <button @click="change">点我</button>
    </div>
</template>
<script setup lang="ts">
import { userTest } from './store';
const Test = userTest()
const change = () => {
    // 第一种修改数据
    // Test.current++
    // 第二种修改
    // Test.$patch({
    //     current: 888,
    //     name: '玩玩'
    // })
    // 第三种修改   通过一个工厂函数处理一些逻辑
    // Test.$patch((state) => {
    //     state.current = 999
    //     state.name = 'asdasd'
    // })
    // 第四种修改     这里必须把所有属性写上
    // Test.$state = {
    //     current: 888,
    //     name: '虾米那'
    // }
    // 第五种   通过actions修改
    // Test.setCurrent(567)
}
</script>
<style lang="less" scoped>
</style>

store文件中index.js:

import { defineStore } from "pinia";
import { Names } from "./store-name";
export const userTest = defineStore(Names.TEST, {
    state: () => {
        return {
            current: 2,
            name: '小满'
        }
    },
    // 相当于计算属性  修饰一些值
    getters: {
    },
    // 相当于methods 可以做同步异步操作,提交state
    actions: {
        setCurrent(num: number) {
            this.current = num
        }
    }
})
pinia 解构出的参数和vuex一样不具有响应式,解决方案可以使用 storeToRefs
import { storeToRefs } from 'pinia'
 
const Test = useTestStore()
 
const { current, name } = storeToRefs(Test)

其原理跟toRefs 一样的给里面的数据包裹一层toref,源码 通过toRaw使store变回原始数据防止重复代理,循环store 通过 isRef isReactive 判断 如果是响应式对象直接拷贝一份给refs 对象 将其原始对象包裹toRef 使其变为响应式对象 。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NKgAd9FE-1656491381007)(en-resource://database/558:1)]

actions和getters的使用
Actions(支持同步异步)
  • 1.同步 直接调用即可
    index.js:
import { defineStore } from 'pinia'
import { Names } from './store-naspace'
export const useTestStore = defineStore(Names.TEST, {
    state: () => ({
        counter: 0,
    }),
    actions: {
        increment() {
            this.counter++
        },
        randomizeCounter() {
            this.counter = Math.round(100 * Math.random())
        },
    },
})

app.vue:

<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.counter}}
          </div>    
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {
     Test.randomizeCounter()
}
 
</script>
 
<style>
 
</style>
  • 2.异步 可以结合async await 修饰
    index.js :
import { defineStore } from 'pinia'
import { Names } from './store-naspace'
 
type Result = {
    name: string
    isChu: boolean
}
 
const Login = (): Promise<Result> => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({
                name: '小满',
                isChu: true
            })
        }, 3000)
    })
}
 
export const useTestStore = defineStore(Names.TEST, {
    state: () => ({
        user: <Result>{},
        name: "123"
    }),
    actions: {
        async getLoginInfo() {
            const result = await Login()
            this.user = result;
        }
    },
})

app.vue:

<template>
     <div>
         <button @click="Add">test</button>
          <div>
             {{Test.user}}
          </div>    
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {
     Test.getLoginInfo()
}
 
</script>
 
<style>
 
</style>

getters
1.使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state。
主要作用类似于computed 数据修饰并且有缓存

    getters:{
       newPrice:(state)=>  `$${state.user.price}`
    },

2.普通函数形式可以使用this

    getters:{
       newCurrent ():number {
           return ++this.current
       }
    },
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值