Skip to content

getActivePinia()

getActivePinia() 函数返回当前活动的 Pinia 实例。这在需要访问当前 Pinia 实例的场景中很有用。

函数签名

ts
function getActivePinia(): Pinia | undefined

参数

无参数。

返回值

  • 类型: Pinia | undefined
  • 描述: 当前活动的 Pinia 实例,如果没有活动实例则返回 undefined

基础用法

获取活动实例

js
import { getActivePinia } from 'pinia'

const pinia = getActivePinia()
if (pinia) {
  console.log('找到活动的 Pinia 实例')
} else {
  console.log('没有活动的 Pinia 实例')
}

检查实例状态

js
import { getActivePinia } from 'pinia'

function checkPiniaStatus() {
  const pinia = getActivePinia()
  
  if (!pinia) {
    throw new Error('Pinia 实例未初始化')
  }
  
  return pinia
}

常见用例

1. 插件开发

在开发 Pinia 插件时获取当前实例:

js
function myPiniaPlugin() {
  const pinia = getActivePinia()
  
  if (!pinia) {
    console.warn('插件需要活动的 Pinia 实例')
    return
  }
  
  // 使用 pinia 实例进行插件逻辑
  pinia.use((context) => {
    // 插件逻辑
  })
}

2. 工具函数

创建需要访问 Pinia 的工具函数:

js
import { getActivePinia } from 'pinia'

function getAllStores() {
  const pinia = getActivePinia()
  
  if (!pinia) {
    return []
  }
  
  // 返回所有注册的 stores
  return Array.from(pinia._s.values())
}

function getStoreById(id) {
  const pinia = getActivePinia()
  
  if (!pinia) {
    return undefined
  }
  
  return pinia._s.get(id)
}

3. 调试和开发工具

js
import { getActivePinia } from 'pinia'

function debugPiniaState() {
  const pinia = getActivePinia()
  
  if (!pinia) {
    console.log('没有活动的 Pinia 实例')
    return
  }
  
  console.log('Pinia 实例信息:')
  console.log('- 注册的 stores 数量:', pinia._s.size)
  console.log('- 插件数量:', pinia._p.length)
  console.log('- 状态:', pinia.state.value)
}

4. 条件性 Store 创建

js
import { getActivePinia, createPinia, setActivePinia } from 'pinia'

function ensurePiniaInstance() {
  let pinia = getActivePinia()
  
  if (!pinia) {
    console.log('创建新的 Pinia 实例')
    pinia = createPinia()
    setActivePinia(pinia)
  }
  
  return pinia
}

高级用法

实例监控

js
import { getActivePinia } from 'pinia'

class PiniaMonitor {
  constructor() {
    this.checkInterval = null
  }
  
  startMonitoring() {
    this.checkInterval = setInterval(() => {
      const pinia = getActivePinia()
      
      if (pinia) {
        this.logPiniaStats(pinia)
      } else {
        console.warn('Pinia 实例丢失')
      }
    }, 5000)
  }
  
  stopMonitoring() {
    if (this.checkInterval) {
      clearInterval(this.checkInterval)
      this.checkInterval = null
    }
  }
  
  logPiniaStats(pinia) {
    console.log('Pinia 统计:', {
      stores: pinia._s.size,
      plugins: pinia._p.length,
      timestamp: new Date().toISOString()
    })
  }
}

实例比较

js
import { getActivePinia } from 'pinia'

function comparePiniaInstances(expectedPinia) {
  const currentPinia = getActivePinia()
  
  if (!currentPinia) {
    return {
      match: false,
      reason: '没有活动的 Pinia 实例'
    }
  }
  
  if (currentPinia === expectedPinia) {
    return {
      match: true,
      reason: '实例匹配'
    }
  }
  
  return {
    match: false,
    reason: '实例不匹配',
    current: currentPinia,
    expected: expectedPinia
  }
}

安全访问模式

js
import { getActivePinia } from 'pinia'

function withActivePinia(callback, fallback = null) {
  const pinia = getActivePinia()
  
  if (!pinia) {
    console.warn('没有活动的 Pinia 实例,使用回退值')
    return fallback
  }
  
  try {
    return callback(pinia)
  } catch (error) {
    console.error('使用 Pinia 实例时出错:', error)
    return fallback
  }
}

// 使用示例
const storeCount = withActivePinia(
  (pinia) => pinia._s.size,
  0 // 回退值
)

TypeScript 用法

ts
import { Pinia, getActivePinia } from 'pinia'

function getTypedActivePinia(): Pinia {
  const pinia = getActivePinia()
  
  if (!pinia) {
    throw new Error('没有活动的 Pinia 实例')
  }
  
  return pinia
}

// 类型守卫
function hasActivePinia(): boolean {
  return getActivePinia() !== undefined
}

// 条件类型
type PiniaOrUndefined = ReturnType<typeof getActivePinia>

function processActivePinia(): string {
  const pinia: PiniaOrUndefined = getActivePinia()
  
  if (pinia) {
    return `找到 Pinia 实例,包含 ${pinia._s.size} 个 stores`
  }
  
  return '没有活动的 Pinia 实例'
}

错误处理

安全检查

js
import { getActivePinia } from 'pinia'

function safeGetActivePinia() {
  try {
    return getActivePinia()
  } catch (error) {
    console.error('获取活动 Pinia 实例时出错:', error)
    return undefined
  }
}

验证实例

js
import { getActivePinia } from 'pinia'

function validateActivePinia() {
  const pinia = getActivePinia()
  
  if (!pinia) {
    throw new Error('需要活动的 Pinia 实例')
  }
  
  if (!pinia._s) {
    throw new Error('Pinia 实例损坏:缺少 stores 映射')
  }
  
  if (!pinia._p) {
    throw new Error('Pinia 实例损坏:缺少插件数组')
  }
  
  return pinia
}

最佳实践

1. 始终检查返回值

js
// 正确
const pinia = getActivePinia()
if (pinia) {
  // 使用 pinia
}

// 错误 - 不检查 undefined
const pinia = getActivePinia()
pinia._s.size // 如果 pinia 是 undefined 会出错

2. 在适当的时机调用

js
// 正确 - 在 Vue 应用设置后调用
function afterAppSetup() {
  const pinia = getActivePinia()
  // 使用 pinia
}

// 避免 - 在模块加载时调用
const pinia = getActivePinia() // 可能还没有设置

3. 缓存结果(如果适用)

js
class PiniaService {
  constructor() {
    this._cachedPinia = null
  }
  
  getPinia() {
    if (!this._cachedPinia) {
      this._cachedPinia = getActivePinia()
    }
    return this._cachedPinia
  }
  
  invalidateCache() {
    this._cachedPinia = null
  }
}

常见陷阱

1. 假设总是有活动实例

js
// 错误 - 假设总是有实例
function badExample() {
  return getActivePinia()._s.size
}

// 正确 - 检查实例存在
function goodExample() {
  const pinia = getActivePinia()
  return pinia ? pinia._s.size : 0
}

2. 在错误的时机调用

js
// 有问题 - 在导入时调用
const globalPinia = getActivePinia()

// 更好 - 在函数中调用
function getCurrentPinia() {
  return getActivePinia()
}

3. 不处理实例变化

js
// 有问题 - 缓存可能过时的实例
const cachedPinia = getActivePinia()

// 更好 - 每次都获取当前实例
function getCurrentStoreCount() {
  const pinia = getActivePinia()
  return pinia ? pinia._s.size : 0
}

相关函数

相关链接

Released under the MIT License.