从 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

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

相关文章
|
4月前
|
存储 缓存 JavaScript
深入了解 Pinia:现代 Vue 应用的状态管理利器
深入了解 Pinia:现代 Vue 应用的状态管理利器
深入了解 Pinia:现代 Vue 应用的状态管理利器
|
4月前
|
JavaScript 开发者
Vue状态管理: 在Vuex中,什么是mutation?它们应该如何使用?
Vue状态管理: 在Vuex中,什么是mutation?它们应该如何使用?
95 4
|
20天前
|
Web App开发 JavaScript 安全
Vue状态管理库Pinia详解
Pinia 是一款专为 Vue 设计的状态管理库,它提供了一套简洁且直观的 API,旨在简化状态管理流程。Pinia 的设计理念强调简单性和易用性,相较于 Vuex,它摒弃了许多复杂的概念如 mutations 和模块的深层嵌套结构,转而提供一种更现代化且与 Vue 3 Composition API 高度兼容的状态管理模式。
|
2月前
|
存储 开发框架 JavaScript
在Vue3项目中使用pinia代替Vuex进行数据存储
在Vue3项目中使用pinia代替Vuex进行数据存储
|
4月前
(学习笔记)抛弃 Vuex,使用 Pinia
(学习笔记)抛弃 Vuex,使用 Pinia
52 1
|
JavaScript
一文解析Pinia和Vuex,带你全面理解这两个Vue状态管理模式(上)
一文解析Pinia和Vuex,带你全面理解这两个Vue状态管理模式(上)
131 0
|
缓存 JavaScript
一文解析Pinia和Vuex,带你全面理解这两个Vue状态管理模式(下)
一文解析Pinia和Vuex,带你全面理解这两个Vue状态管理模式(下)
171 0
|
JavaScript 前端开发 中间件
|
SQL 存储 缓存
Vue3中状态管理pinia学习(八)
Vue3中状态管理pinia学习(八)
246 2
Vue3中状态管理pinia学习(八)
|
存储 SQL 缓存
Vue3中状态管理pinia学习(六)
Vue3中状态管理pinia学习(六)
236 2
Vue3中状态管理pinia学习(六)