Vue08天禹老师主讲

3 篇文章 0 订阅

Pinia的理解

集中式状态管理

准备一个效果

加数字,变成字符串拼接,如何改变

方法一:v-model.number=“n”

    <div class="count">
        <h2>当前求和为:{{sum}}</h2>
        <select name="" id="" 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>

方法二:

            <option :value="1">1</option>
            <option :value="2">2</option>
            <option :value="3">3</option>

LoveTalk.vue

准备一个数组,生成之后,再给他放进数组,这个之前没见过!

还有下面一个命名

Axios 是一个 基于 promise 的 HTTP 客户端,适用于 node.js 和浏览器。

<template>
    <div class="talk">
        <button @click="getLoveTalk">获取一句土味情话</button>
        <ul>
            <li v-for="talk in talklist" :key="talk.id">{{talk.title}}</li>
        </ul>
    </div>
</template>

<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: '今天天气好2' },
        { id: 'ftrfasdf03', title:'今天天气好3'}
    ])
//方法
    async function getLoveTalk() {
        //发请求
        let result = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
        console.log(result);
        console.log(result.data);
        console.log(result.data.content);
        //把请求回来的字符,包装成一个对象
        let obj = {id:nanoid(),title:result.data.content} //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title  {data:{content:title}}
        //放到数组中
        talklist.unshift(obj)
    }
</script>

搭建pinia环境

安装pinia包

npm i pinia

main.ts

//引入pinia
import {ceratePinia} from 'pinia'
//创建pinia
const pinia = createPinia()
//安装pinia
app.use(pinia)

存储+读取数据

注意小点:

let obj = reactive({
a:1,
b:2,
c:ref(3)
})
let x = ref(9)
console.log(obj.a) //1
console.log(obj.b) //2
console.log(obj.c) //3,在reactive里面就可以直接不用.value
console.log(x) //ref实例对象
console.log(x.value) //9

存储数据 store/count.ts

import { defineStore } from 'pinia'

export const useCountStore = defineStore('count', {
    //state真正存储数据的地方
    state() {
        return {
            sum: 6
        }
    }
})

读取数据 Count.vue

<script setup lang="ts" name="Count">
    import { ref } from 'vue';
    import { useCountStore } from '@/store/count'

const countStore = useCountStore()
    console.log('@@@', countStore);
    //以下两种都可以拿到state中的数据
// console.log('@@@',countStore.sum);
    console.log('@@@',countStore.$state.sum);
</script>

修改数据

第一种修改方式

    <script setup lang="ts" name="Count">
//方法
    function add() {
        //第一种修改方式
        countStore.sum += 1
	}
     </script>

第二种修改方式

    <script setup lang="ts" name="Count">
//方法
    function add() {
        //第二种方式 数据很多的时候
        countStore.$patch({
            sum: 9,
            school: '北京',
            address:'朝阳'
        })
	}
     </script>

第三种修改方式

Count.vue

    <script setup lang="ts" name="Count">
//方法
    function add() {
        //第三种修改方式
        countStore.increment(n.value)
	}
     </script>

store/count.ts

 export const useCountStore = defineStore('count', {  
	actions: {
        increment(value: number) {
            console.log('increment被调用了', value)
            //修改数据 this是当前的store
            console.log(this.sum); //6
            this.sum += 1

        }
    }
 })

storeToRefs

将方法可以放到lovetalk.ts里面

export const useLoveTalkStore = 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 } //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title  {data:{content:title}}
            // //放到数组中
            this.talkList.unshift(obj)
        }
    }
})

在LoveTalk.vue里面可以直接调用

<script setup lang="ts" name="LoveTalk">
    import { useLoveTalkStore } from '@/store/lovetalk';
    
    const talkStore = useLoveTalkStore()
  
    //方法
    function getLoveTalk() {
        talkStore.getATalk()
    }
</script>

如何调用数据写法更简洁,使用storeTorefs

h3标题里面不用写countStore.sum、countStore.school 、countStore.address

<template>
    <div class="count">
        <h2>当前求和为:{{sum}}</h2>
        <h3>欢迎来到:{{ school }},坐落于{{ address }}</h3>
        <select name="" id="" 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>

<script setup lang="ts" name="Count">
    import { ref,toRefs } from 'vue';
    import { useCountStore } from '@/store/count'
    import { storeToRefs } from 'pinia';

    const countStore = useCountStore()
    //storeToRefs只会关注store中数据,不会对方法进行ref包裹
    const {sum,school,address} = storeToRefs(countStore)
    console.log('@@@', storeToRefs(countStore));

    //数据
    let n = ref(1) //用户选择的数字

    function minus() {
       countStore.sum -= n.value  
    }
</script>
<template>
    <div class="talk">
        <button @click="getLoveTalk">获取一句土味情话</button>
        <ul>
            //下面这行里面不用写talkStore.talkList
            <li v-for="talk in talkList" :key="talk.id">{{talk.title}}</li>
        </ul>
    </div>
</template>

<script setup lang="ts" name="LoveTalk">
    import { useLoveTalkStore } from '@/store/lovetalk';
    
    import { storeToRefs } from 'pinia';
    const {talkList} = storeToRefs(talkStore)

</script>

getters的使用

当state中的数据,需要经过处理后再使用时,可以使用getters配置

count.ts

export const useCountStore = defineStore('count', {
    //state真正存储数据的地方
    state() {
        return {
            sum: 6,
            school: 'beijing',
            address: 'chaoyang'
        }
    },
    getters: {
        // bigSum(state) {
        //     return state.sum * 10
        // },
        //第二种写法
        bigSum: state => state.sum * 10,

        upperSchool(state) {
            return state.school.toUpperCase()  //这里state改成this也可以
        }
    }
})
<template>
    <div class="count">
        <h2>当前求和为:{{sum}},放大十倍后{{ bigSum }}</h2>
        <h3>欢迎来到:{{ school }},大写为:{{ upperSchool }},坐落于{{ address }}</h3>
        <select name="" id="" 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>

<script setup lang="ts" name="Count">
    import { ref,toRefs } from 'vue';
    import { useCountStore } from '@/store/count'
    import { storeToRefs } from 'pinia';

    const countStore = useCountStore()
    //storeToRefs只会关注store中数据,不会对方法进行ref包裹
    const {sum,school,address,bigSum,upperSchool} = storeToRefs(countStore)

    //数据
    let n = ref(1) //用户选择的数字

</script>

$subscribe的使用

通过store的$subscribe()方法侦听state及其变化

<script setup lang="ts" name="LoveTalk">
    import { useLoveTalkStore } from '@/store/lovetalk';
    import { storeToRefs } from 'pinia';
    
    const talkStore = useLoveTalkStore()
    const { talkList } = storeToRefs(talkStore)
    talkStore.$subscribe((mutate,state) => {
        console.log('talkStore里面保存的数据发生了变化',mutate,state);
        localStorage.setItem('talkList',JSON.stringify(state.talkList))
    })
  
    //方法
    function getLoveTalk() {
        talkStore.getATalk()
    }
</script>

lovetalk.ts 可以不是放一个固定数组,去上面本地存储的获取的数据,但如果一开始本地啥都没有,就是null,如果null重新获取unshift就无法取得数据,所以加一个或者||[]给一个空数组。注意:前面必须加JSON.parse不然无法解析

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

export const useLoveTalkStore = 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 } //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title  {data:{content:title}}
            // //放到数组中
            this.talkList.unshift(obj)
        }
    },
    //state真正存储数据的地方
    state() {
        return {
            talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
        }
    }
})
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值