pinia使用

pinia使用

安装和引入

  • 在使用pinia时需要将模块下载并且需要引入

下载pinia

 # yarn
yarn add pinia
# 或 npm
npm i -D pinia

引入pinia

方式一:在main.ts
  • main.ts中引用
const app = createApp(App);
// 引入pinia
import { createPinia } from "pinia";
// 初始化pinia
const pinia = createPinia();
app.use(pinia);
方式二:定义 文件导出
  • 方式二看得会稍微简洁些,但是官方写法是方式一中的,可以根据自己的需求来选择
// 引入pinia
import { createPinia } from "pinia";
// 初始化pinia
const pinia = createPinia();
// 导出pinia
export default pinia;
  • 导出后在main.ts中再去引用
import pinia from "@/store/index";
app.use(pinia);

效果也是一样的

定义和使用store

定义

  • 需要定义的名字一定要为唯一的,否则会有冲突
  • 后面的花括号中就是一些其它数据选项,如果想把后面对象单独拎出来,后面要想修改数据会用到this,正是如此不建议单独拎出来。
  • 如果单独拿出来此时的this指向就变了
import { defineStore } from 'pinia'

export const useStore = defineStore('需要定义的名字', {
 // 其它的一些数据选项
})

使用sore

  • 如果使用,需要定义数据之类的,和在vuex中类似,语法形式像vue2
state的定义
  • 在vuex中会看到state,在vuex中state后面直接跟着花括号即可,但是在pinia中需要写成函数式,在官方中推荐使用箭头函数,因为有利于推断类型
  • 在这种定义的user,需要在state中返回一个对象
import { defineStore } from "pinia";

export const userStore = defineStore("user", {
  state: () => {
    return {
      count: 0,
      age: 18,
    };
  },
});
  • 使用函数式原因
    1. 使用return 防止数据污染
    2. 推荐使用箭头函数,因为可以更好的类型推理

修改state值

  • 修改state值就需要用到actions,这时就不用像state再去写函数式了,直接写成对象即可,如下所示
  • 直接使用this之后点出state中的值,之后在对其进行需要的操作
import { defineStore } from "pinia";

export const userStore = defineStore("user", {
  // 状态值
  state: () => {
    return {
      count: 0,
      age: 18,
    };
  },
  // 修改值
  actions: {
    // 修改age
    getAge() {
      this.age++;
    },
  },
});

这就是为什么在上面所说不要单独拎出来后面的对象,否则this的指向也会改变

getters计算属性

  • 在vuex中也会有getters属于计算属性,如果不了解可以参考vue中的computed属性和其类似
  • 写法和action差不多,注意后面是花括号不是函数,并且要把处理好的数据返回出去!!!
import { defineStore } from "pinia";

export const userStore = defineStore("user", {
  state: () => {
    return {
      count: 0,
      age: 18,
    };
  },
    
  // 相当于compute的 计算属性
  getters: {
    getterAge(state: any) {
      return `仓库中的${state.age + 5}`;
    },
  },
  
  actions: {
    // 修改age
    getAge() {
      this.age++;
    },
    // 修改count
    getCount() {
      this.count++;
    },
  },
});

在组件中使用

  • 和vuex不同的是,pinia很多都是响应式,只要改了仓库中的数据也会发生改变,除了结构时会有个坑,但是只要外边包个函数即可解决这个问题

不解构方式使用

  • 使用值方式有很多种,下面说三种全都是响应式的,十分的简单
  • 在下面代码中就已经获取到了仓库中的数据
import { userStore } from "@/store/user"; // 引入仓库
const store = userStore();// 使用
// 状态
const State = reactive({
  age: computed(() => store.age),
});

const store = userStore();// 使用

注意是函数,不是直接解构出来就可以用的

组件使用
  • 值的使用
    • 可以使用reactive的方式去使用
    • 也可以直接用store.xxx的方式去使用
    • 也可以在reactive中使用计算属性去使用
  • 函数的使用—和值使用的方式一样,需要去要点击事件等,直接调用即可,根据自己的需求
<template>
  <h1>pinia使用</h1>
  <h4>有计算属性的age:{{ State.age }}</h4>
  <h4>没有计算属性的age:{{ store.age }}</h4>
  <h4>仓库中计算属性的age:----{{ store.getterAge }}</h4>
  <h4>结构出来的的age:----{{ age }}</h4>
  <h4>结构出来的的count:----{{ count }}</h4>
    
  <button @click="store.getAge()">点击增加-age</button>
  <button @click="store.getCount()">点击增加-count</button>
  <button @click="HandelFun.changeAge">在组件中直接修改age</button>
</template>

解构方式使用

  • 在结构时如果解构的是state中的数据,会出现不是响应式的问题,如果状态修改并不会引起值的更新,这时候需要映入storeToRefs如下所示
import { storeToRefs } from "pinia"; // 解决结构后值不是响应式
  • 之后只需要将仓库数据用这个包起来就行了
// 如果这样写是不会有响应式的,但是可以把函数结构出来可以用,只是不会是响应式的
const { age, count } = userStore(); 
// 通过这种方式可以将数据结构但是不能结构出函数,数据是响应式的
const { age, count } = storeToRefs(userStore()); 
在组件函数中使用
  • 直接调用即可
const HandelFun = reactive({
  // 在组件中直接修改age也是响应式的
  changeAge() {
    store.age++;
  },
});

直接在组件中修改

  • 在组件中直接修改当前仓库中的值也是可以的,效果也是响应式的

批量修改

方式一

  • 如果相对仓库中状态的值想做多个修改,可以使用$patch,使用方式如下
store.$patch({
  age: 100,
  count: 100,
});
  • 如果仓库中当前需要修改的值没有,但是还是加上了,例如下面这样,没有namelist
store.$patch({
  age: 100,
  count: 100,
  name: "哈哈哈哈",
  list: [1, 2, 3, 4, 5, 6],
});

如果仓库中没有上面两个值,但是有需要加上,直接修改再去state中找是没有的

  <!-- 修改多个值 -->
  <h2>{{ store.age }}</h2>
  <h2>{{ store.count }}</h2>
  <h2 v-if="store.$state.name">{{ store.$state.name }}</h2>
  <h2 v-if="store.$state.list">{{ store.$state.list }}</h2>
  <button @click="HandelFun.changeState">修改多个值</button>

需要使用store.$state.xxx

方式二

  • 可以直接使用$patch的箭头函数形式去做
  changeState2() {
    console.log(store);

    store.$patch((state: any) => {
      state.name = "方式二修改";
      state.age = 888;
      state.count = 888;
      state.list = [6, 6, 6, 6, 6];
    });
  },

getters高阶函数

  • 如果想对getters进行传参,需要使用到高阶函数,不要忘记一定要return
getterAge(state) {
  return (data: number) => {
    if (data) state.age = data;
    else {
      `仓库中的${state.age + 5}`;
    }
  };
},
  • 在组件中需要对函数进行传值
<!-- 对getters中进行传参该怎么做 -->
<h2>{{ store.age }}</h2>
<button @click="store.getterAge(10)">对getters传参</button>

actions处理异步请求

  • 需要安装axios

store中

 actions: {
    // 模拟获取数据
    async getApi() {
      const result = await axios.get("https://api.apiopen.top/api/sentences");
      this.getApiObj = result.data.result;
      return result.data.result;
    },
  },

点按钮取数据

<h2>模拟获取数据</h2>
<h3>诗名:{{ store.getApiObj.from }}</h3>
<h3>诗句:{{ store.getApiObj.name }}</h3>
<button @click="store.getApi">获取数据</button>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值