学完 Pinia 再也不想用 vuex 真香啊!!!!

💕Pinia 注册

✔ vue3 与 Pinia 注册

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp()

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

✔ vue2 与 Pinia 注册

import Vue from 'vue'
import App from './App.vue'
import { createPinia, PiniaVuePlugin } from 'pinia'

Vue.use(PiniaVuePlugin)

new Vue({
  render: (h) => h(App),
  createPinia()
}).$mount('#app');

💕定义与使用 Store

✔ 定义 Store

import { defineStore } from 'pinia'

// 第一个参数是应用程序中 store 的唯一 id
export const useUser = defineStore('user', {
    state: () => {
        return { name: 'Jack', age: 18 }
    },
    getters: {},
    actions: {}
})

在这里插入图片描述

✔ 在 vue3 <script setup>中使用

<script setup>
import { useUser } from '@/stores/User'
const user = useUser()    
</script>
<template>
    <div>{{ user.name }} - {{ user.age }}</div>
</template>

✔ 在 vue3 setup() 中使用

<script>
import { useUser } from '@/stores/User'
export default {
    setup() {
        const user = useUser()
        
        return {
            user
        }
    }
}
</script>
<template>
    <div>{{ user.name }} - {{ user.age }}</div>
</template>

✔ 在 vue2 中使用

  1. 导入可读属性,无法修改
<script>
import { useUser } from '@/stores/User'
import { mapState } from 'pinia'
// 导入的是只读属性,无法进行修改    
export default {
    computed: {
        ...mapState(useUser, {
            user: (store) => store,
            // 自定义属性
            ownName: 'age'
            double: (store) => store.age * 2,
            // 通过 this 读取自定义属性值
            magicValue: (store) => {
               return this.double + store.age + this.ownName
           }
        })
        // 也可以采用这种方式
        // ...mapState(useUser, ['age', 'name'])
        // <div>{{ name }} - {{ age }}</div>
    }
}
</script>
<template>
    <button @click="age = 12">尝试修改 age</button>
    <div>{{ user.name }} - {{ user.age }}</div>
</template>

在这里插入图片描述

  1. 导入可读可修改属性
<script>
import { useUser } from '@/stores/User'
import { mapWritableState } from 'pinia'
// 导入的是可修改属性    
export default {
    computed: {
        ...mapWritableState(useUser, {
            user: (store) => store
        })
    }
}
</script>
<template>
    <div>{{ user.name }} - {{ user.age }}</div>
</template>

✔ 使用效果

在这里插入图片描述


💕修改 Store

✔ 直接修改 store

<script setup>
import { useUser } from '@/stores/user'

const user = useUser() // user 是 reactive 对象

// 不能使用 { age, name } = user 进行解绑,具体看注意事项

const handle = () => {
    // 直接修改
    user.age++
}
</script>
<template>
    <div>{{ user.age }} - {{ user.name }}</div>
</template>

✔ 通过 $patch 修改 store

  1. 接收变量的方式
<script setup>
import { useUser } from '@/stores/user'

const user = useUser()

const handle = () => {
    user.$patch({
        name: 'John',
        age: 81
    })
}
</script>
<template>
    <button @click="handle">修改 user 信息</button>
    <div>{{ user.age }} - {{ user.name }}</div>
</template>
  1. 接收函数的方式
<script setup>
import { useUser } from '@/stores/user'

const user = useUser()

const handle = () => {
    user.$patch((state) => {
        // 直接对 state 进行修改
        state.age = 81
        state.name = 'John'
    })
}
</script>
<template>
    <button @click="handle">修改 user 信息</button>
    <div>{{ user.age }} - {{ user.name }}</div>
</template>

在这里插入图片描述

✔ 重置 state

import { useUser } from '@/stores/user'

const user = useUser()

// 重置 (初始状态)
user.$reset()

✔ 替换 state

import { useUser } from '@/stores/user'

const user = useUser()

store.$state = { name: 'Paimon', age: 12 }

💕 订阅 Store

可以通过 $subscribestore 进行订阅。只会在 patches 之后触发一次

import { useUser } from '@/stores/user'
const user = useUser()

user.$subscribe((mutation, state) => {
  console.log(mutation)
  console.log(state)
})

mutation.typepatch object

user.$patch({ name: 'John', age: '81' })

在这里插入图片描述

mutation.typepatch function

user.$patch((state) => {
    state.name = 'John'
    state.age = '81'
})

在这里插入图片描述

mutation.typedirect

user.name = 'John'
user.age = '81'

在这里插入图片描述


💕 定义与使用 Getters

✔ 定义 Getters

import { defineStore } from 'pinia'
import { useOtherStore } from '@/store/otherStore'

// 第一个参数是应用程序中 store 的唯一 id
export const useUser = defineStore('user', {
    state: () => {
        return { name: 'Jack', age: 18 }
    },
    getters: {
        // 访问 state 的值
        doubuleAge: (state) => state.age * 2,
        // 访问 getters 的值(通过 this 进行访问)
        doubleAgePlusOne: (state) => this.doubleAge + 1
        // 访问其他 store 的 getters
        otherstore: () => {
             const otherStore = useOtherStore()
             return state.other
        }
    },
    actions: {}
})

✔ 访问 Getters

<script setup>
import { useUser } from '@/stores/User'
const user = useUser()    
</script>
<template>
    <div>{{ user.name }} - {{ user.age }} - {{ user.doubuleAge }} - {{ user.doubuleAgePlusOne }}</div>
</template>

💕 定义与使用 Actions

✔ 定义 Actions

非常适合定义业务逻辑

import { defineStore } from 'pinia'
import { useOtherStore } from '@/store/otherStore'
// 第一个参数是应用程序中 store 的唯一 id
export const useUser = defineStore('user', {
    state: () => {
        return { name: 'Jack', age: 18 }
    },
    getters: {},
    actions: {
        // 封装业务逻辑
        async registerUser({ name, password }) {
            const data = await api.post({ login, password })
            this.state.name = data.name
            this.state.age = data.age
        }
        // 访问其他的 store
        async fetchUserPreferences() {
           const other = useOtherStore()
           // 获取到 other 的数据
        }
    }
})

actions 可以是异步的,您可以在其中await 任何 API 调用甚至其他操作!

✔ 访问 Actions

import { useUser } from '@/store/user'
const user = useUSer()

// vue3 的方法方式,vue2 的访问方式见注意事项
user.registerUser({
    name: 'john'
    password: '123'
})

💕 定阅 Actions

可以使用 store.$onAction() 订阅 actions 及其结果

const userStore = useUSer()
const unsubscribe = userStore.$onAction(
  ({
    name, // action 的名字
    store, // store 实例
    args, // 调用这个 action 的参数
    after, // 在这个 action 执行完毕之后,执行这个函数
    onError, // 在这个 action 抛出异常的时候,执行这个函数
  }) => {
    // 记录开始的时间变量
    const startTime = Date.now()
    // 这将在 `store` 上的操作执行之前触发
    console.log(`Start "${name}" with params [${args.join(', ')}].`)

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

    // 如果 action 抛出或返回 Promise.reject ,onError 将触发
    onError((error) => {
      console.warn(`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`)
    })
  }
)

// 手动移除订阅
unsubscribe()

💕 Pinia 持久化配置

需要借助 pinia-plugin-persistedstate

import App from './App.vue'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate  from 'pinia-plugin-persistedstate'

const app = createApp(App)
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

app.use(pinia)
// 组合式写法 具体看 注意事项
import { defineStore } from 'pinia'
const persist = {
    key: 'storeKey',
    storage: window.sessionStorage,
    // 部分持久化状态的点符号路径数组,[]意味着没有状态被持久化(默认为undefined,持久化整个状态)
    // paths: ['age']
}
export const useUser = defineStore('user', () => {
  const name = ref('Jack')
  const age = ref(18)
  const session = JSON.parse(window.sessionStorage.getItem('storeKey'))
  if (session) { // 判断 session 是否已经有值存在,实现持久化
    name.value = session.name
    age.value = session.age
  }
  return {
    name, age
  }
}, { persist })

在这里插入图片描述


💕 注意事项

✔ 选项式与组合式写法

// 选项式
import { defineStore } from 'pinia'
export const useUser = defineStore('user', {
  state: () => {
    return {
      name: 'Jack',
      age: 18
    }
  },
  getters: {
    doubuleAge: (state) => state.age * 2,
    doubleAgePlusOne: (state) => this.doubleAge + 1
  },
  actions: {
      async registerUser() {/*.......*/}
  }
})

等价于:

import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useUser = defineStore('user', () => {
    // state
    const name = ref('Jack')
    const age = ref(18)
    
    // getters
    const doubuleAge = ref()
    doubuleAge.value = age.value * 2
    const doubleAgePlusOne = ref()
    doubleAgePlusOne.value = doubuleAge.value + 1
    
    // actions
    const registerUser = () => { /*.......*/ }
    
    return {
        name,
        age,
        doubuleAge,
        doubleAgePlusOne,
        registerUser
    }
})

✔ 解构失去响应式

<script setup>
import { useUser } from '@/stores/user'
const user = useUser()

// user 是 reactive 对象

let { age, name } = user // 解构失去了响应式,不解构是不会失去响应式的

const handle = () => {
  age++ // 修改值
  console.log(age) // 修改后
}
</script>
<template>
    <button @click="handle">尝试修改 age</button>
    <div>{{ name }} - {{ age }}</div>
</template>

在这里插入图片描述

解决办法:使用 storeToRefs ,它将为任何响应式属性创建 refs

import { storeToRefs } from 'pinia'
import { useUser } from '@/stores/user'
const user = useUser()
let { age, name } = storeToRefs(user) // 有了响应式

const handle = () => {
  age.value = age.value + 1 // 注意
}

✔ 取消订阅 Store

默认情况下,state subscriptions 绑定到添加它们的组件。当组件被卸载时,它们将被自动删除。如果要在卸载组件后保留它们,可以进行以下操作:

<script setup>
import { useUser } from '@/stores/user'
const user = useUser()

// 此订阅将在组件卸载后保留
user.$subscribe((mutation, state) => {
  console.log(mutation)
  console.log(state)
}, { detached: true })
</script>

✔ 取消订阅 Actions

默认情况下,action subscriptions 绑定到添加它们的组件。当组件被卸载时,它们将被自动删除。如果要在卸载组件后保留它们,可以进行以下操作:

<script setup>
import { useUser } from '@/stores/user'
const user = useUser()

// 此订阅将在组件卸载后保留
user.$onAction(() => {/* ..... */}, true)
</script>

✔ vue2 将 Actions 印射到组件

import { mapActions } from 'pinia'
import { useUser } from '@/stores/user'
export default {
  methods: {
    ...mapActions(useUser, ['registerUser'])
    ...mapActions(useUser, { myOwnName: 'registerUser' }),
  },
}

✔ 如何监听整个 Pinia 状态

import { createApp, watch } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp()

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

app.use(pinia)
app.mount('#app')

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/299561.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java推荐系统:好友推荐思路

1.表的设计 表里面就两个字段&#xff0c;一个字段是用户id&#xff0c;另外一个字段是好友id&#xff0c;假如A跟B互为好友&#xff0c;那在数据库里面就会有两条数据 2.推荐好友思路 上面的图的意思是&#xff1a;h跟a的互为好友&#xff0c;a跟b&#xff0c;c&am…

Python笔记04-数据容器列表、元组、字符串、集合、字典

文章目录 listtuple 元组str序列&#xff08;切片&#xff09;setdict集合通用功能 Python中的数据容器&#xff1a; 一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为1个元素 每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等…

JavaWeb——新闻管理系统(Jsp+Servlet)之jsp新闻删除

java-ee项目结构设计 1.dao:对数据库的访问&#xff0c;实现了增删改查 2.entity:定义了新闻、评论、用户三个实体&#xff0c;并设置对应实体的属性 3.filter&#xff1a;过滤器&#xff0c;设置字符编码都为utf8&#xff0c;防止乱码出现 4.service:业务逻辑处理 5.servlet:处…

Qt/QML编程学习之心得:Linux下USB接口使用(25)

很多linux嵌入式系统都有USB接口,那么如何使用USB接口呢? 首先,linux的底层驱动要支持,在linux kernal目录下可以找到对应的dts文件,(device tree) usb0: usb@ee520000{compatible = "myusb,musb";status = "disabled";reg = <0xEE520000 0x100…

Unity中Shader序列帧动画(总结篇)

文章目录 前言一、半透明混合自定义调整1、属性面板2、SubShader中3、在片元着色器(可选)3、根据纹理情况自己调节 二、适配Build In Render Pipeline三、最终代码 前言 在前几篇文章中&#xff0c;我们依次解决了实现Shader序列帧动画所遇到的问题。 Unity中Shader序列图动画…

2.C++的编译:命令行、makefile和CMake

1. 命令行编译 命令行编译是指直接在命令行中输入以下指令&#xff1a; 预处理&#xff1a;gcc -E main.c -o main.i 编译&#xff1a;gcc -S main.i -o main.s 汇编&#xff1a;gcc -c main.s -o main.o 链接&#xff1a;gcc main.o -o main 命令汇总&#xff1a;gcc main.c …

LabVIEW开发自动读取指针式仪表测试系统

LabVIEW开发自动读取指针式仪表测试系统 在工业领域&#xff0c;尤其是煤矿、变电站和集气站等环境中&#xff0c;指针式仪表因其简单的结构、抗干扰能力强以及能适应高温高压等恶劣环境条件而被广泛应用于设备运行状态监视。然而&#xff0c;传统的人工读表方式不仅成本高昂&…

【Leetcode】移除后集合的最多元素数

目录 &#x1f4a1;题目描述 &#x1f4a1;思路 &#x1f4a1;总结 100150. 移除后集合的最多元素数 &#x1f4a1;题目描述 给你两个下标从 0 开始的整数数组 nums1 和 nums2 &#xff0c;它们的长度都是偶数 n 。 你必须从 nums1 中移除 n / 2 个元素&#xff0c;同时从 …

SpringMVC源码解析——HTTP请求处理(持续更新中)

在SpringMVC源码解析——DispatcherServlet的逻辑处理中&#xff0c;最后介绍到了org.springframework.web.servlet.DispatcherServlet的doDispatch方法中关于处理Web HTTP请求的核心代码是调用AbstractHandlerMethodAdapter类的handle方法&#xff0c;源码如下&#xff1a; /*…

04-微服务-Nacos

Nacos注册中心 国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心&#xff0c;SpringCloudAlibaba也推出了一个名为Nacos的注册中心。 1.1.认识和安装Nacos Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在…

[redis] redis的安装,配置与简单操作

一、缓存的相关知识 1.1 缓存的概念 缓存是为了调节速度不一致的两个或多个不同的物质的速度&#xff0c;在中间对速度较慢的一方起到加速作用&#xff0c;比如CPU的一级、二级缓存是保存了CPU最近经常访问的数据&#xff0c;内存是保存CPU经常访问硬盘的数据&#xff0c;而且…

Matlab二维绘图

低级绘图命令line 有什么点就点哪里&#xff0c;然后连起来&#xff0c;没什么细节&#xff0c;不光滑&#xff0c;所以基本不会用到。 x0:0.2*pi:2*pi; ysin(x); line(x,y);%画一条sin函数线 line([-5,5],[2,2]);%画一条水平线 line([5,5],[0,2]);%画一条竖线 高级绘图命令…

1867_noweb简介

Grey 全部学习内容汇总&#xff1a; GitHub - GreyZhang/g_org: my learning trip for org-mode 1867_noweb简介 noweb是一个简单可扩展的文学式编程工具&#xff0c;操作简单且不限制编程语言。 主题由来介绍 本质上来说&#xff0c;我对noweb没有太多的了解欲望。但是我…

5.云原生安全之kubesphere应用网关配置域名TLS证书

文章目录 cloudflare配置使用cloudflare托管域名获取cloudflare API Token在cloudflare中配置SSL/TLS kubesphere使用cert-manager申请cloudflare证书安装证书管理器创建Secret资源创建cluster-issuer.yaml创建cert.yaml申请证书已经查看申请状态 部署harbor并配置ingress使用证…

机器学习笔记 - 基于OpenCV+稀疏光流的无监督运动检测

一、简述 在各种高级开源库的帮助下&#xff0c;检测固定摄像机拍摄的运动行为是轻而易举可以实现的&#xff0c;但检测移动的摄像机拍摄的移动物体的运动检测依然是一个复杂的问题。在这里&#xff0c;我们将继续基于稀疏光流&#xff0c;并检测移动的无人机相机的运动。 这里…

2024年道路运输企业主要负责人证考试题库及道路运输企业主要负责人试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年道路运输企业主要负责人证考试题库及道路运输企业主要负责人试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人…

STL标准库与泛型编程(侯捷)笔记2

STL标准库与泛型编程&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCo…

企业网盘全方位解读:热门云存储工具的优势与适用场景

企业网盘无疑是当下最热门的企业协同工具。什么是企业网盘&#xff1f;企业网盘与个人网盘又有什么不同呢&#xff1f;一文全方位解读企业网盘这一热门云存储工具。 什么是企业网盘 企业网盘为企业级文件存储、管理与共享平台&#xff0c;企业团队可以在企业网盘中存储企业文…

2024.1.6 关于 Redis 数据类型 Zset 常用命令

目录 Zset 基本概念 Zset 命令操作 ZADD ZRANGE ZREVRANGE ZCARD ZCOUNT ZRANGEBYSCORE ZPOPMAX BZPOPMAX ZPOPMIN BZPOPMIN ZRANK ZREVRANK ZSCORE ZREM ZREMRANGEBYRANK ZREMRANGEBYSCORE ZINCRBY Zset 基本概念 Set&#xff08;集合&#xff09; 元素具…

ARM笔记-----输入捕获

输入捕获可以对输入的信号的上升沿、下降沿或者双边沿进行捕获&#xff0c;常用的有测量输入信号的脉 宽&#xff0c;和测量 PWM 输入信号的频率和占空比这两种。 输入捕获的大概的原理 当捕获到信号的跳变沿的时候&#xff0c;把计数器 CNT 的值锁存到捕获寄 存器 CCR 中…