vue3的pinia详解

引入pinia

安装pinia

cnpm install pinia --save

main.js

import {createPinia} from "pinia"

const pinia=createPinia()

app.use(pinia)

state

state是store的核心部分

创建store仓库【src/store/count.js】

选项式

     import { defineStore } from "pinia"
            //模块命名规则:use+关键功能+Store
            //defineStore:参数1:命名  参数2:对象
            export const useConutStore = defineStore("count", {
                //state必须是函数类型
                state: () => {
                    return {
                        count:20
                    }
                }
            })

组合式

   import { defineStore } from "pinia"
            import {ref,reactive} from "vue"
            //模块命名规则:use+关键功能+Store
            //组合式API优势:不需要引入state
            export const useConutStore = defineStore("count", ()=>{
                const count=ref(200)
                const userInfo=reactive({
                    name:"wkj"
                })  
                return {
                    count,
                    userInfo
                }
            })

访问 “state”

【组合式API】

   <template>
             <p>Count1:{{ count }}</p>
          </template>
          <script setup>
          import { useCountStore } from "../store/count"
          const { count } = useCountStore();
          </script>
          

【选项式API】

   <template>
             <p>Count1:{{ count }}</p>
             <p>Count2:{{ doubleCount }}</p>
          </template>
          <script>
          import { mapState } from "pinia"
          import { useCountStore } from "../store/count"
          export default {
            computed:{
              ...mapState(useCountStore,{
                myOwnName:"count",
                count:store => store.count,
                doubleCount(store){
                  return store.count * 2
                 }
               })
             }
          }
          </script>

修改 “state”

在 pinia 中修改状态要比在 vuex 中修改状态简单的多,因为不用引入额外的概念,直接用 store.counter++ 修改 store

组合式API

     import { useCountStore } from "../store/count"
        const store = useCountStore();
        function updateClick(){
          store.count++
        }

选项式API

  import { mapState,mapWritableState  } from "pinia"
        import { useCountStore } from "../store/count"
        export default {
          computed:{
            ...mapState(useCountStore,{
              myOwnName:"count",
              count:store => store.count,
              doubleCount(store){
                return store.count * 2
               }
             }),
            ...mapWritableState(useCountStore,["count"])
           },
          methods:{
            updateClick(){
              this.count++
             }
           }
        }
        

Getters

Getter 完全等同于 Store 状态的计算值

创建store仓库【src/store/count.js】

  import { defineStore } from "pinia"
            export const useCountStore = defineStore("count",{
              state:() =>{
                return{
                  count:10
                 }
               },
              getters:{
                getCount:(state) => "当前Count:"+ state.count
               }
            })
             

访问 Getters

组合式API

  <template>
            <p>{{ store.getCount }}</p>
          </template>
          <script setup>
          import { useCountStore } from "../store/count"
          const store = useCountStore();
          </script>

选项式API

  <template>
            <p>{{ getCount }}</p>
          </template>
          <script setup>
          import { mapState  } from "pinia"
          import { useCountStore } from "../store/count"
          export default {
            computed:{
              ...mapState(useCountStore,["getCount"])
             }
          }
          </script>
          

访问其他 Getter

  getters:{
                getCount:(state) => "当前Count:"+ state.count,
                  doubleCount(state){
                  return this.getCount + state.count
                 }
              }

Actions

Actions 相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑

创建store仓库【src/store/count.js】


            import { defineStore } from "pinia"
            export const useCountStore = defineStore("count", {
              state: () => {
                return {
                  count: 10
                 }
               },
              getters: {
                getCount: (state) => "当前Count:" + state.count,
                doubleCount(state) {
                  return this.getCount + state.count
                 }
               },
              actions: {
                increment() {
                  this.count++
                 },
                decrement() {
                  this.count--
                 }
               }
            })

读取Actions

组合式API

    <template>
                <h3>Pinia</h3>
                <p>Count1:{{ store.count }}</p>
                <button @click="addCountHandler">增加</button>
                <button @click="minCountHandler">减少</button>
            </template>
            <script setup>
              import { useCountStore } from "../store/count"
              const store = useCountStore();
              function addCountHandler(){
                store.increment()
              }
              function minCountHandler(){
                store.decrement()
              }
            </script>

选项式API

 <template>
                <h3>Pinia</h3>
                <p>Count1:{{ store.count }}</p>
                <button @click="addCountHandler">增加</button>
                <button @click="minCountHandler">减少</button>
            </template>
            <script>
              import { mapState,mapActions } from "pinia"
              import { useCountStore } from "../store/count"
              
              
              export default {
                computed:{
                  ...mapState(useCountStore,{
                    myOwnName:"count",
                    count:store => store.count,
                    doubleCount(store){
                      return store.count * 2
                     }
                   })
                 },
                methods:{
                  ...mapActions(useCountStore,["increment","decrement"]),
                  addCountHandler(){
                    this.increment()
                   },
                  minCountHandler(){
                    this.decrement()
                   }
                 }
              }
            </script>

异步操作

actions 可以是异步的,这也是使用 actions 最大的原因

  import { defineStore } from "pinia"
            import axios from "axios"
            export const useBannerStore = defineStore("banner", {
              state: () => {
                return {
                  banner:[]
                 }
               },
              actions: {
                setBanner(url){
                  axios.get(url)
                   .then(res =>{
                    this.banner = res.data.banner
                   }).catch(error =>{
                    console.log(error);
                   })
                 }
               }
            })
            

             <template>
             <h3>网络请求</h3>
             <ul>
              <li v-for="(item,index) in store.banner" :key="index">
               <h3>{{ item.title }}</h3>
               <p>{{ item.content }}</p>
              </li>
             </ul>
             </template>
             <script setup>
              import { onMounted } from "vue"
              import { useBannerStore } from "../store/banner"
              const store = useBannerStore();
              onMounted(() =>{
                store.setBanner("http://iwenwiki.com/api/blueberrypai/getIndexBanner.php")
              })
              </script>

解构赋值响应式

直接从 pinia 中解构赋值,操作的时候会发现,内容根本不会发生变化,因为直接从 pinia 中解构数据失去了响应式

我们可以用 storeToRefs 来解决找个问题


            import { storeToRefs } from "pinia";
            import { useCountStore } from "../store/count";
            const store = useCountStore();
            const { count } = storeToRefs(store)
            function addCountHandler(){
              store.increment(5)
            }
            function minCountHandler(){
              store.decrement(5)
            } 

Pinia热更新

pinia 支持热模块替换,因此你可以编辑store,并直接在您的应用程序中与它们交互,而无需重新加载页面,允许您保持现有的状态,添加,甚至删除state,action和getter

    import { defineStore, acceptHMRUpdate } from "pinia"
            import axios from "axios"
            
            
            export const useCountStore = defineStore("count", {
              state: () => {
                return {
                  count: 10
                 }
               },
              getters: {
                getCount: (state) => "当前Count:" + state.count
               }
            })
            
            
            if (import.meta.hot) {
              import.meta.hot.accept(acceptHMRUpdate(useCountStore, import.meta.hot))
            }
             

数据持久化插件

安装pinia数据持久化插件

cnpm install --save pinia-plugin-persist

main.js

import piniaPersist from 'pinia-plugin-persist'

pinia.use(piniaPersist)

编写stores/loginStore.js

   import { defineStore } from "pinia"
  
            export const useLoginStore = defineStore("login", {
                state: () => {
                    return {
                        token:false,//登录的token
                        username: "",//用户名
                        permissions:''//用户权限
                    }
                },
                //本地持久化(把数据存储到浏览器本地)
                persist: {
                    enabled: true,//是否开启持久化
                    strategies: [
                        {
                            key: 'login', //自定义Key值,存储到本地时的key
                            storage: localStorage, // 选择存储方式:本地存储
                        },
                    ],
                }
            }) 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

月木@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值