13、Vue-组合式-状态管理

60 阅读2分钟

主要是为了集中对组件状态进行管理,不同组件之间获取其他组件当前状态

点击前往官方文档

一、官方示例-reactive

1、新建一个store目录用于存储状态管理相关文件

2、store目录下新建index.js

import { reactive } from 'vue'

// 所有的状态可以都定义到这里
export const store = reactive({
  counter: 0    // 定义一个简单的计数器
})

3、app.vue中进行使用

<script setup>
// 不管在js中使用状态还是html中使用状态都需要导入
import {store} from "./store/index"
function addHandle(){
    store.counter++
}
</script>

<template>
    <!--js中调用-->
    <button @click="addHandle">计数器增加</button>
    <!--html中调用-->
    <button @click="store.counter--">计数器减少</button>

    <p>计数器当前值:{{store.counter}}</p>
</template>

效果预览:

其实,通过前面的学习,想要实现一个类似的效果非常简单。比如修改app.vue为下述代码:

<script setup>
import {ref} from "vue";

const counter = ref(0)
</script>

<template>
    <!--js中调用-->
    <button @click="counter++">计数器增加</button>
    <!--html中调用-->
    <button @click="counter--">计数器减少</button>

    <p>计数器当前值:{{counter}}</p>
</template>

reactive和上述简单示例的区别在于:定义在reactive中的状态可以被所有组件很轻易调用。

二、官方推荐状态管理插件:Pinia

以前官方推荐的是vuex,现在推荐的是Pinia

前往插件官网

1、安装

Vue项目内使用下述命令进行插件安装

npm install --save pinia

2、基础示例

1)新建一个store目录存储状态相关文件

2)新建一个index.js用于统一存储状态,代码如下

import {defineStore} from "pinia";
import {ref} from "vue";

// 定义store, 第一个参数是应用中store的唯一Id
export const usePiniaStore = defineStore('usePiniaStore',()=>{
  // 定义一个计数器状态
  const counter = ref(0)
  // 定义一个计数器操作方法
  function counterAdd(){
    counter.value++
  }

  // 返回出来
  return {counter, counterAdd}
})

注意:

  • 上述的代码使用的是 Setup Store的创建方式,跟vue的组合式Api比较相似。还有一种Option Store, 跟选项式比较相似。这里不进行演示
  • 可以创建尽可能多的defineStore来进行状态的管理,而不是在一个defineStore中添加多个状态。多个状态管理之间可以使用store.stateName状态名.属性名的方式进行相互调用

3)修改main.js使用状态管理

import {createApp, ref} from 'vue'
import App from './App.vue'
import router from "./router/index";

import {createPinia} from "pinia";  // 导入pinia
const pinia = createPinia() // 创建引用

const app = createApp(App)
app.use(router)
app.use(pinia)  // 使用
app.mount('#app')

3)app.vue中使用状态

<script setup>
import {usePiniaStore} from "@/store";
const piniaStore = usePiniaStore()
function counterHandle(){
    piniaStore.counter--
}
</script>

<template>
    <!--使用index.js中定义的方法-->
    <button @click="piniaStore.counterAdd()">计数器增加</button>
    <!--在js中调用-->
    <button @click="counterHandle">计数器减少</button>
    <!--html中调用-->
    <p>计数器当前值:{{piniaStore.counter}}</p>
</template>

效果就不演示了,跟官方示例的效果相同

三、总结

好吧,其实我好像没有看出 reactivepinia之间的区别。

官方给出的说法是如果正在开发的是服务端渲染(SSR)的应用,使用 reactive会有问题。

等到后续如果有深度使用了再来补充心得吧