• Vue3+ts(day07:pinia)


    学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes

    觉得有帮助的同学,可以点心心支持一下哈(笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】,记录一下学习笔记,用于自己复盘,有需要学习的可以去b站学习原版视频)

    一、准备一个效果

    App组件:

    1. <template>
    2. <Count></Count>
    3. <br />
    4. <LoveTalk></LoveTalk>
    5. </template>
    6. <script setup lang="ts" name="App">
    7. import Count from './components/Count.vue'
    8. import LoveTalk from './components/LoveTalk.vue'
    9. </script>
    10. <style scoped></style>

    Count组件:

    1. <template>
    2. <div class="count">
    3. <h2>当前求和为:{{ sum }}</h2>
    4. <select v-model.number="n">
    5. <option value="1">1</option>
    6. <option value="2">2</option>
    7. <option value="3">3</option>
    8. </select>
    9. <button @click="add"></button>
    10. <button @click="minus"></button>
    11. </div>
    12. </template>
    13. <script setup lang="ts" name="Count">
    14. import { ref } from 'vue'
    15. // 数据
    16. let sum = ref(1) //当前求和
    17. let n = ref(1) //用户选择的数据
    18. // 方法
    19. function add () {
    20. sum.value += n.value
    21. }
    22. function minus () {
    23. sum.value -= n.value
    24. }
    25. </script>
    26. <style scoped>
    27. .count {
    28. padding: 10px;
    29. border-radius: 10px;
    30. box-shadow: 0 0 10px;
    31. background-color: skyblue;
    32. }
    33. select,
    34. button {
    35. margin: 0px 5px;
    36. height: 25px;
    37. }
    38. </style>

    LoveTalk组件:

    1. <template>
    2. <div class="talk">
    3. <button @click="getLoveTalk">获取一句土味情话</button>
    4. <ul>
    5. <li v-for="talk in talkList" :key="talk.id">
    6. {{ talk.title }}
    7. </li>
    8. </ul>
    9. </div>
    10. </template>
    11. <script setup lang="ts" name="LoveTalk">
    12. import { reactive } from 'vue'
    13. import axios from 'axios'
    14. import { nanoid } from 'nanoid'
    15. import { title } from 'process'
    16. // 数据
    17. let talkList = reactive([
    18. {
    19. id: 'wad1',
    20. title: '莫文蔚的阴天,孙燕姿的雨天,周杰伦的晴天,都不如你和我聊天。'
    21. },
    22. {
    23. id: 'wad2',
    24. title: '“你为什么要害我?”“害你什么?”“害我那么喜欢你!”'
    25. },
    26. {
    27. id: 'wad3',
    28. title: '你知道你和星星有什么区别吗?星星在天上,你在我心里。'
    29. }
    30. ])
    31. // 方法
    32. async function getLoveTalk () {
    33. // 发请求
    34. let result = await axios.get(
    35. 'https://api.uomg.com/api/rand.qinghua?format=json'
    36. )
    37. // 把请求回来的字符串,包装成一个对象
    38. let obj = { id: nanoid(), title: result.data.content }
    39. talkList.unshift(obj)
    40. }
    41. </script>
    42. <style scoped>
    43. .talk {
    44. padding: 10px;
    45. border-radius: 10px;
    46. box-shadow: 0 0 10px;
    47. background-color: orange;
    48. }
    49. select,
    50. button {
    51. margin: 0px 5px;
    52. height: 25px;
    53. }
    54. </style>

    二、搭建 pinia 环境

    第一步:npm install pinia

    第二步:操作src/main.ts

    1. import { createApp } from 'vue'
    2. import App from './App.vue'
    3. /* 引入createPinia,用于创建pinia */
    4. import { createPinia } from 'pinia'
    5. /* 创建pinia */
    6. const pinia = createPinia()
    7. const app = createApp(App)
    8. /* 使用插件 */{}
    9. app.use(pinia)
    10. app.mount('#app')

    此时开发者工具中已经有了pinia选项

    三、存储+读取数据

    1. Store是一个保存:状态业务逻辑 的实体,每个组件都可以读取写入它。
    2. 它有三个概念:state、getter、action,相当于组件中的: data、 computed 和 methods。
    3. 具体编码:src/store/count.ts
    1. import { defineStore } from "pinia";
    2. export const useCountStore = defineStore("count", {
    3. // 真正存储数据的地方
    4. state() {
    5. return {
    6. sum: 6,
    7. };
    8. },
    9. });
    1. 具体编码:src/store/talk.ts
    1. // 引入defineStore用于创建store
    2. import { defineStore } from "pinia";
    3. // 定义并暴露一个store
    4. export const useTalkStore = defineStore("talk", {
    5. // 动作
    6. actions: {},
    7. // 状态
    8. state() {
    9. return {
    10. talkList: [
    11. {
    12. id: "wad1",
    13. title: "莫文蔚的阴天,孙燕姿的雨天,周杰伦的晴天,都不如你和我聊天。",
    14. },
    15. {
    16. id: "wad2",
    17. title: "“你为什么要害我?”“害你什么?”“害我那么喜欢你!”",
    18. },
    19. {
    20. id: "wad3",
    21. title: "你知道你和星星有什么区别吗?星星在天上,你在我心里。",
    22. },
    23. ],
    24. };
    25. },
    26. });
    1. 组件中使用state中的数据
    1. <template>
    2. <div class="count">
    3. <h2>当前求和为:{{ sumStore.sum }}</h2>
    4. <select v-model.number="n">
    5. <option value="1">1</option>
    6. <option value="2">2</option>
    7. <option value="3">3</option>
    8. </select>
    9. <button @click="add"></button>
    10. <button @click="minus"></button>
    11. </div>
    12. </template>
    13. <script setup lang="ts" name="Count">
    14. import { ref } from 'vue'
    15. import { useCountStore } from '@/store/count'
    16. // 数据
    17. let sumStore = useCountStore()
    18. let n = ref(1) //用户选择的数据
    19. // 方法
    20. function add () {
    21. sumStore.sum += n.value
    22. }
    23. function minus () {
    24. sumStore.sum -= n.value
    25. }
    26. </script>
    1. <template>
    2. <div class="talk">
    3. <button @click="getLoveTalk">获取一句土味情话</button>
    4. <ul>
    5. <li v-for="talk in talkStore.talkList" :key="talk.id">
    6. {{ talk.title }}
    7. </li>
    8. </ul>
    9. </div>
    10. </template>
    11. <script setup lang="ts" name="LoveTalk">
    12. import { reactive } from 'vue'
    13. import axios from 'axios'
    14. import { nanoid } from 'nanoid'
    15. import { useTalkStore } from '@/store/talk'
    16. // 数据
    17. let talkStore = useTalkStore()
    18. // 方法
    19. async function getLoveTalk () {
    20. // 发请求
    21. let result = await axios.get(
    22. 'https://api.uomg.com/api/rand.qinghua?format=json'
    23. )
    24. // 把请求回来的字符串,包装成一个对象
    25. let obj = { id: nanoid(), title: result.data.content }
    26. talkStore.talkList.unshift(obj)
    27. }
    28. </script>

    四、修改数据(三种方式)

    1. 第一种修改方式,直接修改countStore.sum = 666
    2. 第二种修改方式:批量修改
    1. countStore.$patch({
    2. sum:999,
    3. school:'atguigu'
    4. })
    1. 第三种修改方式:借助action修改(action中可以编写一些业务逻辑)
    1. import { defineStore } from 'pinia'
    2. export const useCountStore = defineStore('count', {
    3. /*************/
    4. actions: {
    5. //
    6. increment(value:number) {
    7. if (this.sum < 10) {
    8. //操作countStore中的sum
    9. this.sum += value
    10. }
    11. },
    12. //
    13. decrement(value:number){
    14. if(this.sum > 1){
    15. this.sum -= value
    16. }
    17. }
    18. },
    19. /*************/
    20. })
    1. 组件中调用action即可
    1. // 使用countStore
    2. const countStore = useCountStore()
    3. // 调用对应action
    4. countStore.incrementOdd(n.value)

    五、storeToRefs

    • 借助storeToRefs将store中的数据转为ref对象,方便在模板中使用。
    • 注意:pinia提供的storeToRefs只会将数据做转换,而Vue的toRefs会转换store中所有数据包括方法。
    1. <template>
    2. <div class="count">
    3. <h2>当前求和为:{{sum}}</h2>
    4. </div>
    5. </template>
    6. <script setup lang="ts" name="Count">
    7. import { useCountStore } from '@/store/count'
    8. /* 引入storeToRefs */
    9. import { storeToRefs } from 'pinia'
    10. /* 得到countStore */
    11. const countStore = useCountStore()
    12. /* 使用storeToRefs转换countStore,随后解构 */
    13. const {sum} = storeToRefs(countStore)
    14. </script>

    六、getters

    1. 概念:当state中的数据,需要经过处理后再使用时,可以使用getters配置。
    2. 追加getters配置。
    1. // 引入defineStore用于创建store
    2. import {defineStore} from 'pinia'
    3. // 定义并暴露一个store
    4. export const useCountStore = defineStore('count',{
    5. // 动作
    6. actions:{
    7. /************/
    8. },
    9. // 状态
    10. state(){
    11. return {
    12. sum:1,
    13. school:'atguigu'
    14. }
    15. },
    16. // 计算
    17. getters:{
    18. bigSum:(state):number => state.sum *10,
    19. upperSchool():string{
    20. return this. school.toUpperCase()
    21. }
    22. }
    23. })
    1. 组件中读取数据:
    1. const {increment,decrement} = countStore
    2. let {sum,school,bigSum,upperSchool} = storeToRefs(countStore)

    七、$subscribe(订阅)

    通过 store 的 $subscribe() 方法侦听 state 及其变化,类似于watch

    mutate:本次修改的信息

    state:真正修改的数据

    1. talkStore.$subscribe((mutate, state) => {
    2. localStorage.setItem('talkList', JSON.stringify(talkList.value))
    3. })

    八、store组合式写法

    1. import { defineStore } from "pinia";
    2. import axios from "axios";
    3. import { nanoid } from "nanoid";
    4. import { reactive } from "vue";
    5. export const useTalkStore = defineStore("talk", () => {
    6. // talkList就是state
    7. const talkList = reactive(
    8. JSON.parse(localStorage.getItem("talkList") as string) || []
    9. );
    10. // getATalk函数相当于action
    11. async function getLoveTalk() {
    12. // 发请求,下面这行的写法是:连续解构赋值+重命名
    13. let {
    14. data: { content: title },
    15. } = await axios.get("https://api.uomg.com/api/rand.qinghua?format=json");
    16. // 把请求回来的字符串,包装成一个对象
    17. let obj = { id: nanoid(), title };
    18. // 放到数组中
    19. talkList.unshift(obj);
    20. }
    21. return { talkList, getLoveTalk };
    22. });

  • 相关阅读:
    Debezium-Embedded 实时监控MySQL数据变更
    二叉树层序遍历及判断完全二叉树
    产品新闻稿撰写流程是怎样的,纯干货
    Cisco Packet Tracer HSRP技术练习
    JavaScript学习_01——JavaScript简介
    docker 部署node项目
    串行协议——USB驱动[基础]
    【小f的刷题笔记】(JS)数组 - 前缀和 LeetCode303 & LeetCode34
    Java语言的过滤数据流
    CentOS Integration SIG 正式成立
  • 原文地址:https://blog.csdn.net/weixin_51591826/article/details/139031421