Pinia新一代状态管理工具
Pinia 是 Vue.js 的轻量级状态管理库,是vuex的升级版
官方网站:Pinia | The intuitive store for Vue.js
中文文档: 介绍 | Pinia 中文文档
pinia与vuex的内容:
1.vuex的内容
●state
●mutations
●actions
●getters
●modules
●plugins
2.pinia的内容
●state
●actions
●getters
●modules
●plugins
小结
pinia基本使用
步骤
1安装 npm i pinia
2在main.js中use
3定义模块
4使用模块
在main.js中引入pinia
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')
定义模块:新建文件src/store/counter.js
import { defineStore } from 'pinia'
// 创建store,命名规则: useXxxxStore
// 参数1:store的唯一标识
// 参数2:回调函数,类似于setup()的功能,可以提供state actions getters
import { ref } from 'vue'
const useCounterStore = defineStore('counter', () => {
// 数据(state)
const count = ref(0)
// 修改数据的方法 (action)
const addCount = () => {
count.value++
}
// 以对象形式返回
return {count, addCount}
})
export default useCounterStore
使用模块
步骤:
- 在组件中引入模块
- 调用store函数得到store
- 使用store
<script setup>
// 1. 在组件中引入模块
import useCounterStore from '@/src/store/counter'
// 2. 调用store函数得到store
const counter = useCounterStore()
console.log(counter)
</script>
<template>
// 使用store
count: {{ counter.count }}
<button @click="counter.addCount">点击增加</button>
</template>
小结
1. 定义pinia的模块的函数是?它的第二个参数有什么特点?
defineStore,在函数中return出来数据和方法
2. 定义pinia的模块的函数是?它的第二个参数有什么特点?
defineStore,在函数中return出来数据和方法
pinia中getters的使用
pinia中的getters直接使用computed函数进行模拟,再把getters return出去.
定义getters(计算属性)
import { defineStore } from 'pinia'
// 创建store,命名规则: useXxxxStore
// 参数1:store的唯一表示
// 参数2:回调函数,类似于setup()的功能,可以提供state actions getters
import { ref, computed } from 'vue'
const useCounterStore = defineStore('counter', () => {
// 数据(state)
const count = ref(0)
// 修改数据的方法 (action)
const addCount = () => {
count.value++
}
// 计算属性
const doubleCount = computed(() => count.value * 2)
// 以对象形式返回
return {count, addCount, doubleCount}
})
export default useCounterStore
在组件中使用
<script setup>
import useCounterStore from '@/stores/counter.js'
const counterStore = useCounterStore()
console.log(counterStore)
</script>
<template>
<div>
{{ counterStore.doubleCount }}
<button @click="counterStore.addCount">+1</button>
count: {{ counterStore.count }}
</div>
</template>
小结
1. 如何理解pinia的getters?
就是computed
pinia中异步actions的使用
新建一个store来实现
import { defineStore } from 'pinia'
import { ref } from 'vue'
import axios from 'axios'
export default defineStore('newList', () => {
const list = ref([])
const getList = async () => {
const res = await axios.get('http://api-toutiao-web.itheima.net/mp/v1_0/channels')
list.value = res.data.data.channels
}
return { list, getList }
})
在组件中使用
<script setup>
import useCounterStore from '@/stores/counter.js'
const counterStore = useCounterStore()
import useNewsListStore from '@/stores/newsList.js'
import { onMounted } from 'vue';
const newsListStore = useNewsListStore()
onMounted(() => {
newsListStore.getList()
})
</script>
<template>
<div>
{{ counterStore.doubleCount }}
<button @click="counterStore.addCount">+1</button>
count: {{ counterStore.count }}
{{ newsListStore.list }}
</div>
</template>
小结
1. pinia中有类似于vuex的mutations和action的概念吗?
没有,它就是提供了函数来修改数据,而不在意这个函数是同步的还是异步的。合并了原vuex中的action和mutation的概念
用storeToRefs来优化pinia的使用
问题
在模板中使用数据时,要加上模块的名字,例如:
<template>
<h1>根组件---{{ counter.count }}</h1>
<h3>{{ counter.double }}</h3>
</template>
思考:上面代码中的counter 可以省略么?用解构赋值?
结论:如果直接从pinia中解构数据,会丢失响应式。
const counterStore = useCounterStore()
// 这样的count没有响应式效果
const { count } = counterStore
console.log(count, addCount)
storeToRefs
使用storeToRefs可以保证解构出来的数据(state + getter)也是响应式的。注意: 不要对action
const { state属性名1, state属性名2 } = storeToRefs(模块名)
进行结构
测试使用
<script setup>
import { storeToRefs } from 'pinia'
import useCounterStore from './store/counter'
const counter = useCounterStore()
// 如果直接从pinia中解构数据,会丢失响应式
const { count, double } = counter
// 使用storeToRefs可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
</script>
持久化
有现成的第三方插件可以使用
Why this plugin ? | pinia-plugin-persistedstate
1.安装 : npm i pinia-plugin-persistedstate
2.配置:main.js
import { createPinia } from 'pinia'
// 引入持久化插件
import piniaPluginPersist from 'pinia-plugin-persistedstate'
const store = createPinia()
// 使用该插件
store.use(piniaPluginPersist)
app.use(store)
3.在某个store中使用
const useCounterStore = defineStore('counter', () => {
// 以对象形式返回
return {count, addCount, doubleCount}
},{
persist: {
key: 'my-custom-key' // 持久化使用的属性名,默认是 store.$id
storage: sessionStorage, // 默认是localStorage
paths: ['list', 'type'], // 要持久化的属性
}
})