好,这一段是 Pinia 的 settings 全局配置仓库 ,再加上 VueUse 的暗黑模式 。
你现在问的是 「语法结构」 ,我就不扯业务细节 ,专门把 每一层语法是干嘛的、为什么这样写 讲清楚。
一、整体结构一眼看懂
ts
import ...
import ...
const xxx = ...
const yyy = ...
const useSettingsStore = defineStore(
'settings',
{
state: () => ({}),
actions: {}
}
)
export default useSettingsStore
👉 这是 Pinia 的标准 Store 定义结构
可以拆成 5 个语法层级:
import(依赖引入)- 顶层普通变量(非响应式)
defineStore定义 storestate:响应式状态actions:方法(可改 state)
二、import 语法层
ts
import defaultSettings from '@/settings'
- 默认导入
defaultSettings是一个普通 JS 对象(不是响应式)
ts
import { useDark, useToggle } from '@vueuse/core'
- 命名导入
- VueUse 提供的组合式函数
ts
import { useDynamicTitle } from '@/utils/dynamicTitle'
- 自定义工具函数
- 修改
document.title
三、普通变量(不属于 Pinia)
ts
const isDark = useDark()
const toggleDark = useToggle(isDark)
语法重点
- 写在 store 外面
- 只会执行一次
- 不会被 Pinia 重建
ts
isDark // Ref<boolean>
toggleDark() // 切换 isDark.value
👉 这是 组合式 API + Pinia 混用的典型写法
四、解构默认配置(ES6 解构语法)
ts
const {
sideTheme,
showSettings,
navType,
tagsView,
tagsIcon,
fixedHeader,
sidebarLogo,
dynamicTitle,
footerVisible,
footerContent
} = defaultSettings
等价于:
ts
const sideTheme = defaultSettings.sideTheme
const showSettings = defaultSettings.showSettings
...
作用:
- 减少
defaultSettings.xxx的重复书写 - 提高可读性
五、localStorage 读取(短路语法)
ts
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
语法点
JSON.parse(null)→nullnull || ''→''
👉 所以 storageSetting 要么是对象,要么是空字符串
⚠️ 这也是为什么下面频繁用 === undefined 判断
六、defineStore 语法结构(重点)
ts
const useSettingsStore = defineStore(
'settings',
{
state: () => ({}),
actions: {}
}
)
1️⃣ 'settings'
ts
'settings'
-
store 的唯一 ID
-
用于:
- devtools
- pinia 持久化
- 跨模块引用
2️⃣ state: () => ({})
ts
state: () => ({
title: '',
theme: ...,
isDark: isDark.value
})
语法规则
- 必须是 函数
- 返回一个 普通对象
- Pinia 内部会自动转为
reactive
等价概念:
ts
const state = reactive({
title: ''
})
3️⃣ state 中的"或运算符 + 三元"
典型例子:
ts
theme: storageSetting.theme || '#409EFF'
ts
navType:
storageSetting.navType === undefined
? navType
: storageSetting.navType
为什么不用 ||
ts
false || true // 会变成 true(不符合预期)
所以用:
ts
=== undefined ? 默认值 : 本地值
👉 这是一个非常成熟的 JS 防坑写法
七、actions 语法结构
1️⃣ 普通方法写法
ts
actions: {
changeSetting(data) {
...
}
}
等价于:
ts
changeSetting: function (data) {}
但这是 ES6 简写
2️⃣ this 的含义(关键)
ts
this[key] = value
在 Pinia 的 actions 中:
this👉 store 实例- 等价于:
ts
const store = useSettingsStore()
store[key] = value
3️⃣ hasOwnProperty 防御式写法
ts
if (this.hasOwnProperty(key)) {
this[key] = value
}
防止:
- 写入不存在的字段
- 拼写错误污染 store
4️⃣ setTitle 的语法重点
ts
setTitle(title) {
this.title = title
useDynamicTitle()
}
- 修改 state
- 调用副作用函数
- actions 可以有副作用(state 不行)
5️⃣ 切换暗黑模式
ts
toggleTheme() {
this.isDark = !this.isDark
toggleDark()
}
语法重点:
this.isDark:Pinia 状态toggleDark():VueUse 的 ref 操作- 两者同步,但不是同一个对象
八、export default
ts
export default useSettingsStore
使用方式:
ts
const settingsStore = useSettingsStore()
settingsStore.toggleTheme()
九、一句话总结「语法结构」
这是「选项式 Pinia + 组合式 API」的混合写法
| 部分 | 作用 |
|---|---|
| import | 引入依赖 |
| 顶层 const | 非响应式工具 |
| defineStore | 定义 store |
| state | 响应式数据 |
| actions | 修改 state 的方法 |
如果你下一步想搞清楚:
- 🔍 为什么 isDark 不直接放 state 里
- 🧠 defineStore vs setup store 的区别
- 🧹 怎么改成 setup 风格
你直接说一句:
"讲 Pinia setup 写法" 或 "这段怎么简化" 就行。