目录

Pinia 介绍

pinia 的实现逻辑

Pinia 基本用法


Pinia 介绍

如何实现多个组件之间的数据传递:

        方式1:组件传参 (兄弟传参)

        方式2:路由传参

        方式3:通过pinia状态管理定义共享数据

当我们有多个组件共享一个共同的状态(数据源)时,多个视图可能都依赖于同一份状态。来自不同视图的交互,也可能需要更改同一份状态。

pinia 的实现逻辑

Pinia 基本用法

1. 准备 vite 项目:

npm create vite@4.3.2

npm install

npm install vue-router@4 --save

2. 安装 pinia

npm install pinia

创建 Operate.vue 和 List.vue

router.js:

import {createRouter, createWebHashHistory} from 'vue-router'

import List from '../components/List'
import Operate from '../components/Operate'

const router = createRouter({
    history:createWebHashHistory(),
    routes:[
        {
        path:'/list',
        component:List,
        },
        {
            path:'/operate',
            component:Operate,
        },
        {
            path:'/',
            component:Operate,
        },
    ]
})

export default router

main.js:

import { createApp } from 'vue'

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


let app = createApp(App)
app.use(router)
app.mount('#app')

App.vue:

<script setup>

</script>

<template>
  <div>
    <router-link to = "/operate">operate</router-link> <br>
    <router-link to = "/list">list</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>

<style scoped>

</style>

定义 pinia store 对象 src/store/store.js:

/* 定义共享的 pinia 资源 */
import {defineStore} from 'pinia'

// 定义一个 Person 共享
// 定义数据并且对外暴露
// store 就是定义共享状态的包装对象
// 内部有四个属性: id 唯一标识 state 完整类型推理,推荐使用箭头函数 getters 类似属性计算,存储数据
// 操作的方法:action 存储数据的复杂业务逻辑方法
// 理解:store 类似 Java 中的实体类,id 就是类名,state 就是装数据值的属性,getter 就是 get 方法
// action 就是对数据进行操作的方法

export const definedPerson = defineStore('personPinia' // 当前数据的 id 必须全局唯一
    
    {
        state: () => {
            return {
                username:'张三',
                age:0,
                hobbies:['唱歌','跳舞']
            }
        },
        getters:{
            // 用于定义一些通过数据计算而得到结果的方法
            // 一般在此处不做对数据的修改操作
            // getters 中的方法可以当作属性值方式使用
            getHobbiesCount() {
                return this.hobbies.length
             },
             getAge() {
                return this.age
             },
        },
        actions:{
            // 用于定义一些对数据修改的方法
            doubleAge() {
                this.age = this.age * 2
            }
        }
    }
)

再配置 main.js:

import { createApp } from 'vue'

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

// 开启全局的 pinia 功能
import {createPinia} from 'pinia'
let pinia = createPinia()

let app = createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')

Operate.vue:

<script setup>
    // 导入 pinia 数据
    import {definedPerson} from '../store/store.js'
    let person = definedPerson()
</script>

<template>
  <div>
    <h1> 用于修改 pinia 数据 </h1>
    名字:<input type = 'text' v-model="person.username"><br>
    年龄:<input type = 'text' v-model="person.age"><br>
    <span>{{person.getAge}}</span><br>
    爱好:
        吃饭<input type = "checkbox" value = '吃饭' v-model="person.hobbies">
        睡觉<input type = "checkbox" value = '睡觉' v-model="person.hobbies">
        打豆豆<input type = "checkbox" value = '打豆豆' v-model="person.hobbies">
        唱歌<input type = "checkbox" value = '唱歌' v-model="person.hobbies">
        跳舞<input type = "checkbox" value = '跳舞' v-model="person.hobbies">
        <br>
        <button @click="person.doubleAge()">年龄加倍</button>
        <!-- 恢复默认值 -->
        <button @click ="person.$reset()">恢复默认</button>
        <!-- 一次性修改多个属性 -->
        <button @click ="person.$patch({username:'奥特曼',age:20,hobbies:['晒太阳','打怪兽']})">变身奥特曼</button>
    <hr>
    展示一下 person 中的数据 ==》{{person}}
  </div>
</template>

<style scoped>

</style>

List.vue:

<script setup>
import {definedPerson} from '../store/store.js'
let person = definedPerson()
</script>

<template>
  <div>
    <h1> 用于展示 pinia 数据 </h1>
    读取姓名:{{person.username}} <br>
    读取年龄:{{person.age}}<br>
    通过get得到年龄{{person.getAge}}<br>
    爱好数量:{{person.getHobbiesCount}}<br>
    所有的爱好:
    <ul>
        <li v-for="(hobby,index) in person.hobbies" :key = "index" v-text="hobby"></li>
    </ul>
  </div>
</template>

<style scoped>

</style>

更多推荐