前端面经-VUE3篇(四)--pinia篇-基本使用、store、state、getter、action、插件

一、基本使用

1、什么是 Pinia?

Pinia 是 Vue.js 的官方状态管理库,是 Vuex 的“升级版”。它专为 Vue 3 和 Composition API 设计,用于管理多个组件之间共享的数据(也叫“全局状态”)。

2、为什么需要状态管理库?

在 Vue 中,多个组件如果需要共享数据(例如登录用户信息、购物车内容、权限配置等),仅使用 props 和 emits 会变得非常复杂。这时就需要一个“中心仓库”来统一管理这些数据 —— 这就是 Pinia 的作用。

举个例子

假设你有一个购物车组件、一个商品列表组件和一个订单组件,都需要访问或修改购物车的内容。这种“共享数据”就是 Pinia 的用武之地。

在没有 Pinia 的情况下你可能需要这样做:

  • 商品列表通过 emit 告诉父组件加入购物车

  • 父组件再传递数据给购物车组件

  • 数据很容易混乱且难以追踪

用 Pinia 后,这些组件可以直接访问全局共享的购物车数据,逻辑清晰,易于维护。

3、 基本使用

1. 配置 Pinia 到 Vue 应用在 main.js 或 main.ts 中引入并注册:
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const app = createApp(App)
const pinia = createPinia()app.use(pinia)
app.mount('#app')2. 创建一个 Store(状态模块)
你可以把每个业务逻辑写在一个独立的 store 文件中,例如:
// stores/counter.js 或 counter.ts
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {state: () => ({count: 0}),getters: {doubleCount: (state) => state.count * 2},actions: {increment() {this.count++}}
})
state: 用来定义数据getters: 类似于计算属性actions: 用来修改数据(支持异步)
3. 在组件中使用 Store
<script setup>
import { useCounterStore } from '@/stores/counter'const counter = useCounterStore()function addOne() {counter.increment()
}
</script><template><div>当前计数:{{ counter.count }}</div><div>双倍计数:{{ counter.doubleCount }}</div><button @click="addOne">+1</button>
</template>

二、store

1、什么是 Pinia 的 Store?

在 Pinia 中,store 是用来集中管理状态、逻辑和数据的地方。它就像是一个“全局的数据容器”,供多个 Vue 组件共享和操作。

每一个 store 都是独立的模块,可以包含:

  • state(状态数据)

  • getters(计算属性)

  • actions(行为函数)

 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字。这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use... 是一个符合组合式函数风格的约定。

import { defineStore } from 'pinia'// 你可以任意命名 `defineStore()` 的返回值,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。
// (比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {// 其他配置...
})

defineStore() 的第二个参数可接受两类值:Setup 函数或 Option 对象。

1、Option Store​

与 Vue 的选项式 API 类似,我们也可以传入一个带有 stateactions 与 getters 属性的 Option 对象

export const useCounterStore = defineStore('counter', {state: () => ({ count: 0, name: 'Eduardo' }),getters: {doubleCount: (state) => state.count * 2,},actions: {increment() {this.count++},},
})
你可以认为 state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods)。

2、Setup Store​

也存在另一种定义 store 的可用语法。与 Vue 组合式 API 的 setup 函数 相似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。

export const useCounterStore = defineStore('counter', () => {const count = ref(0)const doubleCount = computed(() => count.value * 2)function increment() {count.value++}return { count, doubleCount, increment }
})

在 Setup Store 中:

  • ref() 就是 state 属性
  • computed() 就是 getters
  • function() 就是 actions

注意,要让 pinia 正确识别 state,你必须在 setup store 中返回 state 的所有属性。这意味着,你不能在 store 中使用私有属性。不完整返回会影响 SSR ,开发工具和其他插件的正常运行。 

2、使用 Store​

虽然我们前面定义了一个 store,但在我们使用 <script setup> 调用 useStore()(或者使用 setup() 函数,像所有的组件那样) 之前,store 实例是不会被创建的:

<script setup>
import { useCounterStore } from '@/stores/counter'
// 可以在组件中的任意位置访问 `store` 变量 ✨
const store = useCounterStore()
</script> 

请注意,store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value。就像 setup 中的 props 一样,我们不能对它进行解构

<script setup>
import { useCounterStore } from '@/stores/counter'
import { computed } from 'vue'const store = useCounterStore()
// ❌ 这将不起作用,因为它破坏了响应性
// 这就和直接解构 `props` 一样
const { name, doubleCount } = store
name // 将始终是 "Eduardo" //
doubleCount // 将始终是 0 //
setTimeout(() => {store.increment()
}, 1000)
// ✅ 这样写是响应式的
// 💡 当然你也可以直接使用 `store.doubleCount`
const doubleValue = computed(() => store.doubleCount)
</script>

 3、如何从 Pinia 的 store 中 解构变量 的同时 保持响应式

 在 Vue 中,如果你这样写:const { name, doubleCount } = useCounterStore()

那么 namedoubleCount失去响应性,也就是说它们变成了普通变量,不再随着 store 的状态变化自动更新页面。 

 使用 storeToRefs():

import { storeToRefs } from 'pinia'const store = useCounterStore()
const { name, doubleCount } = storeToRefs(store)

 storeToRefs() 会把 store 中的所有响应式属性(stategetters转换成 ref 对象,从而保留响应性。

const { increment } = store

这里可以直接解构 action,因为:

  • actions 本身就是函数

  • 它们是绑定过 this 的,不需要 ref 包装

  • 所以解构时不会失效,直接拿来调用即可

4、总结

属性类型是否需要 storeToRefs()是否保持响应性是否可以解构
state 数据✅ 需要✅(通过 storeToRefs)
getters✅ 需要✅(通过 storeToRefs)
actions❌ 不需要✅(始终)✅(直接解构)

三、state 

 在 Pinia 中,state 就是你用来存储全局数据的地方。它相当于组件中的 data(),但它可以被多个组件共享。

 例如:

state: () => ({count: 0,user: {name: 'Xia',loggedIn: false}
})

 这段代码定义了两个状态变量:countuser,你可以在任何组件中使用和修改它们。

1、state 的三个关键点

1. 必须是一个函数(返回对象)

这是为了确保每个 store 实例有自己的状态(尤其是在 SSR 环境中)。

state: () => ({count: 0
})

2. 是响应式的

Pinia 内部使用 Vue 的响应式系统(reactivity API)来管理状态。这意味着当你修改 state 中的数据,使用它的组件会自动更新。

3. 可以直接读写

与 Vuex 不同,Pinia 的 state 变量可以直接修改,不需要通过 mutation。例如:

store.count++  // 这是合法的
store.user.name = 'Yang' // 也可以这样直接改

2、 state高级用法

1. 重置 state($reset() 方法)

作用

  • state 恢复为创建时定义的初始值。

  • 适合用于退出登录清空表单重置计数器等场景。

使用方式

选项式 API 可直接使用 store.$reset()

const store = useStore()
store.$reset()
这个方法会自动调用最初定义的 state() 函数,用返回的对象替换当前的 state。

组合式 API 需要手动实现 $reset() 方法。 

 如果你使用的是 组合式 API(即 defineStore('id', () => {...}) 格式),需要自己手动写一个 $reset() 方法:

export const useCounterStore = defineStore('counter', () => {const count = ref(0)function $reset() {count.value = 0}return { count, $reset }
})

2、$patch() — 批量或复杂修改 state

作用

  • 用于一次性更新多个 state 属性

  • 避免多次赋值产生性能问题,也方便调试(devtools 会合并记录)。

  • 支持复杂的数组/对象操作。

用法

对象方式(简洁)
store.$patch({count: store.count + 1,name: 'DIO'
})函数方式(适合复杂修改)
store.$patch((state) => {state.items.push({ id: 1, name: 'shoes' })
})

 $state — 替换整个 state(实际上是 patch)

作用

  • 用于初始化或从服务器、localStorage 恢复 state。

  • 虽然看起来是“覆盖”,但实际上是调用了 $patch()

store.$state = { count: 24, name: 'Zhang' }

 3、mapState() — 把 state 映射为只读计算属性

作用

  • 用于在选项式 API 的组件中使用 Pinia 的 state。

  • store.count 变成 this.count,方便模板访问。

  • 本质上是一个只读 computed()

computed: {...mapState(useCounterStore, ['count'])
}

 4、mapWritableState() — 把 state 映射为可写计算属性

作用

  • mapState() 类似,但支持修改值

  • 适合表单绑定、v-model 等双向数据绑定场景。

computed: {...mapWritableState(useCounterStore, ['count'])
}
✅ 你可以在模板中用 v-model="count" 实现响应式输入。

5、$subscribe() — 监听 state 的变化

作用

  • 监听 store 的 state 改变,并触发回调。

  • 常用于持久化(localStorage)发送日志自动保存等场景。

  • 与 Vue 的 watch() 不同:$subscribe()patch 触发一次,不是属性粒度触发

store.$subscribe((mutation, state) => {localStorage.setItem('cart', JSON.stringify(state))
})

 加上 { detached: true },让监听器在组件卸载后仍然有效(适合全局监听)。

6、watch(pinia.state) — 监听整个应用状态(全局级别)

✅ 作用

  • 用于在应用级别跟踪所有 store 的状态。

  • 常用于初始化持久化系统跨模块状态变化处理

watch(pinia.state,(state) => {localStorage.setItem('piniaState', JSON.stringify(state))},{ deep: true }
)

小知识: 

初始化持久化系统”是指在 Vue 应用中,通过 Pinia 将全局状态(state)保存到浏览器的本地存储(如 localStorage),并在应用加载时恢复之前保存的状态,从而实现“断电重连”、“页面刷新不丢数据”等功能。

 “跨模块状态变化处理”指的是:监听或响应多个 Pinia store 之间的状态变动,从而实现它们之间的协调、联动或同步逻辑。

为什么需要跨模块状态处理?

在实际开发中,你通常会为不同功能创建多个 store(模块化):

Store 模块功能
userStore管理登录用户信息
cartStore管理购物车内容
orderStore管理订单信息
uiStore控制 UI 状态(弹窗、loading 等)

但这些模块的状态往往不是孤立的

  • 用户退出登录时,需要清空购物车、重置订单模块

  • 添加商品到购物车后,UI 弹窗需要自动关闭

  • 切换语言后,需要让其他模块响应更新

四、Getter 

1、什么是 Getter?

在 Pinia 中,getter 就是计算属性(computed),用于从 state 中派生出一些数据,例如格式化、计算总和、过滤等。

它的作用就像:

  • Vue 组件中的 computed

  • Vuex 中的 getter

2、Getter 的作用

主要功能举例说明
派生出新值例如 items.lengthcount * 2是否登录
基于 state 但不会直接修改 state保证“只读逻辑”
提高代码可读性通过 getter 抽象逻辑,例如 isAdmin
性能优化只有依赖的值变化时才重新计算(和 computed 一样)

 Getter 的定义方式

在选项式 API中(推荐初学者)
export const useCounterStore = defineStore('counter', {state: () => ({count: 2}),getters: {doubleCount: (state) => state.count * 2,isEven: (state) => state.count % 2 === 0}
})在组合式 API中(进阶)
export const useCounterStore = defineStore('counter', () => {const count = ref(2)const doubleCount = computed(() => count.value * 2)return { count, doubleCount }
})

 Getter 的使用方式

在组件中直接访问(不需要调用)
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script><template><p>原始:{{ counter.count }}</p><p>双倍:{{ counter.doubleCount }}</p>
</template>
✅ 注意:getter 就像计算属性,是自动响应式的,不需要加括号。✍️ Getter 可以访问其他 state、getter
getters: {isEven: (state) => state.count % 2 === 0,label: (state, getters) => getters.isEven ? '偶数' : '奇数'
}

3、Getter 是只读的

你不能直接修改 getter 的返回值:

 store.doubleCount = 10 // ❌ 不允许,会报错

 如果你需要修改值,请通过 action 或直接改 state。

 1. 访问其他 Getter(组合 Getter)

 当你想让一个 getter 基于另一个 getter 的结果继续计算,可以直接通过 this 访问其他 getter。

export const useCounterStore = defineStore('counter', {state: () => ({ count: 0 }),getters: {doubleCount(state) {return state.count * 2},doubleCountPlusOne(): number {return this.doubleCount + 1}}
})
💡 重点说明
this.doubleCount 是另一个 getter
如果你用 TypeScript,必须指定返回值类型,如 : number

2. 向 Getter 传递参数(返回一个函数)

❌ 错误方式(不能这样做)
// 不支持:getUserById(id) { ... }正确方式:返回一个函数
export const useUserListStore = defineStore('userList', {state: () => ({users: [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]}),getters: {getUserById: (state) => {return (userId) => state.users.find((user) => user.id === userId)}}
})

注意

  • 返回函数的 getter 不会被缓存(不像 computed),每次调用都重新执行

  • 更适合用于 过滤、查找 等需要参数的场景

 3. 缓存变体:先筛选再返回函数

getActiveUserById(state) {const activeUsers = state.users.filter((u) => u.active)return (id) => activeUsers.find((u) => u.id === id)
}
适合场景:
当你要多次按 id 查询某个子集(如活跃用户)
手动做了第一步过滤以节省后续运算

 4. 访问其他 Store 的 Getter

import { useOtherStore } from './other-store'export const useStore = defineStore('main', {state: () => ({ localData: 10 }),getters: {otherGetter(state) {const otherStore = useOtherStore()return state.localData + otherStore.doubleValue // 使用别的 store 的 getter}}
})
你可以在 getter 中随意使用其他 store,就像在组件中那样要确保其他 store 已经定义好尽量避免循环依赖(Store A 调用 B,B 又回头调用 A)

 五、Action

 Action 相当于组件中的 method。它们可以通过 defineStore() 中的 actions 属性来定义,并且它们也是定义业务逻辑的完美选择。

 类似 getter,action 也可通过 this 访问整个 store 实例,并支持完整的类型标注(以及自动补全✨)不同的是,action 可以是异步的,你可以在它们里面 await 调用任何 API,以及其他 action!

 1、定义

1. 使用选项式 API 定义 Store
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {state: () => ({count: 0}),actions: {increment() {this.count++}}
})
✅ 说明:
state: 返回一个对象,定义响应式数据  actions: 包含可以修改 state 的方法
这是 Pinia 的 选项式 API 写法,类似 Vue 组件的 data、methods🧩 2. 在组件中使用 store(有两种写法)
✅ 使用 setup()(组合式 API 风格)
import { useCounterStore } from '@/stores/counter'
export default defineComponent({setup() {const counterStore = useCounterStore()return { counterStore }},methods: {incrementAndPrint() {this.counterStore.increment()console.log('New Count:', this.counterStore.count)}}
})
📌 特点:
虽然这是在选项式组件中,但使用了 setup(),所以不需要 mapState() 或 mapActions() 映射
store 的属性都挂在 this.counterStore 上
✅ 不使用 setup(),使用 mapActions() 辅助函数
import { mapActions } from 'pinia'
import { useCounterStore } from '../stores/counter'export default {methods: {...mapActions(useCounterStore, ['increment']),...mapActions(useCounterStore, { myOwnName: 'increment' })}
}特点:将 store 中的 action 映射为当前组件的 method
this.increment() 实际调用的是 store.increment()
如果你不使用 setup(),这是官方推荐的写法

2. 订阅 Action 的执行:$onAction()

✅ 作用:

$onAction() 允许你拦截 action 的执行过程,记录日志、添加监控、处理错误等。

const unsubscribe = store.$onAction(({ name, args, after, onError }) => {const start = Date.now()console.log(`Start "${name}" with args:`, args)after((result) => {console.log(`Finished "${name}" in ${Date.now() - start}ms. Result:`, result)})onError((err) => {console.warn(`Failed "${name}" in ${Date.now() - start}ms. Error:`, err)})
})

📌 回调参数说明:

参数说明
name当前执行的 action 名称
args调用该 action 时传入的参数
after(fn)在 action 成功执行后触发的回调
onError(fn)在 action 执行失败或抛错时触发的回调

3. 解绑监听器(防止内存泄露)

 unsubscribe() // 手动移除订阅器

✅ 默认行为:

  • 如果 store 是在组件的 setup() 中创建的,$onAction() 会自动在组件卸载时移除监听器。

✅ 永久监听(不随组件销毁):

 store.$onAction(callback, true) // 第二个参数为 true

适用于:

  • 全局日志系统

  • 性能监控

  • 状态操作历史记录

 六、插件

1、什么是 Pinia 插件?

Pinia 插件是用来扩展所有 store 的功能的工具。它们可以:

  • 添加默认属性

  • 注入共享方法

  • 实现状态持久化、本地缓存、日志记录等功能

可以把插件理解为:给每个 Store 加“外挂”功能,类似 Vue 插件或 Vuex 插件。

插件 = 给每个 store 加功能的小外挂。

想象一下你有很多个 store,就像很多个员工。你想让每个员工都多一个新技能,比如:

  • 会自动保存工作成果(= 自动把 state 保存到 localStorage)

  • 每次干活都写日志(= action 调用时打印日志)

  • 都能说一句“你好老板”(= 添加一个公共方法)

你不用每次都手动写这段逻辑,而是通过 插件,一次性注入到所有 store 里,就像给每个员工配发一个新“工具包”。

2、插件能做什么?

Pinia 插件可以用来实现以下场景:

功能示例
状态持久化保存 store 到 localStorage
自动记录操作日志记录每次 action 调用的时间、参数
注入公共方法$toast()$confirm()
初始化共享状态比如全局主题、设置项
插件封装业务逻辑例如 API 请求封装、授权检测

 Pinia 插件是一个函数,可以选择性地返回要添加到 store 的属性。它接收一个可选参数,即 context

export function myPiniaPlugin(context) {context.pinia // 用 `createPinia()` 创建的 pinia。context.app // 用 `createApp()` 创建的当前应用(仅 Vue 3)。context.store // 该插件想扩展的 storecontext.options // 定义传给 `defineStore()` 的 store 的可选对象。// ...
}

然后用 pinia.use() 将这个函数传给 pinia

pinia.use(myPiniaPlugin)

插件只会应用于在 pinia 传递给应用后创建的 store,否则它们不会生效。

3、如何使用插件?

✅ 注册插件到 Pinia 实例

// main.js
import { createPinia } from 'pinia'
import piniaPlugin from './myPlugin'const pinia = createPinia()
pinia.use(piniaPlugin)

✅ 插件的基本结构

// myPlugin.js
export default function myPlugin({ store }) {// 添加一个自定义属性store.hello = 'world'// 添加一个共享方法store.sayHello = () => {console.log(`Hello from ${store.$id}`)}
}

使用后,你可以在任意 store 中访问:

const store = useMyStore()
store.sayHello() // 打印:Hello from myStore

4、插件能做的几件事(举例)

插件功能作用说明类比
自动保存 state 到本地页面刷新后还能恢复数据自动保存工作成果
打印日志每次调用 action 时记录操作打卡上下班
增加自定义方法比如 $toast() 弹窗提示提供快捷按钮
修改 store 行为比如封装通用校验定制化员工行为

5、插件和 store 有什么区别?

Store 是什么?插件是干嘛的?
管理状态(数据)和操作(actions)扩展每个 store 的功能
每个业务写一个全局使用一次,所有 store 都能用
比如 userStore, cartStore比如“保存功能”、“日志功能”

6、插件的真正价值

插件的核心作用是:统一增强所有 store 的功能,而不是在每个 store 里重复写。

举个例子:

如果你希望所有模块的状态都能自动保存到本地(比如购物车、用户设置等),你肯定不想在每个 store 里写一遍 localStorage.setItem()

所以,你就写一个插件,让每个 store 自动保存它自己的数据,只要注册一次,全局生效。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构之图的遍历

图的遍历 图的遍历目的是访问图的每一个顶点恰好一次,&#xff0c;同时访问图中每条边恰好一 次。 对于无向图&#xff0c;常见的遍历方式有深度优先遍历&#xff08;Depth-First Search, DFS&#xff09; 和广度优先遍历&#xff08;Breadth-First Search, BFS&#xff09;。…

Ubuntu 第11章 网络管理_常用的网络配置命令

为了管理网络&#xff0c;Linux提供了许多非常有用的网络管理命令。利用这些命令&#xff0c;一方面可以有效地管理网络&#xff0c;另一方面出现网络故障时&#xff0c;可以快速进行诊断。本节将对Ubuntu提供的网络管理命令进行介绍。 11.2.1 ifconfig命令 关于ifconfig命令&…

Qt解决自定义窗口样式不生效问题

方法一&#xff1a; this->setAttribute(Qt::WA_StyledBackground, true); 方法二&#xff1a; 将类继承QWidget 改成继承 QFrame class MyWidget : public QFrame {} 方法三&#xff1a;重新实现QWidget的paintEvent函数时&#xff0c;使用QStylePainter绘制。 void p…

HNUST湖南科技大学-软件测试期中复习考点(保命版)

使用说明&#xff1a;本复习考点仅用于及格保命。软件测试和其他专业课不太一样&#xff0c;记忆的太多了&#xff0c;只能说考试的时候&#xff0c;想到啥就写啥&#xff0c;多写一点&#xff01;多写一点&#xff01;多写一点&#xff01;&#xff08;重要事情说三遍&#xf…

ES6 知识点整理

一、变量声明&#xff1a;var、let、const 的区别 作用域 var&#xff1a;函数作用域&#xff08;函数内有效&#xff09;。let/const&#xff1a;块级作用域&#xff08;{} 内有效&#xff0c;如 if、for&#xff09;。 变量提升 var 会提升变量到作用域顶部&#xff08;值为…

分布式爬虫去重:Python + Redis实现高效URL去重

1. 引言 在互联网数据采集&#xff08;爬虫&#xff09;过程中&#xff0c;URL去重是一个关键问题。如果不对URL进行去重&#xff0c;爬虫可能会重复抓取相同页面&#xff0c;导致资源浪费、数据冗余&#xff0c;甚至触发目标网站的反爬机制。 对于单机爬虫&#xff0c;可以使…

C# WPF 颜色拾取器

x:Name=Color Picker 语言:C# WPF 下载:https://download.csdn.net/download/polloo2012/90780640 主界面 颜色库 关于我们 颜色拾取器是一种能够帮助用户获取颜色信息,并进行颜色选择、识别和调整的工具,以下将从其常见类型、使用场景及部分软件工具这几个维度展开介绍…

Git 使用的全流程以及SourceTree工具的使用操作和忽略文件的配置

1. 安装 Git 要使用 Git&#xff0c;首先得在你的系统上安装它。你可以按照不同操作系统的安装指南来操作&#xff1a; Windows&#xff1a;访问 Git 官方下载页面&#xff0c;下载安装程序并运行。 macOS&#xff1a;可以使用 Homebrew 来安装&#xff0c;命令为 brew inst…

《深入理解Linux网络》笔记

《深入理解Linux网络》笔记 前言参考 前言 前段时间看了《深入理解Linux网络》这本书&#xff0c;虽然有些地方有以代码充篇幅的嫌疑&#xff0c;但总体来说还是值得一看的。在这里简单记录一下笔记&#xff0c;记录下对网络新的理解。 内核是如果接受网络包的&#xff1f; 如…

数仓-可累计,半累加,不可累加指标,是什么,举例说明及解决方案

目录 1. 可累计指标定义&#xff1a;举例&#xff1a;解决方案&#xff1a; 2. 半累加指标定义&#xff1a;举例&#xff1a;解决方案&#xff1a; 3. 不可累加指标定义&#xff1a;举例&#xff1a;解决方案&#xff1a; 4. 总结对比5. 实际场景中的注意事项 这是数据仓库设计…

NestJS 的核心构建块有哪些?请简要描述它们的作用(例如,Modules, Controllers, Providers)

NestJS 核心构建块解析&#xff08;Modules、Controllers、Providers&#xff09; NestJS 是一个基于 TypeScript 的渐进式 Node.js 框架&#xff0c;核心设计借鉴了 Angular 的模块化思想。下面从实际开发角度解析它的三大核心构建块&#xff0c;并附代码示例和避坑指南。 一…

vue2 上传pdf,拖拽盖章,下载图片

效果图片&#xff1a; 不多废话上代码&#xff1a; <template><div class"pdf-stamp" onbeforecopyreturn false onselectdocument.selection.empty() ondragstartreturn false onselectstart return false ><div class"scroll-box" scro…

理性地倾听与表达:检索算法的语言学改进

论文标题 Rational Retrieval Acts: Leveraging Pragmatic Reasoning to Improve Sparse Retrieval 论文地址 https://arxiv.org/pdf/2505.03676 代码地址 https://github.com/arthur-75/Rational-Retrieval-Acts 作者背景 巴黎萨克雷大学&#xff0c;索邦大学&#xff…

MySQL及线程关于锁的面试题

目录 1.了解过 MySQL 死锁问题吗&#xff1f; 2.什么是线程死锁&#xff1f;死锁相关面试题 2.1 什么是死锁&#xff1a; 2.2 形成死锁的四个必要条件是什么&#xff1f; 2.3 如何避免线程死锁&#xff1f; 3. MySQL 怎么排查死锁问题&#xff1f; 4.Java线上死锁问题如…

【Reality Capture 】Reality Capture1.5中文版安装教程(附安装包下载)

文章目录 一、Reality Capture1.5中文版安装教程二、拷贝中文补丁三、Reality Capture1.5中文版下载地址一、Reality Capture1.5中文版安装教程 1. Reality Capture v1.4.0汉化版安装包下载并解压 2. 运行EpicInstaller-15.17.1-4a91a118786f4c2aa3c0093b23f83863.msi 3. 更改…

SVG数据可视化设计(AI)完全工作流解读|计育韬

AI 的 SVG 创作极限在哪里&#xff1f;绝不是那些初级的流程图生成和粗糙的商业模型设计。以下是由我们 JZ Creative Studio 通过 Claude 和 Deepseek 开展的专业级 SVG Data Visualization 创作&#xff0c;应广大读者强烈要求&#xff0c;专程直播讲授了一期 AI 工作流分享。…

not a genuine st device abort connection的问题

1.魔法棒里面电机Settings 2.然后在Other里面把Enabled的钩子去掉

uv简单使用

通过uv创建项目和虚拟环境 初始化项目 uv init --package my-project 初始化一个名为 my-project 的新项目&#xff0c;并生成必要的文件结构。 创建虚拟环境 uv venv .venv 激活虚拟环境 # For Windows .venv\Scripts\activate# For macOS/Linux source .venv/bin/acti…

测试左移系列-产品经理实战-实战认知1

课程&#xff1a;B站大学 记录产品经理实战项目系统性学习&#xff0c;从产品思维&#xff0c;用户画像&#xff0c;用户体验&#xff0c;增长数据驱动等不同方向理解产品&#xff0c;从0到1去理解产品从需求到落地的全过程&#xff0c;测试左移方向&#xff08;靠近需求、设计…

从需求到用例的AI路径:准确率与挑战

用工作流生成测试用例和自动化测试脚本&#xff01; 引言&#xff1a;用例的黄金起点 在软件工程中&#xff0c;“测试用例”是连接需求理解与质量保障之间的关键桥梁。一份高质量的测试用例&#xff0c;不仅是验证功能实现是否符合需求的工具&#xff0c;更是产品风险感知、用…