vue-有關于TS與路由器

title: vue(TS)+路由器
date: 2025-01-28 12:00:00
tags:- 前端
categories:- 前端

Vue3-第二部分

這里是代碼中出現TS的,后面是路由器

現在先上代碼,步步分析。

eg1-props的使用

步步分析代碼(先理解,再實踐)

框架

image-20250128003823892

先分析main.ts

常規出現,就是創建與引入

// 引入createApp用于創建應用
import {createApp} from 'vue'
// 引入App根組件
import App from './App.vue'
?
createApp(App).mount('#app')

分析組件內的person.vue

模版部分
<template><div class="person"><ul><li v-for="p in list" :key="p.id">{ {p.name} } -- { {p.age} }</li></ul></div>
</template>

功能說明:

1. 渲染數據列表

? list 是通過 props 傳遞給 Person 組件的。

? 使用 v-for 循環遍歷 list 數組,動態生成 <li> 列表項。

? 每個 li 顯示每個對象的 name 和 age。

2. 綁定唯一的 key:

? 使用 :key="p.id" 為每個列表項綁定唯一的 key,提高渲染效率。

腳本部分
<script lang="ts" setup name="Person">import { withDefaults } from 'vue'import { type Persons } from '@/types'
?// 接收list + 限制類型 + 限制必要性 + 指定默認值withDefaults(defineProps<{list?: Persons}>(), {list: () => [{ id: 'ausydgyu01', name: '康師傅·王麻子·特侖蘇', age: 19 }]})
</script>

上面的import是什么?

一般是導入工具與類型

? withDefaults:

? 用于為 defineProps 定義的 props 設置默認值。它接收兩個參數:

? defineProps 的返回值(包含 props 的類型約束)。

? 一個對象,用來指定每個 prop 的默認值。

? Persons:

? 從 @/types 導入的類型別名,表示一個由多個 person 對象組成的數組,符合以下結構:

也就是如果我要用到 prop的時候用

知識點解析:

1. defineProps:

? Vue 3 提供的 API,用于定義組件接收的 props。

? defineProps<{list?: Persons}>():

? 定義了一個可選的 list 屬性,類型為 Persons(數組,每個元素是一個符合 PersonInter 的對象)。

2. withDefaults:

? 用來為可選 props(如 list?)設置默認值。

? 默認值為:

[{ id: 'ausydgyu01', name: '康師傅·王麻子·特侖蘇', age: 19 }]

再分析index.ts

// 定義一個接口,用于限制person對象的具體屬性
export interface PersonInter {id: string,name: string,age: number,
}
?
// 一個自定義類型
export type Persons = PersonInter[]

1. 接口 PersonInter:

? 定義了 person 對象的結構,強制要求每個對象包含以下屬性:

? id:字符串,唯一標識。

? name:字符串,人員姓名。

? age:數字,人員年齡。

2. 類型別名 Persons:

? 定義了一個數組類型,數組的每個元素都必須符合 PersonInter 接口。

App.vue解析

<template><!-- 務必看懂下面這一行代碼 --><!-- <h2 a="1+1" :b="1+1" c="x" :d="x" ref="qwe">測試</h2> --><Person a="哈哈" />
</template>

靜態屬性:a = "1 + 1"是一個普通的字符串,直接作為屬性值

動態屬性:b = "1 + 1"是一個動態表達式,結果會被計算后作為屬性值

ref="qwe",綁定DOM引用,可以在JavaScript中通過ref操作這個DOM元素

2. 子組件 <Person /> 的使用:

? <Person /> 是導入的子組件,代表 person.vue 文件。

? a="哈哈" 是傳遞給 <Person /> 的一個普通屬性。

腳本部分

<script lang="ts" setup name="App">import Person from './components/Person.vue'import { reactive } from 'vue'import { type Persons } from '@/types'
?let x = 9
?let personList = reactive<Persons>([{ id: 'asudfysafd01', name: '張三', age: 18 },{ id: 'asudfysafd02', name: '李四', age: 20 },{ id: 'asudfysaf)d03', name: '王五', age: 22 }])
</script>

1. 引入 Person 組件:

? import Person from './components/Person.vue' 引入 person.vue,使得 <Person /能夠在模板中使用。

  1. 定yi響應式數據:

  2. reactive 的作用:

    ? 使得 personList 成為響應式數據。當 personList 或其內部的對象屬性發生變化時,Vue 會自動更新視圖。

整體邏輯總結

Index.ts 定義了personInter接口和Person類型,用來約束person數據結構

Person.vue 接收list作為props,通過withDefaults為list設置默認值

渲染list數據。動態生成列表

App.vue

定義一個響應式數據personalist,并可以通過props傳遞給pweson.vue

image-20250128010109534

vue2生命周期

<template><div class="person"><h2>當前求和為:{ { sum } }</h2><button @click="add">點我sum+1</button></div>
</template>

功能說明:

1. 數據綁定:

? { { sum } } 用來動態展示變量 sum 的值。

? 每次點擊按鈕,sum 的值增加 1。

2. 事件綁定:

? @click="add":綁定按鈕點擊事件,觸發 add 方法,更新 sum 的值。

<script lang="ts" setup name="Person">import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'// 數據let sum = ref(0)// 方法function add() {sum.value += 1}// 創建console.log('創建')// 掛載前onBeforeMount(() => {// console.log('掛載前')})// 掛載完畢onMounted(() => {console.log('子---掛載完畢')})// 更新前onBeforeUpdate(() => {// console.log('更新前')})// 更新完畢onUpdated(() => {// console.log('更新完畢')})// 卸載前onBeforeUnmount(() => {// console.log('卸載前')})// 卸載完畢onUnmounted(() => {// console.log('卸載完畢')})
</script>

image-20250128011042599

app.vue

<template><Person v-if="isShow" />
</template>

1. <Person v-if="isShow" /

? 條件渲染子組件 Person。

? 當 isShow 為 true 時,<Person / 會被掛載。

? 當 isShow 為 false 時,<Person /會被卸載。

腳本部分

<script lang="ts" setup name="App">import Person from './components/Person.vue'import { ref, onMounted } from 'vue'let isShow = ref(true)// 掛載完畢onMounted(() => {console.log('父---掛載完畢')})
</script>

功能解析:

1. 引入子組件:

? Person 是一個子組件,來自 ./components/Person.vue。

2. 響應式數據:

? let isShow = ref(true):定義了一個響應式布爾值 isShow,控制 <Person /> 的顯示和隱藏。

3. 生命周期鉤子:

? onMounted:在 App 組件掛載到 DOM 后執行。這里輸出 父---掛載完畢,用于標記父組件掛載完成。

運行流程

  1. 父組件掛載(App

? isShow 默認為 true。

? <Person / 被掛載到 DOM 中。

? 控制臺輸出:

父---掛載完畢
創建
子---掛載完畢

. 子組件更新(Person

? 點擊按鈕時,sum.value 增加 1,觸發子組件更新。

? 在更新階段,執行以下生命周期鉤子:

? onBeforeUpdate

? onUpdated

3. 子組件卸載(Person

? 如果將 isShow 設置為 false(例如通過交互),<Person /> 會被卸載。

? 卸載階段執行:

? onBeforeUnmount

? onUnmounted

5. 總結

person.vue 的功能

? 通過按鈕點擊實現 sum 的動態更新。

? 使用 Vue 3 的生命周期鉤子監控組件的各個階段,包括掛載、更新、卸載。

app.vue 的功能

? 使用 v-if 控制子組件 Person 的掛載和卸載。

? 父組件負責管理子組件的存在與否,同時通過生命周期鉤子記錄父組件的掛載階段。

生命周期運行示意圖

1. 父組件掛載:

? onMounted -> 輸出:父---掛載完畢

2. 子組件掛載:

? 創建

? onBeforeMount(未輸出)

? onMounted -> 輸出:子---掛載完畢

3. 子組件更新:

? onBeforeUpdate

? onUpdated

4. 子組件卸載:

? onBeforeUnmount

? onUnmounted

image-20250128012228275

對應頁面

Eg2-hook自定義

<template><div class="person"><h2>當前求和為:{ { sum } },放大10倍后:{ { bigSum } }</h2><button @click="add">點我sum+1</button><hr><img v-for="(dog,index) in dogList" :src="dog" :key="index"><br><button @click="getDog">再來一只小狗</button></div>
</template><script lang="ts" setup name="Person">import useSum from '@/hooks/useSum'import useDog from '@/hooks/useDog'const {sum,add,bigSum} = useSum()const {dogList,getDog} = useDog()
</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;}img {height: 100px;margin-right: 10px;}
</style>

這個是person.vue

在模版部分,

? 圖片渲染:

? 使用 v-for 循環 dogList,通過動態綁定 src 和 key 屬性渲染小狗圖片。

在腳本部分

? 引入邏輯模塊:

? 從 useSum.ts 中引入了 sum、add 和 bigSum,負責數值的處理。

? 從 useDog.ts 中引入了 dogList 和 getDog,負責圖片列表的管理和 API 請求。

? 使用組合式 API:

? 通過解構的方式,將邏輯解耦到獨立的模塊中,提高代碼的可復用性。

在useDog.ts模塊

import { reactive, onMounted } from 'vue'
import axios from 'axios'export default function () {// 數據let dogList = reactive(['https://images.dog.ceo/breeds/pembroke/n02113023_4373.jpg'])// 方法async function getDog() {try {let result = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')dogList.push(result.data.message)} catch (error) {alert(error)}}// 鉤子onMounted(() => {getDog()})// 向外部提供東西return { dogList, getDog }
}

功能分析

1. 響應式數據

? 使用 reactive 定義了圖片列表 dogList,默認包含一張圖片。

2. API 請求方法

? getDog 方法使用 Axios 請求 https://dog.ceo 提供的小狗圖片 API。

? 將獲取的圖片 URL 推入 dogList 中。

? 通過 try-catch 捕獲請求錯誤。

3. 生命周期鉤子

? 在組件掛載時 (onMounted) 自動調用 getDog,預加載一張小狗圖片。

關鍵點

? 合理使用 reactive 管理數組的響應式更新。

? 在組件加載時預先獲取數據,優化用戶體驗。

在這里面有一個地方發送異步請求

zlet result = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')

axios.get():

? 使用 axios 發起一個 HTTP GET 請求。

? 請求地址是 https://dog.ceo/api/breed/pembroke/images/random,這是一個提供隨機小狗圖片的 API。

? 返回的數據是一個包含 message 屬性的 JSON 對象

await:

? await 暫停代碼的執行,直到請求完成并返回結果。

? 返回值存儲在 result 變量中,具體數據保存在 result.data 中。

在useSum.ts模塊

import { ref, onMounted, computed } from 'vue'export default function () {// 數據let sum = ref(0)let bigSum = computed(() => {return sum.value * 10})// 方法function add() {sum.value += 1}// 鉤子onMounted(() => {add()})// 給外部提供東西return { sum, add, bigSum }
}

功能分析

1. 響應式數據

? 使用 ref 定義了單一響應式數據 sum。

? 使用 computed 定義了計算屬性 bigSum,動態計算 sum 的 10 倍值。

2. 方法

? add 方法使 sum 增加 1。

3. 生命周期鉤子

? 在 onMounted 中調用 add,在組件加載時使 sum 初始值為 1。

路由

在 Vue 3 中,路由管理通常通過 Vue Router 實現。路由的主要功能是實現頁面的導航和組件的動態渲染。以下是關于路由的核心概念和代碼實現的詳細說明。

1. 什么是路由?

路由是一種通過 URL 映射組件或視圖的方式。它允許用戶在單頁應用(SPA)中導航,而無需重新加載整個頁面。

例如:

? /home 映射到 Home 組件。

? /about 映射到 About 組件。

image-20250128081820700

頁面組件

<template><div class="home"><img src="http://www.atguigu.com/images/index_new/logo.png" alt=""></div>
</template>

? 功能:展示一個居中的圖片。

? 樣式:通過 flex 布局將內容水平和垂直居中。

? 用途:作為首頁內容。

<script setup lang="ts" name="Home">
</script>

? 作用

? 表示該組件使用 Vue 3 的 <script setup> 語法。

? lang="ts" 表示代碼使用 TypeScript,增加類型安全。

? name="Home" 給組件命名為 Home,方便調試和遞歸調用。

樣式部分

<style scoped>.home {display: flex;justify-content: center;align-items: center;height: 100%;}
</style>

? 作用

? 定義組件的樣式。

? scoped 表示樣式只作用于當前組件,不影響其他組件。

? 細節解析

? display: flex;:

? 使用 Flex 布局,使子元素容易居中對齊。

? justify-content: center;:

? 子元素水平居中。

? align-items: center;:

? 子元素垂直居中。

? height: 100%;:

? 根容器的高度設置為父級容器的 100%。

About.vue

<template><div class="about"><h2>大家好,歡迎來到尚硅谷直播間</h2></div>
</template><script setup lang="ts" name="About"></script><style scoped>
.about {display: flex;justify-content: center;align-items: center;height: 100%;color: rgb(85, 84, 84);font-size: 18px;
}
</style>

News.vue

<template><div class="news"><ul><li><a href="#">新聞001</a></li><li><a href="#">新聞002</a></li><li><a href="#">新聞003</a></li><li><a href="#">新聞004</a></li></ul></div>
</template><script setup lang="ts" name="News"></script><style scoped>
/* 新聞 */
.news {padding: 0 20px;display: flex;justify-content: space-between;height: 100%;
}
.news ul {margin-top: 30px;list-style: none;padding-left: 10px;
}
.news li>a {font-size: 18px;line-height: 40px;text-decoration: none;color: #64967E;text-shadow: 0 0 1px rgb(0, 84, 0);
}
</style>

路由配置

// 創建一個路由器,并暴露出去// 第一步:引入createRouter
import {createRouter,createWebHistory} from 'vue-router'
// 引入一個一個可能要呈現組件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
import About from '@/components/About.vue'// 第二步:創建路由器
const router = createRouter({history:createWebHistory(), //路由器的工作模式(稍后講解) routes:[ //一個一個的路由規則{path:'/home',component:Home},{path:'/news',component:News},{path:'/about',component:About},]
})// 暴露出去router
export default router

? createRouter

? 創建一個路由實例。

? createWebHistory

? 使用 HTML5 的歷史記錄模式。

? routes

? 定義路由規則,每條規則對應一個路徑和組件。

應用入口

// 引入createApp用于創建應用
import {createApp} from 'vue'
// 引入App根組件
import App from './App.vue'
// 引入路由器
import router from './router'// 創建一個應用
const app = createApp(App)
// 使用路由器
app.use(router)
// 掛載整個應用到app容器中
app.mount('#app')

App.vue

模版部分

<template><div class="app"><h2 class="title">Vue路由測試</h2><!-- 導航區 --><div class="navigate"><RouterLink to="/home" active-class="xiaozhupeiqi">首頁</RouterLink><RouterLink to="/news" active-class="xiaozhupeiqi">新聞</RouterLink><RouterLink to="/about" active-class="xiaozhupeiqi">關于</RouterLink></div><!-- 展示區 --><div class="main-content"><RouterView></RouterView></div></div>
</template>

<RouterLink:

? Vue Router 提供的導航組件,類似于 HTML 的 <a> 標簽。

? to="/home":指定點擊該鏈接時跳轉的路由路徑。

? active-class="xiaozhupeiqi":定義激活時的樣式類名,當鏈接的路由匹配當前路徑時會自動應用。

? 導航鏈接功能:

? 首頁:跳轉到 /home 路由。

? 新聞:跳轉到 /news 路由。

? 關于:跳轉到 /about 路由。

在展示區

<div class="main-content"><RouterView></RouterView>
</div>

? <RouterView :

? Vue Router 提供的內置組件,用于渲染當前路由匹配的組件。

? 根據用戶點擊的導航鏈接,<RouterView會動態切換為對應的組件內容,例如 Home.vue、News.vue 或 About.vue。

腳本部分

<script lang="ts" setup name="App">import { RouterView, RouterLink } from 'vue-router'
</script>

逐行解析

(1) lang="ts"

? 表示當前腳本部分使用 TypeScript,增強類型安全。

? 允許對變量、函數等進行類型聲明。

(2) setup

? 使用 Vue 3 的組合式 API 的語法糖。

? 在 <script setup中定義的變量和方法,可以直接在模板中使用,無需顯式返回。

(3) name="App"

? 為當前組件指定名稱為 App。

? 在開發者工具(如 Vue DevTools)中調試時,可以看到組件名稱為 App,便于區分。

(4) 引入 Vue Router 的組件

import { RouterView, RouterLink } from 'vue-router'

? RouterLink:用于定義路由導航鏈接。

? RouterView:用于動態渲染路由匹配的組件。

樣式部分

.title {text-align: center;word-spacing: 5px;margin: 30px 0;height: 70px;line-height: 70px;background-image: linear-gradient(45deg, gray, white);border-radius: 10px;box-shadow: 0 0 2px;font-size: 30px;
}
.navigate {display: flex;justify-content: space-around;margin: 0 100px;
}
.navigate a {display: block;text-align: center;width: 90px;height: 40px;line-height: 40px;border-radius: 10px;background-color: gray;text-decoration: none;color: white;font-size: 18px;letter-spacing: 5px;
}

image-20250128085015970

image-20250128085239563

image-20250128085251179

xiaozhupeiqi 激活后呈現的

image-20250128085312669

這個就是超鏈接<a的時候,未點擊前呈現的

視頻中沒有講這一部分,少了一個知識點的講解就是routeLink->轉換為<a標簽

image-20250128085843036

image-20250128090039568

image-20250128090244976

Query 參數-路由

Header.ts

<template><h2 class="title">Vue路由測試</h2>
</template><script setup lang="ts" name="Header"></script><style scoped>.title {text-align: center;word-spacing: 5px;margin: 30px 0;height: 70px;line-height: 70px;background-image: linear-gradient(45deg, gray, white);border-radius: 10px;box-shadow: 0 0 2px;font-size: 30px;}
</style>

About.ts

<template><div class="about"><h2>大家好,歡迎來到尚硅谷直播間</h2></div>
</template><script setup lang="ts" name="About">import {onMounted,onUnmounted} from 'vue'onMounted(()=>{console.log('About組件掛載了')})onUnmounted(()=>{console.log('About組件卸載了')})
</script><style scoped>
.about {display: flex;justify-content: center;align-items: center;height: 100%;color: rgb(85, 84, 84);font-size: 18px;
}
</style>

image-20250128092207216

Detail.ts

<template><ul class="news-list"><li>編號:{ { query.id } }</li><li>標題:{ { query.title } }</li><li>內容:{ { query.content } }</li></ul>
</template><script setup lang="ts" name="About">import {toRefs} from 'vue'import {useRoute} from 'vue-router'let route = useRoute()let {query} = toRefs(route)</script><style scoped>.news-list {list-style: none;padding-left: 20px;}.news-list>li {line-height: 30px;}
</style>

腳本部分

解析

(1) useRoute

? 定義

? useRoute 是 Vue Router 提供的組合式 API,用于獲取當前路由對象。

? 作用

? 返回當前激活的路由信息,包括路徑、參數、查詢字符串等。

? 返回值

? route 是一個響應式對象,包含當前路由的所有信息,例如:

{path: "/news",query: {id: "123",title: "Vue Router",content: "這是一個簡單的示例"},params: { ... },...
}

(2) toRefs

? 定義

? toRefs 是 Vue 的組合式 API,用于將響應式對象的屬性轉換為獨立的響應式引用。

? 作用

? 將 route.query 轉換為響應式引用,使得在模板中訪問 query 的屬性時,能夠保持響應式更新。

? 代碼作用

let { query } = toRefs(route)

(3) 數據流程

? useRoute() 獲取當前路由信息。

? 通過 toRefs(route) 解構出 query,用于動態綁定數據。

Params

image-20250128094158019

image-20250128094312633

<template><div class="news"><!-- 導航區 --><ul><li v-for="news in newsList" :key="news.id"><!-- 第一種寫法 --><!-- <RouterLink :to="`/news/detail/${news.id}/${news.title}/${news.content}`">{ {news.title} }</RouterLink> --><!-- 第二種寫法 --><RouterLink :to="{name:'xiang',params:{id:news.id,title:news.title,content:news.content}}">{ {news.title} }</RouterLink></li></ul><!-- 展示區 --><div class="news-content"><RouterView></RouterView></div></div>
</template><script setup lang="ts" name="News">import {reactive} from 'vue'import {RouterView,RouterLink} from 'vue-router'const newsList = reactive([{id:'asfdtrfay01',title:'很好的抗癌食物',content:'西藍花'},{id:'asfdtrfay02',title:'如何一夜暴富',content:'學IT'},{id:'asfdtrfay03',title:'震驚,萬萬沒想到',content:'明天是周一'},{id:'asfdtrfay04',title:'好消息!好消息!',content:'快過年了'}])</script><style scoped>
/* 新聞 */
.news {padding: 0 20px;display: flex;justify-content: space-between;height: 100%;
}
.news ul {margin-top: 30px;/* list-style: none; */padding-left: 10px;
}
.news li::marker {color: #64967E;
}
.news li>a {font-size: 18px;line-height: 40px;text-decoration: none;color: #64967E;text-shadow: 0 0 1px rgb(0, 84, 0);
}
.news-content {width: 70%;height: 90%;border: 1px solid;margin-top: 20px;border-radius: 10px;
}
</style>

這個是new.vue

image-20250128095252643

image-20250128095646602

Pinia

Count.vue

模版部分

<template><div class="count"><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>
</template>

? 使用 { { sum } } 動態綁定 sum 的值,顯示當前的求和結果。

2. 選擇操作數

? 使用 <select 元素,讓用戶選擇一個數字(1、2 或 3)。

? 通過 v-model.number="n" 雙向綁定選中的值到變量 n,并將其轉換為數值。

  1. 加減操作

? 點擊“加”按鈕時調用 add 方法。

? 點擊“減”按鈕時調用 minus 方法。

腳本部分

<script setup lang="ts" name="Count">import { ref } from "vue";// 數據let sum = ref(1) // 當前求和let n = ref(1) // 用戶選擇的數字// 方法function add(){sum.value += n.value}function minus(){sum.value -= n.value}
</script>

1. ref 定義響應式數據

? sum:當前求和,初始值為 1。

? n:用戶選擇的數字,初始值為 1。

? 響應式數據會自動更新綁定到模板的內容。

2. 方法功能

? add:將選中的數字 n.value 加到 sum.value 上。

? minus:從 sum.value 中減去 n.value。

<script setup lang="ts" name="LoveTalk">import { reactive } from 'vue'import axios from "axios";import { nanoid } from 'nanoid'// 數據let talkList = reactive([{id:'ftrfasdf01',title:'今天你有點怪,哪里怪?怪好看的!'},{id:'ftrfasdf02',title:'草莓、藍莓、蔓越莓,今天想我了沒?'},{id:'ftrfasdf03',title:'心里給你留了一塊地,我的死心塌地'}])// 方法async function getLoveTalk(){// 發請求,下面這行的寫法是:連續解構賦值+重命名let {data:{content:title} } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')// 把請求回來的字符串,包裝成一個對象let obj = {id:nanoid(),title}// 放到數組中talkList.unshift(obj)}
</script>

在app.vue里面寫

<template><Count/><br><LoveTalk/>
</template><script setup lang="ts" name="App">import Count from './components/Count.vue'import LoveTalk from './components/LoveTalk.vue'
</script>
npm i pinia

image-20250128103405430

import {createApp} from 'vue'
import App from './App.vue'
// 第一步:引入pinia
import {createPinia} from 'pinia'const app = createApp(App)
// 第二步:創建pinia
const pinia = createPinia()
// 第三步:安裝pinia
app.use(pinia)
app.mount('#app')

image-20250128103603995

小菠蘿出來啦!!!

存儲+讀取數據

創建一個store文件夾

Count.ts

import {defineStore} from 'pinia'export const useCountStore = defineStore('count',{// 真正存儲數據的地方state(){return {sum:6}}
})

Lovetalk.ts

import {defineStore} from 'pinia'export const useTalkStore = defineStore('talk',{// 真正存儲數據的地方state(){return {talkList:[{id:'ftrfasdf01',title:'今天你有點怪,哪里怪?怪好看的!'},{id:'ftrfasdf02',title:'草莓、藍莓、蔓越莓,今天想我了沒?'},{id:'ftrfasdf03',title:'心里給你留了一塊地,我的死心塌地'}]}}
})

修改數據

import {defineStore} from 'pinia'export const useCountStore = defineStore('count',{// actions里面放置的是一個一個的方法,用于響應組件中的“動作”actions:{increment(value){console.log('increment被調用了',value)if( this.sum < 10){// 修改數據(this是當前的store)this.sum += value}}},// 真正存儲數據的地方state(){return {sum:6,school:'atguigu',address:'宏福科技園'}}
})
import {defineStore} from 'pinia'
import axios from 'axios'
import {nanoid} from 'nanoid'export const useTalkStore = defineStore('talk',{actions:{async getATalk(){// 發請求,下面這行的寫法是:連續解構賦值+重命名let {data:{content:title} } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')// 把請求回來的字符串,包裝成一個對象let obj = {id:nanoid(),title}// 放到數組中this.talkList.unshift(obj)}},// 真正存儲數據的地方state(){return {talkList:[{id:'ftrfasdf01',title:'今天你有點怪,哪里怪?怪好看的!'},{id:'ftrfasdf02',title:'草莓、藍莓、蔓越莓,今天想我了沒?'},{id:'ftrfasdf03',title:'心里給你留了一塊地,我的死心塌地'}]}}
})

現在展開解釋

整體功能

這段代碼通過 Pinia 定義了一個 Store,用于管理一個情話列表 talkList,并提供了一個方法 getATalk 來向 API 請求新的情話并添加到 talkList 中。

1. 引入的依賴

import { defineStore } from 'pinia'
import axios from 'axios'
import { nanoid } from 'nanoid'

解析

1. defineStore:

? 從 pinia 中引入,用于定義一個新的 Store。

? Store 是狀態管理的核心,用于存儲和管理全局共享的狀態。

2. axios:

? 用于發送 HTTP 請求。

? 這里通過 axios.get() 從 https://api.uomg.com/api/rand.qinghua 獲取隨機土味情話。

3. nanoid:

? 一個小型的 ID 生成工具。

? 用于為每條情話生成唯一的 ID,確保 talkList 中的每條情話都有一個獨特的標識。

2. 定義 Store

export const useTalkStore = defineStore('talk', { ... })

解析

1. export const useTalkStore:

? 定義了一個 Store,命名為 useTalkStore。

? 這個名字的命名規則通常是 use 開頭,以表明它是一個 Store。

2. defineStore('talk', {...}):

? 'talk' 是這個 Store 的唯一標識符,用于區分其他 Store。

? 第二個參數是 Store 的配置對象,包含 state 和 actions 等。

3. state:存儲數據

state() {return {talkList: [{ id: 'ftrfasdf01', title: '今天你有點怪,哪里怪?怪好看的!' },{ id: 'ftrfasdf02', title: '草莓、藍莓、蔓越莓,今天想我了沒?' },{ id: 'ftrfasdf03', title: '心里給你留了一塊地,我的死心塌地' }]}
}

解析

1. state:

? 一個函數,返回一個對象,這個對象定義了 Store 中的數據。

? 在這里,state 定義了一個情話列表 talkList。

2. talkList:

? 是一個數組,存儲了情話的初始數據。

? 每條情話是一個對象,包含以下字段:

? id:情話的唯一標識符。

? title:情話的具體內容。

3. 響應式特性

? Pinia 的 state 是響應式的。

? 當 talkList 數據發生變化時,綁定到 talkList 的視圖會自動更新。

4. actions:定義方法

actions: {async getATalk() {let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')let obj = { id: nanoid(), title }this.talkList.unshift(obj)}
}

解析

1. actions:

? 定義了 Store 中的方法,通常用于處理復雜邏輯或修改狀態。

? getATalk 是一個異步方法,用于從 API 獲取新的情話并更新 talkList。

2. getATalk 的工作流程

? 發送請求

let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')

? 使用 axios.get() 發送請求,從 API 獲取情話。

? 解構賦值提取 content 字段,并將其重命名為 title。

? 創建新對象

let obj = { id: nanoid(), title }

? 使用 nanoid() 生成一個唯一的 ID。

? 創建一個包含 id 和 title 的新情話對象。

? 更新 talkList:

this.talkList.unshift(obj)

? 使用 unshift 方法,將新情話添加到 talkList 的開頭。

? 由于 talkList 是響應式的,更新數據后,綁定到 talkList 的 UI 會自動更新。


image-20250128104601061

1. storeToRefs 的使用

storeToRefs 是 Pinia 提供的一個工具函數,主要用于從 Store 中提取狀態(state)和 Getter 的響應式引用,確保解構后不會丟失響應性。

import { storeToRefs } from 'pinia'const store = useSomeStore()
const { stateProp, getterProp } = storeToRefs(store)

作用

? 將 state 和 getter 轉換為響應式 ref。

? 解構 Store 中的屬性時,防止響應性丟失。

2. getters 的使用

Pinia 的 getters 是類似于 Vuex 中的計算屬性,用于對 state 的值進行派生計算。

  state: () => ({talkList: [{ id: '1', title: '情話一' },{ id: '2', title: '情話二' }]}),getters: {talkCount: (state) => state.talkList.length // 返回情話總數}
})
import { useTalkStore } from '@/stores/talkStore'const talkStore = useTalkStore()// 直接訪問 getter
console.log(talkStore.talkCount) // 輸出情話總數

3. $subscribe 的使用

$subscribe 是 Pinia 提供的一個方法,用于監聽 Store 中 state 和 action 的變化。

語法

store.$subscribe((mutation, state) => {console.log(mutation) // 包含 type 和 payloadconsole.log(state)    // 當前狀態
})

4. store 組合式寫法

Pinia 支持組合式 API(Composition API)風格的 Store 定義。

export const useTalkStore = defineStore('talk', () => {const talkList = ref([{ id: '1', title: '情話一' },{ id: '2', title: '情話二' }])const talkCount = computed(() => talkList.value.length)const addTalk = (id, title) => {talkList.value.push({ id, title })}return { talkList, talkCount, addTalk }
})
import { useTalkStore } from '@/stores/talkStore'const talkStore = useTalkStore()// 調用方法和訪問屬性
talkStore.addTalk('3', '情話三')
console.log(talkStore.talkCount) // 輸出 3

image-20250128104929967

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67411.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql.sock.lock 導致mysql重啟失敗

背景 今天公司物業斷電&#xff0c;導致機房服務器停電宕機&#xff0c;所有的服務都得重啟。本著mysql實例都做了服務自啟動&#xff0c;所以沒有太擔心影響開發的日常工作。但是今天一上班開發就找來&#xff0c;各種服務都沒起來有問題&#xff0c;數據庫連不上。馬上登陸數…

git困擾的問題

.gitignore中添加的某個忽略文件并不生效 把某些目錄或文件加入忽略規則&#xff0c;按照上述方法定義后發現并未生效&#xff0c; gitignore只能忽略那些原來沒有被追蹤的文件&#xff0c;如果某些文件已經被納入了版本管理中&#xff0c;則修改.gitignore是無效的。 解決方…

【hot100】刷題記錄(7)-除自身數組以外的乘積

題目描述&#xff1a; 給你一個整數數組 nums&#xff0c;返回 數組 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數據 保證 數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內。 請 不要使用除法&#x…

1-2 飛機大戰游戲場景

前言&#xff1a; 根據前面的項目框架&#xff0c;搭建游戲的運行場景...... 1.0 框架預覽 基于該框架首先實現游戲的運行場景 2.0 圖片文件 創建圖片文件&#xff0c;本次項目使用easyx作為圖形庫文件&#xff0c;在easyx中想要顯示圖片&#xff0c;需要有一張圖片和圖片的掩碼…

進程通訊——類型和發展

進程常用交互方法如上

JavaScript系列(49)--游戲引擎實現詳解

JavaScript游戲引擎實現詳解 &#x1f3ae; 今天&#xff0c;讓我們深入探討JavaScript的游戲引擎實現。游戲引擎是一個復雜的系統&#xff0c;它需要處理渲染、物理、音頻、輸入等多個方面&#xff0c;讓我們一步步實現一個基礎但功能完整的游戲引擎。 游戲引擎基礎概念 &am…

安裝zsh并美化

0 Zsh 是一種功能強大的 shell&#xff0c;通常用于替代默認的 Bash shell。它為命令行提供了更多的功能&#xff0c;例如自動補全、強大的模式匹配和主題支持等。 Oh My Zsh 是用于管理 Zsh 配置的框架。 powerlevel10k是樣式&#xff0c;通過p10k configure腳本可以調節自己…

GMSL 明星產品之 MAX96717

在上一篇文章中&#xff0c;我們詳細介紹了車載市場中爆火的 GMSL 到底是個啥 &#xff1a; 揭開 GMSL 的面紗&#xff1a;自動駕駛背后的隱藏技術。今天我們就來詳細了解下如今在攝像頭側超級火爆的加串器&#xff1a;MAX96717。 MAX96717 系列有三款產品&#xff1a; MAX967…

線段樹 算法

文章目錄 基礎知識適用場景小結 題目概述題目詳解300.最長遞增子序列2407.最長遞增子序列 II 基礎知識 線段樹和樹狀數組都只是一個工具來的&#xff0c;題目并不會一下子就告訴你這個題目用到線段樹和樹狀數組&#xff0c;這個取決于你想使用的數據結構以及所要優化的方向 線…

MATLAB提供的顏色映射表colormap——偽彩色

圖像處理領域的一個習慣&#xff1a;不是真實的顏色&#xff0c;一般用偽彩色。一是說明不是物體本身的顏色&#xff0c;二是彩色更容易分辨。 MATLAB陸續提供了16種顏色映射表colormap。 之前的都很丑&#xff0c;近5年新增的4種還可以。總的說來還是丑。 這是一種鳥的名字。…

20.Word:小謝-病毒知識的科普文章?【38】

目錄 題目? NO1.2.3文檔格式 NO4.5 NO6.7目錄/圖表目錄/書目 NO8.9.10 NO11索引 NO12.13.14 每一步操作完&#xff0c;確定之后記得保存最后所有操作完記得再次刪除空行 題目 NO1.2.3文檔格式 樣式的應用 選中應用段落段落→開始→選擇→→檢查→應用一個一個應用ctr…

【16屆藍橋杯寒假刷題營】第2期DAY4

【16屆藍橋杯寒假刷題營】第2期DAY4 - 藍橋云課 問題描述 幼兒園小班的浩楠同學有一個序列 a。 他想知道有多少個整數三元組 (i,j,k) 滿足 1≤i,j,k≤n 且 ai?aj?ak?。 輸入格式 共2行&#xff0c;第一行一個整數 n&#xff0c;表示序列的長度。 第二行 n 個整數&#x…

MySQL查詢優化(三):深度解讀 MySQL客戶端和服務端協議

如果需要從 MySQL 服務端獲得很高的性能&#xff0c;最佳的方式就是花時間研究 MySQL 優化和執行查詢的機制。一旦理解了這些&#xff0c;大部分的查詢優化是有據可循的&#xff0c;從而使得整個查詢優化的過程更有邏輯性。下圖展示了 MySQL 執行查詢的過程&#xff1a; 客戶端…

Van-Nav:新年,將自己學習的項目地址統一整理搭建自己的私人導航站,供自己后續查閱使用,做技術的同學應該都有一個自己網站的夢想

嗨&#xff0c;大家好&#xff0c;我是小華同學&#xff0c;關注我們獲得“最新、最全、最優質”開源項目和高效工作學習方法 Van-Nav是一個基于Vue.js開發的導航組件庫&#xff0c;它提供了多種預設的樣式和靈活的配置選項&#xff0c;使得開發者可以輕松地定制出符合項目需求…

VSCode+Continue實現AI輔助編程

Continue是一款功能強大的AI輔助編程插件&#xff0c;可連接多種大模型&#xff0c;支持代碼設計優化、錯誤修正、自動補全、注釋編寫等功能&#xff0c;助力開發人員提高工作效率與代碼質量。以下是其安裝和使用方法&#xff1a; 一、安裝VSCode 參見&#xff1a; vscode安…

【hot100】刷題記錄(6)-輪轉數組

題目描述&#xff1a; 給定一個整數數組 nums&#xff0c;將數組中的元素向右輪轉 k 個位置&#xff0c;其中 k 是非負數。 示例 1: 輸入: nums [1,2,3,4,5,6,7], k 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右輪轉 1 步: [7,1,2,3,4,5,6] 向右輪轉 2 步: [6,7,1,2,3,4,5] 向右輪轉…

FPGA 使用 CLOCK_DEDICATED_ROUTE 約束

使用 CLOCK_DEDICATED_ROUTE 約束 CLOCK_DEDICATED_ROUTE 約束通常在從一個時鐘區域中的時鐘緩存驅動到另一個時鐘區域中的 MMCM 或 PLL 時使 用。默認情況下&#xff0c; CLOCK_DEDICATED_ROUTE 約束設置為 TRUE &#xff0c;并且緩存 /MMCM 或 PLL 對必須布局在相同…

阿里:基于路由和規劃的多agent系統

&#x1f4d6;標題&#xff1a;Talk to Right Specialists: Routing and Planning in Multi-agent System for Question Answering &#x1f310;來源&#xff1a;arXiv, 2501.07813 &#x1f31f;摘要 &#x1f538;利用大型語言模型&#xff08;LLM&#xff09;&#xff0c…

數論問題77一一3x+1問題

3X 1問題&#xff0c;也被稱為考拉茲猜想、角谷猜想等&#xff0c;是數學領域一個著名的未解決問題&#xff0c;以下是關于它的介紹&#xff1a; 問題表述 對于任意一個正整數X&#xff0c;如果X是奇數&#xff0c;則將其變為3X 1&#xff1b;如果X是偶數&#xff0c;則將其變…

【Unity3D】實現2D角色/怪物死亡消散粒子效果

核心&#xff1a;這是一個Unity粒子系統自帶的一種功能&#xff0c;可將粒子生成控制在一個Texture圖片網格范圍內&#xff0c;并且粒子顏色會自動采樣圖片的像素點顏色&#xff0c;之后則是粒子編輯出消散效果。 Particle System1物體&#xff08;爆發式隨機速度擴散10000個粒…