文章目录
学习总结
一、简介
- 概念:Pinia是Vue的存储库,它允许您跨组件/页面共享状态,与 vuex 功能一样
- 安装:
npm i pinia
二、搭建Pinia环境
import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
三、存储+读取数据
- store是一个保存:状态、业务逻辑的实体,每个组件都可以读取、写入它
- 有三个概念:state、getter、action,相当于组件中的:data、computed和methods
- store是一个用reactive包裹的对象,这意味着不需要在getter之后写.value,但是,就像setup中的props一样,不能对其进行解构
- 具体编码:
// src/store/count.ts
import { defineStore } from "pinia";
export const useCountStore = defineStore("count", {
// 动作
actions: {},
state: () => {
return {
sum: 0,
};
},
// 计算
getters: {}
});
// src/store/talk.ts
import { defineStore } from "pinia";
export const useTalkStore = defineStore("talk", {
// 动作
actions: {},
// 状态
state() {
return {
talkList: [
{ id: 'tuwei01', title: '今天你有点怪,哪里怪?怪好看的!' },
{ id: 'tuwei02', title: '草莓、蓝莓、蔓越莓,今天你想我了没?' },
{ id: 'tuwei03', title: '心里给你留了一块地,我的死心塌地' }
]
};
},
// 计算
getters: {}
});
四、三种修改数据的方式
import { ref } from 'vue'
// 引入store
import { useCountStore } from '@/store/count'
// 使用
const countStore = useCountStore()
// 数据
let n = ref(1) // 用户选择的数字
// 方法
function add() {
// 第一种修改方式:直接修改
countStore.sum += Number(n.value)
// 第二种修改方式:批量修改
countStore.$patch({
sum: countStore.sum + Number(n.value),
address: '中国'
})
// 第三种修改方式:借助action修改(action中可以编写一些业务逻辑)
countStore.increment(n.value)
}
function minus() {
countStore.sum -= n.value
}
<div class="count">
<h3>欢迎来到:{{ countStore.school }},坐落于{{ countStore.NewYork }}</h3>
<h2>当前求和为:{{ countStore.sum }}</h2>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add">+</button>
<button @click="minus">-</button>
</div>
import { defineStore } from "pinia";
export const useCountStore = defineStore("count", {
// 第三种
// actions里面放置的是一个一个方法,用于响应组件中的“动作”
actions: {
increment(value) {
if (this.sum < 10) {
// 修改数据(this是当前的store对象)
this.sum++
}
}
},
// 真正存储数据的地方
state: () => {
return {
sum: 0,
school: 'HIST',
address: 'NewYork'
};
},
// 计算
getters: {}
});
五、storeToRefs
借助storeToRefs将store中的数据转为ref对象,方便在模版中使用
注意:pinia提供的storeToRefs只会将数据做转换,而Vue的toRefs会转换store中数据
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
// 引入store
import { useCountStore } from '@/store/count'
// 使用
const countStore = useCountStore()
const { sum, school, address } = storeToRefs(countStore)
// 数据
let n = ref(1) // 用户选择的数字
// 方法
function add() {
// 第三种修改方式
countStore.increment(n.value)
}
function minus() {
countStore.sum -= n.value
}
<div class="count">
<h3>欢迎来到:{{ school }},坐落于{{ NewYork }}</h3>
<h2>当前求和为:{{ sum }}</h2>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add">+</button>
<button @click="minus">-</button>
</div>
六、getters
- 概念:当state中的数据,需要经过处理后再使用时,可以使用getters配置
- 追加getters配置
import { defineStore } from "pinia";
export const useCountStore = defineStore("count", {
// actions里面放置的是一个一个方法,用于响应组件中的“动作”
actions: {
increment(value:number) {
if (this.sum < 10) {
// 修改数据(this是当前的store对象)
this.sum++
}
}
},
// 真正存储数据的地方
state: () => {
return {
sum: 0,
school: 'HIST',
address: 'NewYork'
};
},
// 计算
getters: {
bigSum(state){
return state.sum * 10
},
upperSchool():string{
return this.school.toUpperCase()
}
}
});
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
// 引入store
import { useCountStore } from '@/store/count'
// 使用
const countStore = useCountStore()
const { sum, school, address, bigSum, upperSchool } = storeToRefs(countStore)
// 数据
let n = ref(1) // 用户选择的数字
// 方法
function add() {
// 第三种修改方式
countStore.increment(n.value)
}
function minus() {
countStore.sum -= n.value
}
七、action
- action相当于组件中的methods,可以使用defineStore()中的actions属性定义,并且他们非常适合定义业务逻辑
- actions支持异步操作的,可以编写异步函数
八、$subscribe订阅
<div class="talk">
<button @click="getLoveTalk">获取一个土味情话</button>
<ul>
<li v-for="talk in talkStore.talkList" :key="talk.id">{{ talk.title }}</li>
</ul>
</div>
import { reactive } from 'vue'
import { useTalkStore } from '@/store/loveTalk';
const talkStore = useTalkStore()
// const talkList = reactive(useTalkStore().talkList)
talkStore.$subscribe((mutate, state) => {
console.log('talkStore里保存的数据发生了变化', mutate, state);
localStorage.setItem('talkList',JSON.stringify(state.talkList))
})
function getLoveTalk() {
talkStore.getATalk()
}
import { defineStore } from "pinia";
import axios from 'axios'
import { nanoid } from "nanoid";
export const useTalkStore = defineStore("talk", {
// 动作
actions: {
async getATalk() {
let { data } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
this.talkList.unshift({ id: nanoid(), title: data.content })
}
},
// 状态
state() {
return {
talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
};
},
// 计算
getters: {}
});
九、store组合式写法
import { defineStore } from "pinia";
import axios from 'axios'
import { nanoid } from "nanoid";
import { reactive } from "vue";
// export const useTalkStore = defineStore("talk", {
// // 动作
// actions: {
// async getATalk() {
// let { data } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
// this.talkList.unshift({ id: nanoid(), title: data.content })
// }
// },
// // 状态
// state() {
// return {
// talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
// };
// },
// // 计算
// getters: {}
// });
export const useTalkStore = defineStore('talk', () => {
// talkList就是state
const talkList = reactive(
JSON.parse(localStorage.getItem('talkList') as string) || []
)
// getATalk函数相当于action
async function getATalk() {
let { data } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
this.talkList.unshift({ id: nanoid(), title: data.content })
}
return {
talkList,
getATalk
}
})
下周计划
下周开始小组官网,vue感觉学的不是很好,还需要多复习复习
本周总结
本周就一个字忙!小组和纪检部两边都需要带新生,各种事情忙的团团转,今天去看了一下社团招新领到了小玩意