目录
一.为什么要使用 Pinia?
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。 如果您熟悉 Composition API,您可能会认为您已经可以通过一个简单的 export const state = reactive({})
. 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,会使您的应用程序暴露于安全漏洞。 但即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:
- dev-tools 支持
- 跟踪动作、突变的时间线
- Store 出现在使用它们的组件中
- time travel 和 更容易的调试
- 热模块更换
- 在不重新加载页面的情况下修改您的 Store
- 在开发时保持任何现有状态
- 插件:使用插件扩展 Pinia 功能
- 为 JS 用户提供适当的 TypeScript 支持或 autocompletion
- 服务器端渲染支持
二.安装
1.用你最喜欢的包管理器安装 pinia
:
yarn add pinia
//# 或者使用 npm
npm install pinia
提示
如果您的应用使用 Vue 2,您还需要安装组合 API:@vue/composition-api
。 如果您使用 Nuxt,则应遵循 这些说明。
2.引用
创建一个 pinia(根存储)并将其传递给应用程序:
/在main.js中引入
import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia).mount('#app')
三.定义一个 Store
1.在深入了解核心概念之前,我们需要知道 Store 是使用 defineStore()
定义的,并且它需要一个唯一名称,作为第一个参数传递:
在user.js中创建并暴露:
//在user.js中
import { defineStore } from 'pinia'
// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
const useStore = defineStore('main', {
// other options...
})
//默认暴露
export default useStore
在index.js中引入:
//在index.js中引入并统一暴露出去
import useStore from './modules/user'
export {
useStore
}
在页面使用时引入index.js中相应的store,并使用:
import {useStore} from '../store'
const store = useStore()
console.log(store);
四.添加数据到store
1.大多数时候,state 是 store 的核心部分。 我们通常从定义应用程序的状态开始。 在 Pinia 中,状态被定义为返回初始状态的函数。 Pinia 在服务器端和客户端都可以工作。
const useStore = defineStore('user', {
// other options...
state:()=>{
return {
name:'张三',
age:123,
school:{
teacher:'罗翔',
hobby:'判刑'
}
}
}
})
五.在页面上渲染
上述内容有点繁琐,可以通过解构来简化:
注:修改数据时千万不能直接修改解构后的值,要修改store上的值
<template>
<div>
<h1>home</h1>
<h1>{{name}}</h1>
<h1>{{age}}</h1>
<h1>{{school}}</h1>
</div>
</template>
<script setup>
import {useStore} from '../store'
const store = useStore()
//解构简化
const {name,age,school} = store
console.log(store);
</script>
六.pinia的数据处理
6.将数据改变为响应式
//方法一
import { storeToRefs } from 'pinia'
const store = useStore()
const {name,age,school} = storeToRefs(store)
//方法二
import {toRefs} from 'vue'
const store = useStore()
const {name,age,school} = toRefs(store)
6.1重置数据
store.$reset()
6.2批量修改数据
注:按照原来数据类型进行替换,一样则换,不一样就不换
store.$patch({
name:'王五',
age:33,
school:{
teacher:'麻子'
}
})
6.3批量修改数据
//传一个箭头函数,state就是store数据
store.$patch((state)=>{
console.log(state);
state.name = "罗翔"
})
6.4直接替换整个state
//测试时也是局部替换,但是可以(完全替换)里面的数据
store.$state = {
name:'杨七'
}
七.Getters语法
Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore()
中的 getters
属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用:
注:计算属性必须有返回值
getters:{
// 自动将返回类型推断为数字 普通函数
doubleCount(state) {
console.log('state=>',state);
return state.counter * 2+5
},
// 箭头函数中的this不可以用,可以用state参数
doubleCount2:(state)=>{
return 5 + state.doubleCount
},
// this写法
doubleCount2(state){
return 5+this.doubleCount
}
}
在页面渲染
//使用store.属性名
<template>
<p>Double count is {{ store.doubleCount }}</p>
</template>
八.Actions语法
Actions 相当于组件中的 methods。 它们可以使用 defineStore()
中的 actions
属性定义,并且它们非常适合定义业务逻辑:
//actions中没有state参数,数以不要用箭头函数
actions:{
changeAge(a){
console.log(a,'a');
},
//这个函数this.changeAge()最后执行
async too(){
let num = await 999
this.age = num
this.changeAge()
}
}
注:如果想在actions使用箭头函数,但是this指向有问题,可以从页面将store当参数传递过去,
然后用state接收
调用:调用用store.方法名
store.changeAge(1)