尚矽谷影片教程
瞭解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}
})