首页 > 其他分享 >Pinia 简单使用

Pinia 简单使用

时间:2024-02-28 11:49:09浏览次数:21  
标签:count const Pinia 简单 state pinia 使用 import store

更新记录

更新记录
2024年2月28日 初始化。

Pinia 是什么

状态管理包,允许跨组件/页面共享状态。

Pinia 和 Vuex 对比

最大最大的区别,Pinia没有mutations概念,这个东西真的很恶心。
从ExtJS转过来,看Pinia不要太爽,和ExtJS的Store的概念简直一模一样。

安装包

npm install pinia

注册 Pinia 插件

进入 src/main.js

import './assets/main.css'
import { createApp } from 'vue'
//引入Pinia
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)
//使用插件
app.use(createPinia())
app.use(router)

app.mount('#app')

创建初始Stores文件夹

用来存放具体的Store。如果是用的官方脚手架生成的基架,这一切都是自动的。

创建 具体 Store(选项式 API )

defineStore 函数

通过 defineStore 定义一个名为 xxx 的Store。
官方推荐使用 use 开头命名 Store 进行导出。

三个概念,state、getter 和 action,类似组件中的 data、 computed 和 methods。

创建 scr/stores/user.js文件

import { defineStore } from 'pinia'
export const useUserStore = defineStore("user", {
});

state

import { defineStore } from 'pinia'
export const useUserStore = defineStore("user", {
  state: () => {
      return {
        name: "ll",
        age: 18,
        count: 100,
     };
  },
});

action

Actions 支持同步和异步方法。

同步:

  state: () => ({
    count: 0,
  }),
  actions: {
    //同步
    increment() {
      this.count++;
    },
    //异步
    async fetchHomeBanner() {
      const res = await fetch("http://panda666/home/waDataAsync");
      const data = await res.json();
      this.banners = data.data.banner.list;
    },
  },

getters

export const useUserStore = defineStore("user", {
  state: () => ({
    name: "ll",
    age: 18,
    count: 100,
  }),
  getters: {
    doubleCount(state) {
      return state.count * 2;
    },
    getUserById(state) {
        return (id: number) => state.userList.find((item) => item.id === id);
    },
  },
});

创建 具体 Store(组合式 API )

和 选项式API 类似

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  //state
  const count = ref(0);
  //getter
  const doubleCount = computed(() => count.value * 2);
  //actions
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

使用 Store

在 App.vue 中直接引入 useCounterStore 进行调用,然后创建 具体Store的实例对象。

<script setup>
import { useCounterStore } from "@/stores/counter";
// 注意:这里导入的函数,不能被解构,那么会失去响应式。
// 例如不能这样: const { count, increment, decrement, doubleCount } = useCounterStore();
const counterStore = useCounterStore();
</script>

<template>
  <div class="app-wrapper">
    <div>count:{{ counterStore.count }}</div>
    <div>doubleCount:{{ counterStore.doubleCount }}</div>
    <div>
      <button @click="counterStore.increment()">增加</button>
      <button @click="counterStore.decrement()">减少</button>
    </div>
  </div>
</template>

<style scoped></style>

操作 State

读取 state

<template>
  <h1>我是child组件</h1>
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
</template>
<script setup>
import { useUsersStore } from "../src/stores/user";
const store = useUsersStore();
const { name, age, sex } = store;  //纯读取
</script>

修改 state

import { storeToRefs } from 'pinia';  //重要
const store = useUsersStore();
//用于修改需要转为ref
const { name, age, sex } = storeToRefs(store);
//修改
age++;
store.age++;

批量修改 state

const counterStore = useCounterStore();
const add = () => {
  // 调用 $patch 同时应用多个修改
  counterStore.$patch({
    count: 10,
    // ...可同时修改多个属性
  });
};

或者

userStore.$patch( state => {
        state.count++
        state.arr.push(1)
    })

重置 state

const counterStore = useCounterStore();
const resetStore = () => {
  // 调用 $reset 函数进行数据重置为初始值
  counterStore.$reset();
};

注意:在 Setup Stores 中,您需要创建自己的 $reset() 方法

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)

  function $reset() {
    count.value = 0
  }

  return { count, $reset }
})

替换 state

const counterStore = useCounterStore();
const replaceState = () => {
  // 通过 $state 直接赋值替换整个对象
  counterStore.$state = {
    count: 100,
  };
};

订阅state

当state发生变化,就会触发。
通过 store 的 $subscribe() 方法侦听 state 及其变化。

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // 和 cartStore.$id 一样
  mutation.storeId // 'cart'
  // 只有 mutation.type === 'patch object'的情况下才可用
  mutation.payload // 传递给 cartStore.$patch() 的补丁对象。

  // 每当状态发生变化时,将整个 state 持久化到本地存储。
  localStorage.setItem('cart', JSON.stringify(state))
});

默认情况下,state subscription 会被绑定到添加它们的组件上 (如果 store 在组件的 setup() 里面)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,请将 { detached: true } 作为第二个参数,以将 state subscription 从当前组件中分离:

<script setup>
const someStore = useSomeStore()
// 此订阅器即便在组件卸载之后仍会被保留
someStore.$subscribe(callback, { detached: true })
</script>

使用 watch() 函数侦听整个 state

watch(
  pinia.state,
  (state) => {
    // 每当状态发生变化时,将整个 state 持久化到本地存储。
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

订阅action

通过 store.$onAction() 来监听 action 和结果。

const unsubscribe = someStore.$onAction(
  ({
    name, // action 名称
    store, // store 实例,类似 `someStore`
    args, // 传递给 action 的参数数组
    after, // 在 action 返回或解决后的钩子
    one rror, // action 抛出或拒绝的钩子
  }) => {
    // 为这个特定的 action 调用提供一个共享变量
    const startTime = Date.now()
    // 这将在执行 "store "的 action 之前触发。
    console.log(`Start "${name}" with params [${args.join(', ')}].`)

    // 这将在 action 成功并完全运行后触发。
    // 它等待着任何返回的 promise
    after((result) => {
      console.log(
        `Finished "${name}" after ${
          Date.now() - startTime
        }ms.\nResult: ${result}.`
      )
    })

    // 如果 action 抛出或返回一个拒绝的 promise,这将触发
    one rror((error) => {
      console.warn(
        `Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
      )
    })
  }
)

// 手动删除监听器
unsubscribe()

默认情况下,action 订阅器会被绑定到添加它们的组件上(如果 store 在组件的 setup() 内)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,请将 true 作为第二个参数传递给 action 订阅器,以便将其从当前组件中分离:

<script setup>
const someStore = useSomeStore()
// 此订阅器即便在组件卸载之后仍会被保留
someStore.$onAction(callback, true)
</script>

状态持久化-pinia-plugin-persistedstate

避免刷新浏览器的时候出现数据丢失,将需要持久化存储的数据添加到localStorage或sessionStore中。
使用:pinia-plugin-persistedstate 插件。

安装

 npm i pinia-plugin-persistedstate

全局配置

在 src/stores/index.js 中引入插件

import { createPinia } from "pinia"
// 引入持久化插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const store = createPinia()
// 将插件提供给store实例
store.use(piniaPluginPersistedstate)

export default store

使用

在需要持久化的store中引入即可。因为我们定义store有两种方式,因此持久化也有对应的书写方式

Store(state的方式):

import { defineStore } from 'pinia'
export const useUserStore = defineStore("user", {
  state: () => ({
    name: "ll",
    age: 18,
    count: 100,
  }),
  //....
  // 表示这个store里的数据都将持久化存储
  persist: true
});

Store(函数式方式)

import { defineStore } from 'pinia'
import { reactive, toRefs } from "vue"

export const useUserStore = defineStore("user", ()=>{
    return {
        ...toRefs(state),
        fullName,
        updateLastName
    }
}, {
    // 注意defineStore的第三个参数可以传入插件配置
    persist: true
});

只持久化部分数据

设置配置文件

在 src/utils 目录下新建 persist.js 文件,修改存储配置:

import  { PersistedStateOptions } from 'pinia-plugin-persistedstate'
/**
 * @description pinia持久化参数配置
 * @param {String} key 存储到持久化的 name
 * @param {Array} paths 需要持久化的 state name
 * @return persist
 * */
const piniaPersistConfig = (key, paths) => {
	const persist = {
		key,
		storage: window.localStorage,
		// storage: window.sessionStorage,
		paths
	}
	return persist
}

export default piniaPersistConfig

注册插件

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

const pinia = createPinia()
pinia.use(piniaPluginPersist)

在 Store 中使用

修改store中的持久化配置

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 1 }),
  // 开启数据缓存
  persist: {
    enabled: true
  }
})

//或者

const useUserStore = defineStore('user', () => {
    return {
        ...toRefs(state),
    	fullName,
        updateLastName
    }
}, {
    // 注意defineStore的第三个参数可以传入插件配置,根据配置只持久化lastName
    persist: piniaPersistConfig('user', ['lastName'])
})

参考链接

https://blog.logrocket.com/complex-vue-3-state-management-pinia/
https://www.zhihu.com/question/521159639
https://pinia.vuejs.org/

https://zhuanlan.zhihu.com/p/605989666
https://juejin.cn/post/7204735957777203260
https://zhuanlan.zhihu.com/p/533233367
https://pinia.web3doc.top/

标签:count,const,Pinia,简单,state,pinia,使用,import,store
From: https://www.cnblogs.com/cqpanda/p/17309952.html

相关文章

  • springboot两种配置文件的使用(举例:端口号、虚拟路径配置)
    1、properties配置文件使用   2、yml配置文件、yaml配置文件 在项目中更常用 在项目中一般yml配置文件更为常用,因为yml层级更加明确、清晰,更为关注数据。 ......
  • C#简单爬虫实现
    一、环境.netcore6.0vs2022控制台应用程序Nuget引入:AngleSharp1.1.0用于HTML解析Downloader3.0.6用于下载文件 ShellProgressBar5.2.0用于进度条显示二、效果 三、相关代码1.Program.csusingShellProgressBar;usingSpider;usingSystem.Collections;......
  • Spring Boot使用BESApplicationServer宝兰德替换内嵌Tomcat
    移除自带tomcat<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>${spring.version}</version>......
  • Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件
    场景Pythont通过request以及BeautifulSoup爬取几千条情话:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/87348030Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/124182289Jsoup......
  • pure-ftpd安装与使用(转载)
    一、摘要FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为"文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户......
  • selenium使用总结
    1.网页爬取fromseleniumimportwebdriverbrowser=webdriver.Edge()#python根路径配置驱动文件browser.get('')soup=BeautifulSoup(browser.page_source)soup.prettify()2.下拉框选择、网页点击、输入框#下拉框选择sel_element1=browser.find_element_by......
  • Apscheduler 使用Redis集群做为任务存储
    背景由于原生的apscheduler仅支持redis单节点连接,不支持redis集群,所以本人基于原生的RedisJobStore自己修改了一个专门用于连接redis集群的类RedisClusterJobStore修改点有以下内容:修改类名RedisJobStore为RedisClusterJobStore将原始导入的redis替换为rediscluster将原始......
  • Mybatis系列之(五)Mybatis在使用基于代理Dao的方式实现增删改查时都干了啥事儿
    Mybatis在使用基于代理Dao的方式实现增删改查时都干了啥事儿绝对路径:可能出现机器中没有D盘的情况,需要修改代码相对路径:部署项目后src就不存在了,需要修改代码基于以上两点,读取配置文件仅通过图中的两种方式进行读取构建者模式:专业的事儿由专业的人来做工厂模式:需要新的类的对......
  • 使用pySCENIC分析单细胞转录因子活性
    ###---------------------1.Downloaddemosinglecellsequencingdata---------------###wgethttp://cf.10xgenomics.com/samples/cell-exp/3.0.0/pbmc_10k_v3/pbmc_10k_v3_filtered_feature_bc_matrix.tar.gztarxvfpbmc_10k_v3_filtered_feature_bc_matrix.tar.gz###--......
  • SQL 中使用 CONVERT转日期格式
    以下两种情况是相同的select*fromEmployeewhereUpdateTime>=convert(char(23),'2024-02-2600:00:00.00',121)andUpdateTime<=convert(char(23),'2024-02-2723:59:59.999',121)select*fromEmployee whereUpdateTime>='2024-02-......