安装
npm i pinia
引入pinia
import {createPinia} from 'pinia'
const store = createPinia()
app.use(store)
我们需要知道存储是使用定义的defineStore()
,并且它需要一个唯一的名称,作为第一个参数传递
抽离出去了
export const enum Names {
Test = 'TEST'
}
创建文件夹 store
import { defineStore } from 'pinia'
import { Names } from './store-namespace'
export const useTestStore = defineStore(Names.Test, {
// state是一个函数 这里定义初始值
state:() => {
return {
count: 1,
age: 20,
name: '张三',
gender: '男'
}
},
// 类似computed 可以帮我们修饰我们的值
getters: {
},
// 可以操作异步和同步提交state
actions: {
}
})
state
state是允许修改值的
<template>
<p>{{store.count}}</p>
<button @click="add">修改store</button>
</template>
<script setup lang='ts'>
import { useTestStore } from './store/index'
const store = useTestStore()
const add = () => {
store.count++
}
</script>
<style scoped>
</style>
修改多个属性
state通过$patch可以同时修改多个state
<template>
<p>{{store.count}}</p>
<p>{{store.age}}</p>
<p>{{store.gender}}</p>
<p>{{store.name}}</p>
<button @click="add">修改store</button>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
import { useTestStore } from './store/index'
const store = useTestStore()
const add = () => {
// $patch 可以修改多个store值
// store.$patch({
// count: 100,
// age: 22,
// gender: '女',
// name: '李四'
// })
// 批量修改函数写法 推荐这种写法
store.$patch((state) => {
state.count++,
state.age = 22,
state.gender = '女',
state.name = '李四'
})
}
</script>
<style scoped>
</style>
通过原始对象修改整个实例
$state
您可以通过将store的属性设置为新对象来替换store的整个状态
但是缺点就是必须修改整个对象的所有属性
<template>
<p>{{store.count}}</p>
<p>{{store.age}}</p>
<p>{{store.gender}}</p>
<p>{{store.name}}</p>
<button @click="add">修改store</button>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
import { useTestStore } from './store/index'
const store = useTestStore()
const add = () => {
//通过$state修改store必须修改state里面的全部属性
store.$state = {
count: 200,
age: 22,
gender: '女',
name: '李四'
}
}
使用actions修改
定义actions
import { defineStore } from 'pinia'
import { Names } from './store-namespace'
export const useTestStore = defineStore(Names.Test, {
// state是一个函数 这里定义初始值
state:() => {
return {
count: 1,
age: 20,
name: '张三',
gender: '男'
}
},
// 类似computed 可以帮我们修饰我们的值
getters: {
},
// 可以操作异步和同步提交state
actions: {
setCount() {
this.count ++
}
}
})
在组件中直接使用
<template>
<p>{{store.count}}</p>
<p>{{store.age}}</p>
<p>{{store.gender}}</p>
<p>{{store.name}}</p>
<button @click="add">修改store</button>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
import { useTestStore } from './store/index'
const store = useTestStore()
const add = () => {
store.setCount()
}
</script>
<style scoped>
</style>
解构store
在pinia中是不能使用解构的,因为会失去响应式
let { age, gender, name, count } = store
解决方法:使用storeToRefs
import { storeToRefs} from 'pinia'
let { age, gender, name, count } = storeToRefs(store)
actions
同步
直接调用
import { defineStore } from 'pinia'
import { Names } from './store-namespace'
export const useTestStore = defineStore(Names.Test, {
// state是一个函数 这里定义初始值
state:() => {
return {
count: 1,
age: 20,
name: '张三',
gender: '男'
}
},
// 类似computed 可以帮我们修饰我们的值
getters: {
},
// 可以操作异步和同步提交state
actions: {
setCount() {
this.count ++
}
}
})
template
<template>
<p>{{store.count}}</p>
<p>{{store.age}}</p>
<p>{{store.gender}}</p>
<p>{{store.name}}</p>
<button @click="add">修改store</button>
</template>
<script setup lang='ts'>
import { useTestStore } from './store/index'
const store = useTestStore()
const add = () => {
store.setCount()
}
</script>
<style scoped>
</style>
异步
使用async await 修饰符
import { defineStore } from 'pinia'
import { Names } from './store-namespace'
type Result = {
name: string
isChu: boolean
}
const login = (): Promise<Result> => {
return new Promise((resolve, reject) =>{
setTimeout(() => {
resolve({
name: '李四',
isChu: true
})
}, 3000)
})
}
export const useTestStore = defineStore(Names.Test, {
// state是一个函数 这里定义初始值
state:() => {
return {
user:<Result>{},
count: 1,
age: 20,
name: '张三',
gender: '男'
}
},
// 类似computed 可以帮我们修饰我们的值
getters: {
},
// 可以操作异步和同步提交state
actions: {
async getLoginInfo() {
const res = await login()
this.user = res
}
}
})
template
<template>
<p>{{store.count}}</p>
<p>{{store.age}}</p>
<p>{{store.gender}}</p>
<p>{{store.name}}</p>
<div>{{store.user}}</div>
<button @click="add">修改store</button>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
import { storeToRefs} from 'pinia'
import { useTestStore } from './store/index'
const store = useTestStore()
const add = () => {
store.getLoginInfo()
}
</script>
<style scoped>
</style>
getters
注意:使用箭头函数时不能够使用this this只想已经改变指向undefined 修改值使用state
主要作用类似于computed 数据修饰并且有缓存
getters: {
newPrice:(state)=> `$${state.age}`
},
普通函数可以使用this
getters: {
newCurrent ():number {
return ++ this.count
}
},
API
$reset 重置
重置state的状态到初始值
state:() => {
return {
user:<Result>{},
count: 1,
age: 20,
name: '张三',
gender: '男'
}
},
在组件中把state的count属性修改为200, 调用$reset回回到初始的 1
store.count = 200
store.$reset()