VUE入门:pinia实现兄弟通讯

前言

Pinia是一个专为Vue.js设计的状态管理库,特别是针对Vue 3进行了优化。它由Vue.js官方团队维护,提供了一种简单、直观且强大的方式来管理Vue.js应用程序中的状态。 今天我们将学习Pinia,并且通过使用他来实现兄弟通讯

实现兄弟通讯

在上一篇的文章中我们学习了子父组件通讯的4种方法,(希望你不会忘记,如果忘记了请及时回去复习),那么现在让我们想想,如何实现兄弟通讯?

场景

现在我给你3个组件,App.vue作为根组件,add.vue和count.vue作为兄弟组件分别需要实现递加和传入初始值的功能。怎么实现以下效果?

实操

首先可以明确的是需要在App.vue中引入两个子组件,然后实现add.vue和count.vue之间的通讯。实现他俩的通讯需要新建一个文件,将这个文件中的值抛出,然后再到这两文件中引入,有点子小麻烦。

全局文件:

csharp 复制代码
// 在src下新建的文件
import { ref } from 'vue'
export const num = ref(0)

兄弟组件:

add.vue 复制代码
<template>
    <div>
        <button @click="num++">add -- {{ num }}</button>
    </div>
</template>

<script setup>
import { num } from '@/global'
</script>

兄弟组件:

count.vue 复制代码
<template>
    <div>
        {{ num }}
    </div>
</template>

<script setup>
import { num } from '@/global'
</script>

最后功能是实现了,但是怎么多少有点自欺欺人的味道呢?这时候

Pinia

在我们上面的尝试中,虽然勉强算是实现了兄弟通讯,但这种通讯方式在大型项目中的安全漏洞会非常多,在开发复杂的项目时,我们就不得不使用今天的主角------------ pinia

Pinia 是 Vue 的专属状态管理库,它允许我们跨组件或页面共享状态。它提供了比Vuex更简洁、更强大的API,同时完全兼容Vue 3的组合式API。学习理解和熟练的使用pinia是我们在以后的开发过程中必不可少的技能,点击下方链接查阅Pinia官方文档,让我们快速上手。

Pinia | The intuitive store for Vue.js (vuejs.org)

快速上手

安装Pinia

  1. 在你的安装包中安装pinia依赖包
node 复制代码
    npm install pinia
  1. 新建store文件夹,添加默认入口文件index.js,从刚安装的pinia依赖包中引入createPinia实例,并将他抛出。
index.js 复制代码
import { createPinia } from 'pinia'

const store = createPinia()

export default store    // 全局生效

注释:。在同一个模块中,可以使用多次export 语句来导出多个内容。每个模块只能有一个export default ,表示默认导出。当有多个export default语句时,后面的会覆盖前面的

  1. 在mian.js中引入刚刚创建的文件中抛出的pinia状态管理库实例,并在VUE上use他。和当初学习路由一样的操作。
main.js 复制代码
import store from '@/store'

createApp(App).use(store).mount('#app')
  1. 在store库中新建一个分库,我命名为user.js,我向pinia库中引入defineStore,将这个包实例化,可以在这个包中存储一些数据,将他向外抛出
  • defineStore 主要作用是定义和创建一个新的store实例,可以用来存储和管理全局状态或应用级别的数据

  • state:一个函数,返回一个对象,用于存储全局数据。

js 复制代码
// 引入defineStore,存储全局的变量
import { defineStore } from 'pinia' 

// 将全局变量定义为useUserStore并向外抛出
export const useUserStore = defineStore({
    id: 'user',
// 在state中我写入了我的数据,这些数据可以在其他文件中引入
    state: () => {  
        return {
            userInfo: {
                name: '绵绵冰',
                age: 18,
                sex:'女'
            },
        }
    },
})
  1. 现在你可以在其他vue文件中引入你刚刚配置的数据
vue 复制代码
<template>
    <ul>
    // 在此判断是否能成功引入你刚刚配置的数据
        <li>姓名:{{ userStore.userInfo.name }}</li>
    </ul>
</template>

<script setup>
// 引入你刚刚配置的数据
import { useUserStore } from "@/store/user";
// 实例化你引入的数据
const userStore = useUserStore();

console.log(userStore);
</script>

兄弟通讯实操运用

新建一个updata.vue文件,作为user.vue的兄弟文件,在根组件中引入updata.vue。 实现点击按钮时,改变数据中的name。

轻车熟路,我们直接通过@click绑定函数,再使用userStore.userInfo.name = '绵绵冰2号'将数据中的'绵绵冰'变成'绵绵冰2号'。但是这无疑还是会带来一个问题------------如果有很多兄弟组件同时更改这个属性时怎么办?这样的话还是会造成混乱。

actions

怎么解决这个问题?defineStore中的actions允许你在他其中内置函数,我们可以内置一个函数changeUserName,当点击事件触发时执行他。同样的,更改其他属性值也是一样,比如sex

store中的user.js 复制代码
actions: { 
        changeUserName(name) {
            this.userInfo.name = name
        },
        changeSex(sex) {
            this.userInfo.sex = sex
        }
    }
updata.vue 复制代码
// 兄弟组件中执行更改名字的操作
const changeName = () => {
    // userStore.userInfo.name = '绵绵冰2号',这种方法不好
    userStore.changeUserName('绵绵冰2号') 
}

响应式

在更改属性中,例如在更改sex属性时,如果在组件user.vue中获取sex的方式是const sex = userStore.userInfo.sex时,调用actions方法更改不会有效果,因为虽然仓库里的数据userStore.userInfo.sex是响应式的,但通过赋值后的sex却不是。在此处,我们有2个方法可以解决这个问题。

  1. 使用 computed 他会监听变量发生的改变并返回改变后的值
js 复制代码
const sex = computed(() => { return userStore.userInfo.sex; });
  1. 使用 storeToRefs 他能使得传入的数据再赋值之后变为响应式
js 复制代码
import { storeToRefs } from "pinia";
// userInfo里面的数据都变成了响应式
const { userInfo } = storeToRefs(userStore)

getters

getters是仓库中的计算属性,例如当你需要计算十年后你的年龄时你就可以使用 getters,在其中直接定义afterAge方法,在组件中直接通过 userStore.afterAge 调用。

js 复制代码
// 仓库中的计算属性,专门用来获取 state
 getters: {  
        afterAge(state) {
            return state.userInfo.age + 10
        }
    }

persist本地存储

经过上文的一些更改手段,数据可以在前端得到改变,但是当页面刷新时数据又恢复了原样,如何使得更改后的数据持久化存在?

  1. 安装pinia-plugin-persist
node 复制代码
   npm i pinia-plugin-persist
  1. 在仓库中引入
js 复制代码
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

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

export default store
  1. 进行本地存储
js 复制代码
// 开启数据持久化,将数据存储进浏览器中
persist: { 
        enabled: true,
        strategies: [
            {
                paths: ['userInfo'],
                storage: localStorage,
            }
        ]
    }

经过上述操作,更改后的数据将会被存储在浏览器中不会被刷新

相关推荐
joan_852 分钟前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
程序猿进阶3 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
m0_7482361133 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_748248941 小时前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_748235611 小时前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink6 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
LCG元7 小时前
【面试问题】JIT 是什么?和 JVM 什么关系?
面试·职场和发展
迷雾漫步者7 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart