pinia学习

pinia状态管理

名字来源

Pinia是西班牙语中菠萝-词最相似的英语发音: pina。菠萝实际上是一组单独的果实, 它们结合在一起形成一 个水果。与store类似, 每个store都是 单独存在的,但它们最终都是相互关联的。它也是一种美味的热带水果, 原产于南美洲。

状态:

Pinia从2019年11月左右,开始尝试重新使用Composition API设计Vue Store.
Pinia试图尽可能接近Vuex的理念,旨在测试Vuex下- -次迭代的一个方案。目前,Vuex 5的open RFC, API与
Pinia的API非常相似,这说明Pinia成功 了。
注意, Pinia的作者(Eduardo), 也是Vue.js核心团队的一员,积极参与Router和Vuex等API的设计。设计Pinia 的
目的是想重新设计使用store的体验,同时保持Vue的容易理解的理念。将Pinia的API与Vuex保持尽可能的接近,
因为它不断向前发展,使人们能够方便地迁移到Vuex,甚至在未来融合两个项目。

特性:

Pinia具有以下几点特性:
●. 直观,像定义components- 样地定义store
●  完整的Typescript支持
●  去除mutations, 只有state, getters, actions
●  actions支持同步和异步
●  Vue Devtools支持Pinia, 提供更好的开发体验
●  能够构建多个stores,实现自动地代码拆分
●  极其轻量(1kb) ,甚至感觉不到它的存在

 使用方式

npm i pinia

 在main.ts中 引入pinia 结构出 createPInia方法  app上use方法调用 createPInia方法

import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
// 1.安装pinia-> npm install pinia
// 2.导入pinia
import { createPinia } from 'pinia'

createApp(App).use(createPinia()).mount('#app')

创建store库

新建store文件夹 在index.ts中书写如下

  1. 从 pinia中 结构拿出defineStore 
  2. 调用defineStore 并导出
  3. 第一个参数为store名字,第二个参数为对象
  4. 在第二个参数对象中 书写state action getter module

import { defineStore } from 'pinia'

export default defineStore('main', {
  state() {
    return {
      count: 10,
      list: [{
        name: "iphone13",
        price: 5880,
        num: 1
      }, {
        name: "MetaPro",
        price: 6880,
        num: 1
      }]
    }
  },
})

页面使用

使用 state

1. 引入导出的仓库函数     ( 这里是:useMainStore )

2. 调用函数                       ( 这里做了赋值 useMainStore() )

3. 也是可以直接通过           {{store.xxx}} 来渲染数据

4. 结构需要从 pinia中拿到 storeToRefs方法,把store转成响应式


修改方式:

  1. 直接store. xxx 进行修改;如果是结构的数据需要去写他的 .value(因为它是个对象)
  2. $patch 方法修改 (方法内部需要传对象)
  3. $patch 方法执行回调函数 传入state对象

重置状态:是调用 store.$reset() 方法

 页面部分:

<script setup lang="ts">
import useMainStore from "./store/index";
import { storeToRefs } from "pinia";

const store = useMainStore();
let { count, sumPrice } = storeToRefs(store);

// state修改的方式
function handleClick() {
  //   store.count++;
  count.value++;
  store.list.push({
    name: "vivo",
    price: 3000,
    num: 1,
  });
}

// $patch修改
function patchClick() {
  store.list.push({
    name: "oppo",
    price: 2000,
    num: 1,
  });
  store.$patch({
    count: store.count + 5,
    list: store.list,
  });
}

//第三种
function patchFnClick() {
  store.$patch((state) => {
    state.count += 10;
    state.list.push({
      name: "mi13",
      price: 2000,
      num: 1,
    });
  });
}

// 将整个store的state替换
function toggleState() {
  store.$state = {
    count: 100,
    timuList: [],
    list: [
      {
        name: "oppo",
        price: 2000,
        num: 1,
      },
      {
        name: "vivo",
        price: 3000,
        num: 1,
      },
    ],
  };
}
// 重置状态
function resetState() {
  store.$reset();
}

// 监听整个仓库变化
store.$subscribe((mutation, state) => {
  console.log("mutation:", mutation);
  console.log("state:", state);
});

// 计算属性
</script>

<template>
  <div>
    <h1>商品总价:{{ store.sumPrice }}</h1>
    <h1>商品总价:{{ sumPrice }}</h1>
    <h1>商品数量:{{ store.count }}</h1>
    <h1>商品数量:{{ count }}</h1>
    <h1>商品列表</h1>
    <ul>
      <li v-for="item in store.list">{{ item.name }}</li>
    </ul>
    <button @click="handleClick">+1</button>
    <button @click="patchClick">+5</button>
    <button @click="patchFnClick">+10</button>
    <button @click="toggleState">替换state</button>
    <button @click="resetState">重置状态</button>

    <button @click="store.getTimu()">获取异步数据</button>

    <h1>题目列表</h1>
    <ul>
      <li v-for="item in store.timuList">
        {{ item.quiz }}
      </li>
    </ul>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 index.ts部分

import { defineStore } from "pinia";
import axios from 'axios';

export default defineStore('main', {
  state: () => {
    return {
      count: 10,
      list: [{
        name: "iphone13",
        price: 5880,
        num: 1
      }, {
        name: "MetaPro",
        price: 6880,
        num: 1
      }],
      timuList: [] as any
    }
  },
  getters: {
    sumPrice: (state) => {
      return state.list.reduce((pre, item) => {
        return pre + (item.price * item.num)
      }, 0)
    }
  },
  // 同步和异步皆可以
  actions: {
    async getTimu() {
      // let result = axios.get('https://www.cpengx.cn/static/timu/timu.json')

      let result = axios.get('/timu.json')
      console.log(result)

      this.timuList = (await result).data;
    }

  }
})

getters:

在store仓库中 和state同级 ,写getters对象 在对象中写方法 要求传入 state


在页面使用:

  1. 可通过store. xxx 的方式 ;
  2. 结构(需要把store转成响应式)

actions:

 actions同步异步都可以

在store仓库中 和state同级 ,写aciton对象 在对象中写方法 


在页面使用:

  1. 可通过store. xxx 的方式 ;
  2. 结构(需要把store转成响应式)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值