您现在的位置是:首页 >技术教程 >pinia的使用网站首页技术教程
pinia的使用
                简介pinia的使用            
            介绍
- 一个拥有组合式 API 的 Vue 状态管理库
 - 主要是面向 Vue 3 的用户,除了安装和 SSR 两章之外,其余章节中提到的 API 均支持 Vue 2 和 Vue
 - Devtools 支持,追踪 actions、mutations 的时间线,在组件中展示它们所用到的 Store,让调试更容易的 Time travel
 - 热更新。不必重载页面即可修改 Store,开发时可保持当前的 State
 - 插件:可通过插件扩展 Pinia 功能
 - 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能。
 - 支持服务端渲染
 
对比 Vuex
- 与 Vuex 相比,Pinia 提供了一个更简单的 API,mutation 已被弃用
 - 提供了符合组合式 API 风格的 API,也可使用选项式API
 - 搭配 TypeScript 一起使用时有非常可靠的类型推断支持
 - Pinia 从设计上提供的是一个扁平的结构,不再有嵌套结构的模块,不再有可命名的modules。但可以通过导入和使用另一个 Store 来隐含地嵌套 stores 空间。
 
使用
yarn add pinia 
npm install pinia 
----------------------------------
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
 
定义store文件
- 在store文件夹下新建user.js
 - defineStore定义一个store 
  
- 第一个参数是你的应用中 Store 的唯一 ID
 - 第二个参数可接受两类值:Setup 函数或 Option 对象
 - 仓库最好使用 store 的名字,同时以 
use开头且以Store结尾。(比如useUserStore,useCartStore,useProductStore) 
 
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
})
 
Option Store 类似选项式API
export const useUserStore = defineStore('User', {
  state: () => {
    return {
      count: 0, // 所有这些属性都将自动推断出它们的类型
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2,
    doubleCountPlus() { 
      return this.doubleCount + 1
    },
  },
  actions: {
    increment() {
      this.count++
    },
  },
})
 
Setup Store 类似组合式API 的 setup 函数
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }
  return { count, increment }
})
 
使用 Store
- store 是一个用 reactive 包装的对象,所以使用方式和reactive对象一样
 
<script setup>
import { useUserStore } from '@/store/user' 
const userStore= useUserStore()
// ------------使用变量------
// userStore 是一个用 reactive 包装的对象
let count = userStore.count
// 所以reactive对象的属性不具有响应式,所以不能解构直接使用
// 若想解构,先将它每一个属性转化为响应式,类似roRefs()
import { storeToRefs } from 'pinia'
const { name, doubleCount } = storeToRefs(userStore)
// ----------使用方法---------
userStore.increment() 
//或者解构:actions 的 increment 方法可以直接解构
const { increment } = userStore
increment()
</script>
 
修改state的三种方法
- 直接在页面组件中改变数据
 - 使用$patch改变数据 
  
- patch object:是通过我们熟悉的 $patch 的 对象方式 来变化
 - patch function:也是通过 $patch,但是是通过 函数的方式 来变化
 
 - direct:通过 action 变化
 - 重置数据
 
<template>
  <div>baseUrl:{{ baseUrl }}</div>
  <div>ipList:{{ ipList }}</div>
  <button @click="changeData">直接在页面组件中改变数据</button>
  <button @click="changeDataByPatch">使用$patch改变数据</button>
  <button @click="changeDataByAction">使用action改变数据</button>
  <button @click="resetData">重置数据</button>
</template>
 
<script setup>
import useAppStore from "@/store/modules/app"
import { storeToRefs } from "pinia"
const store = useAppStore()
let { baseUrl, ipList } = storeToRefs(store)
/* 第一种修改方式:虽然可以直接修改,但是出于代码结构来说,
*               全局的状态管理还是不要直接在各个组件处随意修改状态,
*               应放于 action 中统一方法修改(piain没有mutation)
*               并不推荐!!!
* */
function changeData() { 
  store.baseUrl = 'https://www.taobao.com/'  
  store.ipList.push('192.168.10.111')  
}
/*第二种修改方式:使用$patch改变数据, $patch 可以同时修改多个值
 *  $patch也有两种的调用方式
 *  第一种写法的在修改数组时,假如我只想修改 ipList 的中第2项 , 也需要传入整个数组, 所以一般都推荐使用第二种传入一个函数的写法
 */
function changeDataByPatch() {
  // 第一种 $patch方法
  store.$patch({
     baseUrl: 'https://www.jd.com/',
     ipList: ['192.168.10.777', '192.168.10.222', '192.168.10.888']
  })
  // 第二种 $patch方法
  store.$patch((state) => {
    state.baseUrl = 'https://www.jd.com/'
    state.ipList[1] = '192.168.10.222'
  })
}
// 第三种修改方式:调用store中的action改变数据的方法changeState
function changeDataByAction() {
  store.changeState('https://www.alibabagroup.com/cn/global/home')  //可以直接给actions里面的方法传递参数
}
// 重置数据
function resetData() {
  store.$reset()
}
</script>
 
订阅$subscribe:监听 state 里面的值是否发生了变化
cartStore.$subscribe((mutation, state) => {
  console.log(mutation, state)
  // mutation.type //发生改变的三种方式: 'direct' | 'patch object' | 'patch function' 
  // mutation.storeId // store名字
  // mutation.payload // 传递给 cartStore.$patch() 的对象。只有 mutation.type === 'patch object'的情况下才可用
  // 每当状态发生变化时,将整个 state 持久化到本地存储。
  localStorage.setItem('cart', JSON.stringify(state))
})
//subscription 会被绑定到添加它们的组件上 ,当该组件被卸载时,它们将被自动删除。如果想保留,设置 { detached: true } ,以将 state subscription 从当前组件中分离
cartStore.$subscribe(callback, { detached: true })
 
当前 getter 访问其他 store 的 getter
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
  getters: {
    otherGetter(state) {
      const otherStore = useOtherStore()
      return state.localData + otherStore.data
    },
  },
})
 
订阅 action
const unsubscribe = someStore.$onAction(
  ({
    name, // action 名称
    store, // store 实例,类似 `someStore`
    args, // 传递给 action 的参数数组
    after, // 在 action 返回或解决后的钩子
    onError, // action 抛出或拒绝的钩子
  }) => {
    // 为这个特定的 action 调用提供一个共享变量
    const startTime = Date.now()
    // 这将在执行 "store "的 action 之前触发。
    console.log(`Start "${name}" with params [${args.join(', ')}].`)
    // 这将在 action 成功并完全运行后触发。
    // 它等待着任何返回的 promise
    after((result) => {
      console.log(
        `Finished "${name}" after ${
          Date.now() - startTime
        }ms.
Result: ${result}.`
      )
    })
    // 如果 action 抛出或返回一个拒绝的 promise,这将触发
    onError((error) => {
      console.warn(
        `Failed "${name}" after ${Date.now() - startTime}ms.
Error: ${error}.`
      )
    })
  }
)
// 手动删除监听器
unsubscribe()
// 此订阅器即便在组件卸载之后仍会被保留
someStore.$onAction(callback, true)
                风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。
        
    
        
    
            




U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结