前端学习-vue视频学习013-pinia
了解pinia
集中式状态(数据)管理的工具,主要管理各组件之间的共享数据
准备一个效果
学到的几个点
- html下拉选择框,可以使用v-model双向绑定
- v-modle获取的值为字符串,可以写为v-model.number,会尽量转为数字
<select name="num" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
- 随机获取id的方式有uuid和nanoid,需要
npm i nanoid
,import引入后使用
<script setup name="LoveTalk" lang="ts">
import { reactive } from 'vue';
import axios from 'axios';
import { nanoid } from 'nanoid'
let talkList = reactive([
{id:'talk01',title:'asdfghjkl'},
{id:'talk02',title:'awejdfaaff'},
{id:'talk03',title:'irjeqirh'},
{id:'talk04',title:'ljfdkjfdf'},
])
async function getTalk() {
// 连续解构赋值+重命名
let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?fomat=json')
let obj = {id:nanoid(),title}
talkList.unshift(obj)
}
</script>
搭建pinia环境
- 安装pinia
npm i pinia
- 引入、创建、安装pinia
// 引入createApp创建应用
import { createApp } from "vue";
// 引入APP根组件
import App from './App.vue'
// 引入pinia
import { createPinia } from "pinia";
// 引入路由器
// import router from "./router";
// 创建一个应用
const app = createApp(App)
// 创建pinia
const pinia = createPinia()
// 使用路由器
// app.use(router)
// 安装pinia-要在应用挂载前 否则报错
app.use(pinia)
// 挂载应用到app容器
app.mount('#app')
读取、存储、修改数据
读取+存储
- 在src中新建文件夹store,专门用于存放pinia数据
- 新建ts文档,将要用到的数据存放在里面
import { defineStore } from "pinia";
export const useCountStore = defineStore('count',{
// state是真正存储数据的地方
state(){
return {
sum:6
}
}
})
- 读取/使用存放着pinia的数据
<template>
<div class="count">
<h2>求和:{{ countPinia.sum }}</h2>
</div>
</template>
<script setup name="Count" lang="ts">
import { ref } from 'vue';
import { useCountStore } from '@/store/count'
let countPinia = useCountStore()
</script>
修改数据的三种方式
方式1:直接操作数据
function add() {
// 方式1
CountStore.sum += n.value
// sum.value += n.value
}
方式2:批量修改数据
function add() {
// 方式1
// CountStore.sum += n.value
// 方式2
CountStore.$patch({
sum:888,
title:'aaa'
})
// sum.value += n.value
}
方式3:使用actions,在其中放置方法,对应响应组件中的动作
- 使用actios
store/talk.ts
import { defineStore } from "pinia";
import axios from "axios";
import { nanoid } from 'nanoid'
export const useTalkStore = defineStore('talk',{
actions:{
async addList() {
// 连续解构赋值+重命名
let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?fomat=json')
let obj = {id:nanoid(),title}
// talkStore.talkList.unshift(obj)
this.talkList.unshift(obj)
}
},
// state是真正存储数据的地方
state(){
return {
talkList:[
{id:'talk01',title:'asdfghjkl'},
]
}
}
})
- 使用actions定义的方法
Talk.vue
<script setup name="LoveTalk" lang="ts">
import { useTalkStore } from '@/store/talk'
let talkStore = useTalkStore()
// let talkList = reactive([
// {id:'talk01',title:'asdfghjkl'},
// ])
function getTalk() {
talkStore.addList()
}
</script>
storeToRefs
在解构数据时,会遇到失去响应式的情况
通常使用toRefs解决
但在pinia中,如果直接使用toRefs 会出现所有数据、方法都获取到的情况
因此pinia提供storeToRefs,只会取到数据
<template>
<div class="count">
<h2>求和:{{ sum }}</h2>
</div>
</template>
<script setup name="Count" lang="ts">
import { useCountStore } from '@/store/count'
import { storeToRefs } from 'pinia'
let countStore = useCountStore()
let { sum } = storeToRefs(countStore)
</script>
getters
export const useCountStore = defineStore('count',{
actions:{
increment(value) {
this.sum += value
},
minus(value) {
this.sum -= value
}
},
// state是真正存储数据的地方
state(){
return {
sum:6
}
},
getters:{
// 写法1
// bigSum(state) {
// return state.sum*10
// }
// 写法2
// bigSum():number {
// return this.sum*10
// }
// 写法3
bigSum:state => state.sum*10
}
})
$subscribe 监视修改
使用浏览器本地存储作为例子
Talk.vue
<script setup name="LoveTalk" lang="ts">
import { reactive } from 'vue';
import axios from 'axios';
import { nanoid } from 'nanoid'
import { useTalkStore } from '@/store/talk'
let talkStore = useTalkStore()
talkStore.$subscribe((mutate,state)=>{
// localStorage.setItem('talkList',state.talkList)
localStorage.setItem('talkList',JSON.stringify(state.talkList))
})
function getTalk() {
talkStore.addList()
}
</script>
talk.ts
import { defineStore } from "pinia";
import axios from "axios";
import { nanoid } from 'nanoid'
export const useTalkStore = defineStore('talk',{
actions:{
async addList() {
// 连续解构赋值+重命名
let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?fomat=json')
let obj = {id:nanoid(),title}
// talkStore.talkList.unshift(obj)
this.talkList.unshift(obj)
}
},
// state是真正存储数据的地方
state(){
return {
talkList:JSON.parse(localStorage.getItem('talkList')) || []
}
}
})
store的组合式写法
import { defineStore } from "pinia";
import axios from "axios";
import { nanoid } from 'nanoid'
// export const useTalkStore = defineStore('talk',{
// actions:{
// async addList() {
// // 连续解构赋值+重命名
// let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?fomat=json')
// let obj = {id:nanoid(),title}
// // talkStore.talkList.unshift(obj)
// this.talkList.unshift(obj)
// }
// },
// // state是真正存储数据的地方
// state(){
// return {
// talkList:JSON.parse(localStorage.getItem('talkList')) || []
// }
// }
// })
import { reactive } from "vue";
export const useTalkStore = defineStore('talk',()=>{
let talkList = reactive(JSON.parse(localStorage.getItem('talkList') as string) || [])
async function addList() {
// 连续解构赋值+重命名
let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?fomat=json')
let obj = {id:nanoid(),title}
// talkStore.talkList.unshift(obj)
talkList.unshift(obj)
}
return {talkList,addList}
})