从 Vuex 到 Pinia:解决 Pinia 缺失的三个基本功能

简介: 从 Vuex 到 Pinia:解决 Pinia 缺失的三个基本功能

引言



大家应该都知道,Pinia 是 Vue 3 推荐的状态管理插件,而不再是 Vuex。而习惯使用Vuex的你,一定不习惯在开发中无法通过一个全局变量 $store 访问,并且无法在任何地方轻松访问它!

因此,我们今天给大家介绍一种方法,让你在使用 Pinia 时也可以像使用Vuex一样顺畅!

首先了解一下Pinia缺失的三个基本功能:

  1. 1. 使用我们熟悉的 this.$store 访问 store
  2. 2. 有一个嵌套结构的 store
  3. 3. 在 Actions 中访问 Vue Router



基本设置

我们在 src/store 目录下创建了所有的 store,目录结构如下:

- src
  -> store
     -> auth
        -> getters.js
        -> index.js
        -> state.js
     -> index.js
     -> state.js

主要的 index.js 充当完整 store 的入口点,关于嵌套和其他内容的工作原理,我们将在第二步中解释。

// src/store/index.js
import state from "./state.js"
import authStore from "./auth"
export const useStore = defineStore('core', {  
  state: () => state,
  actions: {
    setStores() {
      this.auth = authStore()
    }
  }
})
export default useStore
// src/store/state.js
export default {   
    auth: null,
    version: "1.0.0",
}
// src/store/auth/index.js
import state from "./state.js"
import getters from "./getters.js"
export const useStore = defineStore('auth', {  
  state: () => state,
  getters,
  actions: {
    updateUserToken (token) {
      this.token = token
      localStorage.setItem('token', token)
    }
})
export default useStore
// src/store/auth/state.js
export default {
  token: null
}
// src/store/auth/getters.js
export default {}

在 Pinia 中嵌套存储

Pinia 本质上是为了直接在需要时导入和使用 store,但这不是我们想要的,我们希望像在 Vuex 中那样方便地访问,因此我们做了以下操作:

  • • 在主 store 中创建一个名为 store 的新状态变量,例如 auth
// src/store/state.js
export default {
  auth: null
}
  • • 在主 store 中初始化并设置为想要使用的 Pinia store,例如 authStore,将其添加到我们可以初始化所有需要的 store 的主 store 中的一个 action 中,例如 setStores()
// src/store/index.js
...
import authStore from "./auth"
...
export const useStore = defineStore('core', {  
  state: () => state,
  actions: {
    setStores() {
      this.auth = authStore() // 在 action 中初始化 store
    },
    ... // 其他方法
  }
})
  • • 一旦初始化了主 store,就调用该 action
// main.js
...
import { createPinia } from 'pinia'
...
import store from "@/store"
...
app.use(createPinia()) // 创建 Pinia
export const $store = store() // 初始化主 store
$store.setStores() // 调用 action 初始化所有嵌套 store

现在,所有 store 都可以直接从主 store 中访问,以下是一个示例(Options API):

<script>
import { $store } from "@/main.js"
export default {
    mounted() {
       console.log($store.auth.token) // 访问 auth 的状态
       console.log($store.auth.updateUserToken("12345")) // 调用 auth 的 action
       console.log($store.someState) // 访问主 store 的状态
    }
}
</script>

使 Pinia store 在全局可访问

既然我们的 store 已经嵌套并可以通过单个变量访问,现在是时候通过 vue 的全局属性将其直接访问到组件内部了。为此,我们将使用 vue 中的全局属性进行映射。操作如下:

  • • 在 main.js 中初始化主 store
// main.js
...
import { createPinia } from 'pinia'
...
import store from "@/store"
...
app.use(createPinia()) // 创建 Pinia
export const $store = store() // 初始化主 store
app.config.globalProperties.$store = $store // 使 store 在全局可访问
app.config.globalProperties.$store.setStores() // 调用 action 初始化所有嵌套 store

现在,您可以在组件内部(Options API)中访问它,如下所示:

<script>
export default {
    mounted() {
       console.log(this.$store.auth.token) // 访问 auth 的状态
       console.log(this.$store.auth.updateUserToken("12345")) // 调用 auth 的 action
       console.log(this.$store.someState) // 访问主 store 的状态
    },
    watch: {
        '$store.auth.token'() { console.log("Changed") } // 甚至可以监视它
    } 
}
</script>

在 Pinia Actions 中访问 Vue Router

我们尝试直接在 store 中导入 router 实例并使用它,但感觉不太对,这时我们找到了一个方法,我们可以像这样设置某些属性:

  • • 在 main.js
// main.js
...
import router from '@/router'
...
import { createPinia } from 'pinia'
let pinia = createPinia()
pinia.use({store} => {store.router = router}) // 在此设置 router,以便在 store 中访问
app.use(pinia)
...

这样我们就可以随时在 store 中访问 router 实例了,如下所示:

// src/store/index.js
...
import authStore from "./auth"
...
export const useStore = define
Store('core', {  
  state: () => state,
  actions: {
    logRoute() {
       console.log(this.router) // Router 实例
       console.log(this.router.currentRoute) // 获取当前路由 (this.$route)
    }
    ... // 其他方法
  }
})

通过这种方式,我们解决了我们的三大难题!下面是完整的代码,包含了所有三个功能的实现。

 

目录结构

- src
  -> store
     -> auth
        -> getters.js
        -> index.js
        -> state.js
     -> index.js
     -> state.js
  -> main.js
  -> router
     -> index.js
// src/store/index.js
import state from "./state.js"
import authStore from "./auth"
export const useStore = defineStore('core', {  
  state: () => state,
  actions: {
    setStores() {
      this.auth = authStore()
    }
  }
})
export default useStore
// src/store/state.js
export default {   
    auth: null,
    version: "1.0.0",
}
// src/store/auth/index.js
import state from "./state.js"
import getters from "./getters.js"
export const useStore = defineStore('auth', {  
  state: () => state,
  getters,
  actions: {
    updateUserToken (token) {
      this.token = token
      localStorage.setItem('token', token)
    }
})
export default useStore
// src/store/auth/state.js
export default {
  token: null
}
// src/store/auth/getters.js
export default {}// src/store/auth/state.js
export default {
  token: null
}
// src/store/auth/getters.js
export default {}
// main.js
...
import router from '@/router'
...
import { createPinia } from 'pinia'
let pinia = createPinia()
pinia.use({store} => {store.router = router}) // 在此设置 router,以便在 store 中访问
app.use(pinia)
...
export const $store = store() // 初始化主 store
app.config.globalProperties.$store = $store // 使 store 在全局可访问
app.config.globalProperties.$store.setStores() // 调用 action 初始化所有嵌套 store

以上就是全部内容!如果您发现其他实现相同目标的方法,请告诉我们!

相关文章
|
7月前
|
存储 JavaScript 开发者
Pinia和Vuex的区别
Pinia和Vuex的区别
1759 0
|
7月前
|
存储 缓存 JavaScript
深入了解 Pinia:现代 Vue 应用的状态管理利器
深入了解 Pinia:现代 Vue 应用的状态管理利器
深入了解 Pinia:现代 Vue 应用的状态管理利器
|
存储 JavaScript
vue项目中数据存储(pinia)
vue项目中数据存储(pinia)
166 0
|
2月前
|
存储 JavaScript API
Vuex 和 Pinia 的区别
【10月更文挑战第18天】Vuex 和 Pinia 都有各自的优势和适用场景。Vuex 适合较为大型和复杂的项目,强调严格的架构和流程;而 Pinia 则更适合中小型项目以及对灵活性和简洁性有更高要求的开发者。你可以根据项目的具体需求和个人喜好来选择使用哪一个状态管理库。
610 59
|
2月前
|
存储 缓存 资源调度
Vue3状态管理新选择:Pinia安装与使用详解,以及与Vuex的对比分析
Vue3状态管理新选择:Pinia安装与使用详解,以及与Vuex的对比分析
150 0
|
2月前
|
JavaScript 前端开发 数据管理
vue2知识点:理解vuex、安装vuex、搭建vuex环境
vue2知识点:理解vuex、安装vuex、搭建vuex环境
37 0
|
5月前
|
存储 开发框架 JavaScript
在Vue3项目中使用pinia代替Vuex进行数据存储
在Vue3项目中使用pinia代替Vuex进行数据存储
|
4月前
|
Web App开发 JavaScript 安全
Vue状态管理库Pinia详解
Pinia 是一款专为 Vue 设计的状态管理库,它提供了一套简洁且直观的 API,旨在简化状态管理流程。Pinia 的设计理念强调简单性和易用性,相较于 Vuex,它摒弃了许多复杂的概念如 mutations 和模块的深层嵌套结构,转而提供一种更现代化且与 Vue 3 Composition API 高度兼容的状态管理模式。
|
4月前
|
存储 资源调度 JavaScript
Vue3如何使用Pinia详细介绍、pinia持久化存储(pinia-plugin-persistedstate详细配置)
Vue3如何使用Pinia详细介绍、pinia持久化存储(pinia-plugin-persistedstate详细配置)
|
7月前
|
JavaScript 测试技术 开发者
Vue 3 Vuex:构建更强大的状态管理系统
Vue 3 Vuex:构建更强大的状态管理系统
100 1