【精品】pinia详解

简介

pinia是最新一代的轻量级状态管理插。
优点:

  • 简便,存储和组件变得很类似,你可以轻松写出优雅的存储。
    = 类型安全,通过类型推断,可以提供自动完成的功能。
    = vue devtools 支持,可以方便进行调试。
    = Pinia 支持扩展,可以非常方便地通过本地存储,事物等进行扩展。
  • 模块化设计,通过构建多个存储模块,可以让程序自动拆分它们。
  • 非常轻巧,只有大约 1kb 的大小。
  • 服务器端渲染支持。
  • 完整的 ts 的支持;
  • 去除 mutations,只有 state,getters,actions;
  • actions 支持同步和异步;
  • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
  • 无需手动添加 store,store 一旦创建便会自动添加;
  • 支持Vue3 和 Vue2

安装配置

  • 安装命令:
npm install pinia -S
  • main.ts配置
import {createPinia} from 'pinia'

const store= createPinia()
app.use(store)

通过state修改

  • 在state/index.ts文件中编写:
import {defineStore} from "pinia"

export const useUserStore = defineStore('user', {
    state: () => {
        return {
            name:'',
            age: 0
        }
    }
})
  • Demo.vue
<template>
  {{ user .name }}------{{ user .age }}
  <br>
  <el-button type="primary" @click="user.age++">直接修改</el-button>
  <el-button type="primary" @click="fun1">批量修改</el-button>
  <el-button type="primary" @click="fun2">批量修改:函数式写法</el-button>
  <el-button type="primary" @click="fun3">修改所有的值</el-button>
</template>

<script setup lang="ts">
import {useUserStore} from "@/store";
const user = useUserStore()

const  fun1 = ()=>{
  //$patch方法可以批量修改多个值
  user.$patch({
    name:'张三',
    age:1234
  })
}
const  fun2 = ()=>{
  //此处可以编写业务逻辑(推荐使用)
  user.$patch((state)=>{
    if (state.name ==''){
      state.age =6666
    }else {
      state.age =8888
    }
  })
}
const  fun3 = ()=>{
  //$state:设置为新对象来替换store的整个状态。缺限:必须修改所有的值
  user.$state = {
    name:'zhangsan',
    age :3333
  }
}
</script>
  • 结果
    请添加图片描述

通过actions修改

在actions中可以做同步也可以做异步操作。
actions中的方法可以相互调用。

  • store/index.ts
import {defineStore} from "pinia"

export const useCountStore = defineStore('count', {
    state: () => {
        return {
            count: 0
        }
    },
    actions: {
        increment() {
            this.count++
        },
        setCount(p: number) {
            this.count = p
        },
        //异步操作
        decrement() {
            setTimeout(() => {
                this.count--
            }, 1000)
        },
        async sth(){
            const tmp = await 1234
            this.count = tmp
            this.setCount(7878)  //调用
        }
    }
})
  • Demo.vue
<template>
  {{ counter.count }}
  <br>
  <el-button type="primary" @click="fun1">借助actions修改</el-button>
  <el-button type="primary" @click="fun2">借助actions修改</el-button>
  <el-button type="primary" @click="counter.decrement">异步操作</el-button>
  <el-button type="primary" @click="counter.sth">异步操作</el-button>
</template>

<script setup lang="ts">
import {useCountStore} from "@/store";
const counter = useCountStore()
//借助actions修改
const fun1 = ()=>{
  counter.increment()
}
//借助actions修改
const fun2 = ()=>{
  counter.setCount(789)
}
</script>
  • 结果
    在这里插入图片描述

getters

不管调用多少次,getters中的函数只会执行一次,且都会缓存

  • store/index.ts
import {defineStore} from "pinia"

export const useCountStore = defineStore('count', {
    state: () => {
        return {
            count: 10
        }
    },
    getters: {
        //普通函数形式,可以使用this
        getCount(): number {
            return this.count
        },
        //箭头函数形式,不能使用this
        newCount: (state): number => {
            return state.count + 5
        },
        getDoubleCount(state): number {
            return state.count * 2 + this.getCount
        }
    }
})
  • Demo.vue
<template>
  {{counter.count}} <br>
  {{ counter.getCount }} <br>
  {{ counter.getCount }} <br>
  {{ counter.newCount }} <br>
  {{ counter.getDoubleCount }} <br>
</template>

<script setup lang="ts">
import {useCountStore} from "@/store";
const counter = useCountStore()
</script>
  • 结果
    在这里插入图片描述

解构对象

解构主要是针对Store中的state和getters.

示例一

  • store/index.js
import {defineStore} from "pinia"

export const useCountStore = defineStore('count', {
    state: () => {
        return {
            count: 10
        }
    },
    getters: {
        //普通函数形式,可以使用this
        getCount(): number {
            console.info("getCount")
            return this.count
        }
    },
    actions: {
        increment() {
            console.info("increment")
           this.count++
        }
    },
})
  • Demo.vue
<template>
  响应式:{{counter.count}} <br>
  属性解构后丧失响应式:{{ count }} <br>
  getters方法解构后丧失响应式:{{getCount}}
  <br>
  <el-button type="primary" @click="fun">属性解构后丧失响应式</el-button>
  <el-button type="primary" @click="increment">actions方法解构后不会丧失响应式</el-button>
</template>

<script setup lang="ts">
import {useCountStore} from "@/store";

const counter = useCountStore()
//解构
const {count, getCount, increment} = counter

const fun = () => {
  counter.count++
  //属性解构后丧失响应式
  console.info(count)
}
</script>
  • 效果
    请添加图片描述

示例二

  • store/index.js
import {defineStore} from "pinia"

export const useCountStore = defineStore('count', {
    state: () => {
        return {
            count: 10
        }
    },
    getters: {
        //普通函数形式,可以使用this
        getCount(): number {
            console.info("getCount")
            return this.count
        }
    },
    actions: {
        increment() {
            console.info("increment")
           this.count++
        }
    },
})
  • Demo.vue
<template>
  响应式:{{counter.count}} <br>
  属性解构后丧失响应式:{{ count }} <br>
  getters方法解构后丧失响应式:{{getCount}}
  <br>
  <el-button type="primary" @click="fun">属性解构后丧失响应式</el-button>
</template>

<script setup lang="ts">
import {useCountStore} from "@/store";
import {storeToRefs} from "pinia";

const counter = useCountStore()
//解构
const {count, getCount} = storeToRefs(counter)

const fun = () => {
  counter.count++
  //属性解构后丧失响应式
  console.info(count)
}
</script>
  • 效果
    请添加图片描述

pinia常用API

  • store/index.ts
import {defineStore} from "pinia"

export const useCountStore = defineStore('count', {
    state: () => {
        return {
            count: 10
        }
    },
    actions: {
        increment() {
            console.info("increment")
            this.count++
        }
    },
})
  • Demo.vue
<template>
  {{counter.count}}
  <br>
  <el-button type="primary" @click="counter.count++">自增</el-button>
  <el-button type="primary" @click="counter.increment()">actions:自增</el-button>
  <el-button type="primary" @click="counter.$reset()">重置状态数据到最终状态</el-button>
</template>

<script setup lang="ts">
import {useCountStore} from "@/store";
const counter = useCountStore()
//state发生改变时触发
counter.$subscribe((args,state)=>{
  console.info(args,state)
})

//监听actions中的方法
counter.$onAction(args=>{
  console.info(args)
  args.after(()=>{
    console.info("after")
  })
})
</script>
  • 结果
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁云亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值