【Vue】状态管理(Vuex、Pinia)
个人主页:Guiat
归属专栏:Vue
文章目录
- 1. 状态管理概述
- 1.1 什么是状态管理
- 1.2 为什么需要状态管理
- 2. Vuex基础
- 2.1 Vuex核心概念
- 2.1.1 State
- 2.1.2 Getters
- 2.1.3 Mutations
- 2.1.4 Actions
- 2.1.5 Modules
- 2.2 Vuex辅助函数
- 2.2.1 mapState
- 2.2.2 mapGetters
- 2.2.3 mapMutations
- 2.2.4 mapActions
- 2.2.5 createNamespacedHelpers
- 2.3 Vuex插件
- 3. Pinia基础
- 3.1 Pinia介绍
- 3.2 安装和基本设置
- 3.3 定义Store
- 3.4 使用Store
- 3.5 修改状态
- 3.5.1 直接修改
- 3.5.2 使用actions
- 3.5.3 使用$patch方法
- 3.5.4 替换整个状态
- 3.6 Pinia插件
- 4. Vuex与Pinia的对比
- 4.1 核心概念对比
- 4.2 API风格对比
- 4.2.1 Store定义
- 4.2.2 在组件中使用
- 4.3 优缺点比较
- 4.3.1 Vuex优缺点
- 4.3.2 Pinia优缺点
- 5. 高级状态管理模式
- 5.1 组合式Store模式
- 5.1.1 Vuex中的组合
- 5.1.2 Pinia中的组合
- 5.2 持久化状态
- 5.2.1 Vuex持久化
- 5.2.2 Pinia持久化
- 5.3 状态重置
- 5.3.1 Vuex状态重置
- 5.3.2 Pinia状态重置
- 5.4 状态订阅
- 5.4.1 Vuex状态订阅
- 5.4.2 Pinia状态订阅
正文
1. 状态管理概述
1.1 什么是状态管理
在Vue应用中,状态管理是指对应用中各种数据状态的集中式管理。随着应用规模的增长,组件之间共享状态变得越来越复杂,简单的父子组件通信方式可能不再适用。状态管理工具提供了一种集中式存储管理应用所有组件的状态的方式。
1.2 为什么需要状态管理
当应用变得复杂时,我们面临以下挑战:
- 多个视图依赖同一状态
- 来自不同视图的行为需要变更同一状态
- 组件层级深,组件间通信变得困难
- 全局状态难以追踪变化来源
状态管理工具解决了这些问题,提供了:
- 集中存储共享状态
- 可预测的状态变更机制
- 开发工具支持的调试能力
- 模块化的状态管理方案
2. Vuex基础
2.1 Vuex核心概念
Vuex是Vue官方的状态管理模式,它采用集中式存储管理应用的所有组件的状态。
2.1.1 State
State是存储应用状态的地方:
// store/index.js
import { createStore } from 'vuex'export default createStore({state: {count: 0,todos: [],user: null}
})
在组件中访问状态:
// Vue 2
export default {computed: {count() {return this.$store.state.count}}
}// Vue 3
import { computed } from 'vue'
import { useStore } from 'vuex'export default {setup() {const store = useStore()const count = computed(() => store.state.count)return { count }}
}
2.1.2 Getters
Getters用于从store的state中派生出一些状态:
// store/index.js
export default createStore({state: {todos: [{ id: 1, text: 'Learn Vue', done: true },{ id: 2, text: 'Learn Vuex', done: false }]},getters: {doneTodos: state => {return state.todos.filter(todo => todo.done)},doneTodosCount: (state, getters) => {return getters.doneTodos.length}}
})
在组件中使用getters:
// Vue 2
export default {computed: {doneTodosCount() {return this.$store.getters.doneTodosCount}}
}// Vue 3
import { computed } from 'vue'
import { useStore } from 'vuex'export default {setup() {const store = useStore()const doneTodosCount = computed(() => store.getters.doneTodosCount)return { doneTodosCount }}
}
2.1.3 Mutations
Mutations是更改store中状态的唯一方法:
// store/index.js
export default createStore({state: {count: 0},mutations: {increment(state) {state.count++},incrementBy(state, payload) {state.count += payload.amount}}
})
在组件中提交mutations:
// Vue 2
export default {methods: {increment() {this.$store.commit('increment')},incrementBy(amount) {this.$store.commit('incrementBy', { amount })}}
}// Vue 3
import { useStore } from 'vuex'export default {setup() {const store = useStore()function increment() {store.commit('increment')}function incrementBy(amount) {store.commit('incrementBy', { amount })}return { increment, incrementBy }}
}
2.1.4 Actions
Actions用于处理异步操作:
// store/index.js
export default createStore({state: {todos: []},mutations: {setTodos(state, todos) {state.todos = todos},addTodo(state, todo) {state.todos.push(todo)}},actions: {async fetchTodos({ commit }) {try {const response = await fetch('/api/todos')const todos = await response.json()commit('setTodos', todos)} catch (error) {console.error('Error fetching todos:', error)}},async addTodo({ commit }, todoText) {try {const response = await fetch('/api/todos', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ text: todoText, done: false })})const newTodo = await response.json()commit('addTodo', newTodo)} catch (error) {console.error('Error adding todo:', error)}}}
})
在组件中分发actions:
// Vue 2
export default {created() {this.$store.dispatch('fetchTodos')},methods: {addTodo() {this.$store.dispatch('addTodo', this.newTodoText)}}
}// Vue 3
import { useStore } from 'vuex'
import { ref, onMounted } from 'vue'export default {setup() {const store = useStore()const newTodoText = ref('')onMounted(() => {store.dispatch('fetchTodos')})function addTodo() {store.dispatch('addTodo', newTodoText.value)newTodoText.value = ''}return { newTodoText, addTodo }}
}
2.1.5 Modules
Modules用于将store分割成模块:
// store/modules/counter.js
export default {namespaced: true,state: {count: 0},getters: {doubleCount: state => state.count * 2},mutations: {increment(state) {state.count++}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment')}, 1000)}}
}// store/modules/todos.js
export default {namespaced: true,state: {list: []},getters: {doneTodos: state => state.list.filter(todo => todo.done)},mutations: {add(state, todo) {state.list.push(todo)}},actions: {async fetchAll({ commit }) {const response = await fetch('/api/todos')const todos = await response.json()todos.forEach(todo => commit('add', todo))}}
}// store/index.js
import { createStore } from 'vuex'
import counter from './modules/counter'
import todos from './modules/todos'export default createStore({modules: {counter,todos}
})
在组件中访问模块:
// Vue 2
export default {computed: {count() {return this.$store.state.counter.count},doubleCount() {return this.$store.getters['counter/doubleCount']}},methods: {increment() {this.$store.commit('counter/increment')},incrementAsync() {this.$store.dispatch('counter/incrementAsync')}}
}// Vue 3
import { computed } from 'vue'
import { useStore } from 'vuex'export default {setup() {const store = useStore()const count = computed(() => store.state.counter.count)const doubleCount = computed(() => store.getters['counter/doubleCount'])function increment() {store.commit('counter/increment')}function incrementAsync() {store.dispatch('counter/incrementAsync')}return { count, doubleCount, increment, incrementAsync }}
}
2.2 Vuex辅助函数
Vuex提供了一些辅助函数简化代码:
2.2.1 mapState
// Vue 2
import { mapState } from 'vuex'export default {computed: {// 映射this.count为store.state.count...mapState({count: state => state.count,countAlias: 'count',countPlusLocalState(state) {return state.count + this.localCount}}),// 映射this.count为store.state.count...mapState(['count', 'todos'])}
}
2.2.2 mapGetters
// Vue 2
import { mapGetters } from 'vuex'export default {computed: {// 映射this.doneTodosCount为store.getters.doneTodosCount...mapGetters(['doneTodosCount','anotherGetter',]),// 使用别名...mapGetters({doneCount: 'doneTodosCount'})}
}
2.2.3 mapMutations
// Vue 2
import { mapMutations } from 'vuex'export default {methods: {// 映射this.increment()为this.$store.commit('increment')...mapMutations(['increment','incrementBy']),// 使用别名...mapMutations({add: 'increment'})}
}
2.2.4 mapActions
// Vue 2
import { mapActions } from 'vuex'export default {methods: {// 映射this.fetchTodos()为this.$store.dispatch('fetchTodos')...mapActions(['fetchTodos','addTodo']),// 使用别名...mapActions({fetch: 'fetchTodos'})}
}
2.2.5 createNamespacedHelpers
// Vue 2
import { createNamespacedHelpers } from 'vuex'// 创建基于某个命名空间辅助函数
const { mapState, mapActions } = createNamespacedHelpers('counter')export default {computed: {// 映射this.count为store.state.counter.count...mapState({count: state => state.count})},methods: {// 映射this.increment()为this.$store.dispatch('counter/increment')...mapActions(['increment','incrementAsync'])}
}
2.3 Vuex插件
Vuex支持插件系统,用于扩展功能:
// 简单的日志插件
const myPlugin = store => {// 当store初始化后调用store.subscribe((mutation, state) => {// 每次mutation之后调用console.log('mutation type:', mutation.type)console.log('mutation payload:', mutation.payload)console.log('current state:', state)})
}// 持久化状态插件
const persistStatePlugin = store => {// 从localStorage恢复状态const savedState = localStorage.getItem('vuex-state')if (savedState) {store.replaceState(JSON.parse(savedState))}// 订阅状态变更store.subscribe((mutation, state) => {localStorage.setItem('vuex-state', JSON.stringify(state))})
}// 在store中使用插件
export default createStore({// ...plugins: [myPlugin, persistStatePlugin]
})
3. Pinia基础
3.1 Pinia介绍
Pinia是Vue官方团队成员开发的新一代状态管理库,被视为Vuex 5的替代品。它提供了更简单的API、完整的TypeScript支持,以及更好的开发体验。
3.2 安装和基本设置
# 安装Pinia
npm install pinia
# 或
yarn add pinia
在Vue应用中注册Pinia:
// main.js (Vue 3)
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const app = createApp(App)
app.use(createPinia())
app.mount('#app')
3.3 定义Store
在Pinia中,store的定义更加直观:
// stores/counter.js
import { defineStore } from 'pinia'// 第一个参数是store的唯一ID
export const useCounterStore = defineStore('counter', {// state是一个返回初始状态的函数state: () => ({count: 0,name: 'Eduardo'}),// getters类似于组件的计算属性getters: {doubleCount: (state) => state.count * 2,// 使用this访问其他gettersdoubleCountPlusOne() {return this.doubleCount + 1}},// actions包含可以修改状态和执行异步操作的方法actions: {increment() {this.count++},async fetchData() {const response = await fetch('/api/data')const data = await response.json()this.count = data.count}}
})
3.4 使用Store
在组件中使用Pinia store:
// Vue 3 组件
<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'// 获取store实例
const counterStore = useCounterStore()// 解构store状态和getters (使用storeToRefs保持响应性)
const { count, name } = storeToRefs(counterStore)
const { doubleCount } = storeToRefs(counterStore)// 直接调用actions
function handleClick() {counterStore.increment()
}// 异步actions
async function loadData() {await counterStore.fetchData()
}
</script><template><div><p>Count: {{ count }}</p><p>Double count: {{ doubleCount }}</p><p>Name: {{ name }}</p><button @click="handleClick">Increment</button><button @click="loadData">Load Data</button></div>
</template>
3.5 修改状态
Pinia提供了多种修改状态的方式:
3.5.1 直接修改
const store = useCounterStore()// 直接修改状态
store.count++
store.name = 'Alex'
3.5.2 使用actions
const store = useCounterStore()// 通过actions修改
store.increment()
3.5.3 使用$patch方法
const store = useCounterStore()// 一次性修改多个状态
store.$patch({count: store.count + 1,name: 'Alex'
})// 使用函数形式的$patch处理复杂状态
store.$patch((state) => {state.count++state.name = 'Alex'// 可以包含更复杂的逻辑if (state.items) {state.items.push({ id: nanoid(), text: 'New Item' })}
})
3.5.4 替换整个状态
const store = useCounterStore()// 完全替换状态
store.$state = {count: 10,name: 'Alex'
}
3.6 Pinia插件
Pinia支持插件系统,可以扩展store功能:
// plugins/persistPlugin.js
import { toRaw } from 'vue'export function persistPlugin({ store }) {// 从localStorage恢复状态const storedState = localStorage.getItem(`pinia-${store.$id}`)if (storedState) {store.$state = JSON.parse(storedState)}// 监听状态变化并保存store.$subscribe((mutation, state) => {localStorage.setItem(`pinia-${store.$id}`, JSON.stringify(toRaw(state)))})
}// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { persistPlugin } from './plugins/persistPlugin'
import App from './App.vue'const pinia = createPinia()
pinia.use(persistPlugin)const app = createApp(App)
app.use(pinia)
app.mount('#app')
4. Vuex与Pinia的对比
4.1 核心概念对比
特性 | Vuex | Pinia |
---|---|---|
状态定义 | state对象 | state函数 |
计算状态 | getters | getters |
同步修改 | mutations | actions |
异步操作 | actions | actions |
模块化 | modules + namespaced | 多个store |
TypeScript支持 | 有限 | 完全支持 |
开发工具 | Vue Devtools | Vue Devtools |
4.2 API风格对比
4.2.1 Store定义
Vuex:
// store/index.js
import { createStore } from 'vuex'export default createStore({state: {count: 0},getters: {doubleCount: state => state.count * 2},mutations: {increment(state) {state.count++}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment')}, 1000)}}
})
Pinia:
// stores/counter.js
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {state: () => ({count: 0}),getters: {doubleCount: state => state.count * 2},actions: {increment() {this.count++},incrementAsync() {setTimeout(() => {this.increment()}, 1000)}}
})
4.2.2 在组件中使用
Vuex (Vue 2):
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'export default {computed: {...mapState(['count']),...mapGetters(['doubleCount'])},methods: {...mapMutations(['increment']),...mapActions(['incrementAsync'])}
}
Vuex (Vue 3 Composition API):
import { computed } from 'vue'
import { useStore } from 'vuex'export default {setup() {const store = useStore()const count = computed(() => store.state.count)const doubleCount = computed(() => store.getters.doubleCount)function increment() {store.commit('increment')}function incrementAsync() {store.dispatch('incrementAsync')}return { count, doubleCount, increment, incrementAsync }}
}
Pinia:
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'export default {setup() {const store = useCounterStore()// 解构时保持响应性const { count } = storeToRefs(store)const { doubleCount } = storeToRefs(store)// 直接使用actionsconst { increment, incrementAsync } = storereturn { count, doubleCount, increment, incrementAsync }}
}
4.3 优缺点比较
4.3.1 Vuex优缺点
优点:
- 成熟稳定,生态系统丰富
- 与Vue 2完全兼容
- 严格的状态管理模式,mutation/action分离
- 丰富的中间件和插件
缺点:
- API相对复杂,样板代码较多
- TypeScript支持有限
- 模块嵌套时命名空间管理复杂
- 必须通过mutation修改状态
4.3.2 Pinia优缺点
优点:
- API简洁,样板代码少
- 完全支持TypeScript
- 更好的开发体验和IDE支持
- 可直接修改状态,无需mutations
- 更小的包体积
- 模块化设计更简单,无需嵌套
缺点:
- 相对较新,生态系统不如Vuex丰富
- 对Vue 2需要额外适配
- 缺少严格模式的状态追踪
5. 高级状态管理模式
5.1 组合式Store模式
5.1.1 Vuex中的组合
// store/modules/user.js
export default {namespaced: true,state: () => ({profile: null,preferences: {}}),getters: {isLoggedIn: state => !!state.profile},mutations: {setProfile(state, profile) {state.profile = profile}},actions: {async login({ commit }, credentials) {const profile = await authService.login(credentials)commit('setProfile', profile)return profile}}
}// store/modules/cart.js
export default {namespaced: true,state: () => ({items: []}),getters: {totalPrice: state => {return state.items.reduce((total, item) => {return total + (item.price * item.quantity)}, 0)}},mutations: {addItem(state, item) {state.items.push(item)}},actions: {async checkout({ state, commit }) {await orderService.createOrder(state.items)// 清空购物车state.items = []}}
}// store/index.js
import { createStore } from 'vuex'
import user from './modules/user'
import cart from './modules/cart'export default createStore({modules: {user,cart}
})
5.1.2 Pinia中的组合
// stores/user.js
import { defineStore } from 'pinia'
import { authService } from '@/services/auth'export const useUserStore = defineStore('user', {state: () => ({profile: null,preferences: {}}),getters: {isLoggedIn: state => !!state.profile},actions: {async login(credentials) {const profile = await authService.login(credentials)this.profile = profilereturn profile},logout() {this.profile = null}}
})// stores/cart.js
import { defineStore } from 'pinia'
import { orderService } from '@/services/order'export const useCartStore = defineStore('cart', {state: () => ({items: []}),getters: {totalPrice: state => {return state.items.reduce((total, item) => {return total + (item.price * item.quantity)}, 0)}},actions: {addItem(item) {this.items.push(item)},async checkout() {await orderService.createOrder(this.items)this.items = []}}
})// 在组件中组合使用多个store
import { useUserStore } from '@/stores/user'
import { useCartStore } from '@/stores/cart'export default {setup() {const userStore = useUserStore()const cartStore = useCartStore()async function checkoutAsUser() {if (!userStore.isLoggedIn) {await userStore.login()}await cartStore.checkout()}return { userStore, cartStore, checkoutAsUser }}
}
5.2 持久化状态
5.2.1 Vuex持久化
使用vuex-persistedstate插件:
// store/index.js
import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'export default createStore({// ...store配置plugins: [createPersistedState({key: 'vuex-state',paths: ['user.profile', 'cart.items'] // 只持久化特定路径})]
})
5.2.2 Pinia持久化
使用pinia-plugin-persistedstate插件:
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import App from './App.vue'const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)const app = createApp(App)
app.use(pinia)
app.mount('#app')// stores/user.js
import { defineStore } from 'pinia'export const useUserStore = defineStore('user', {state: () => ({profile: null}),// 配置持久化persist: {key: 'user-store',storage: localStorage,paths: ['profile']},// ...其他配置
})
5.3 状态重置
5.3.1 Vuex状态重置
// store/index.js
export default createStore({// ...mutations: {// 添加重置状态的mutationresetState(state) {Object.assign(state, initialState)}},actions: {resetStore({ commit }) {commit('resetState')}}
})// 在组件中使用
methods: {logout() {this.$store.dispatch('resetStore')}
}
5.3.2 Pinia状态重置
Pinia提供了内置的$reset方法:
// 在组件中使用
const store = useCounterStore()// 重置store到初始状态
function resetStore() {store.$reset()
}
5.4 状态订阅
5.4.1 Vuex状态订阅
// 订阅mutation
store.subscribe((mutation, state) => {console.log('mutation type:', mutation.type)console.log('mutation payload:', mutation.payload)console.log('current state:', state)
})// 订阅action
store.subscribeAction({before: (action, state) => {console.log(`before action ${action.type}`)},after: (action, state) => {console.log(`after action ${action.type}`)}
})
5.4.2 Pinia状态订阅
const store = useCounterStore()// 订阅状态变化
const unsubscribe = store.$subscribe((mutation, state) => {// 每次状态变化时触发console.log('mutation type:', mutation.type)console.log('mutation payload:', mutation.payload)console.log('current state:', state)
}, { detached: false }) // detached: true 会在组件卸载后保持订阅// 订阅action
store.$onAction(({name, // action名称store, // store实例args, // 传递给action的参数数组after, // 在action返回或解决后的钩子onError // action抛出或拒绝的钩子
}) => {console.log(`Start "${name}" with params [${args.join(', ')}]`)after((result) => {console.log(`Finished "${name}" with result: ${result}`)})onError((error) => {console.error(`Failed "${name}" with error: ${error}`)})
})
结语
感谢您的阅读!期待您的一键三连!欢迎指正!
相关文章:
【Vue】状态管理(Vuex、Pinia)
个人主页:Guiat 归属专栏:Vue 文章目录 1. 状态管理概述1.1 什么是状态管理1.2 为什么需要状态管理 2. Vuex基础2.1 Vuex核心概念2.1.1 State2.1.2 Getters2.1.3 Mutations2.1.4 Actions2.1.5 Modules 2.2 Vuex辅助函数2.2.1 mapState2.2.2 mapGetters2.…...
施磊老师基于muduo网络库的集群聊天服务器(四)
文章目录 实现登录业务登录业务代码补全数据库接口:查询,更新状态注意学习一下里面用到的数据库api测试与问题**问题1:****问题2:** 用户连接信息与线程安全聊天服务器是长连接服务器如何找到用户B的连接?在业务层存储用户的连接信息多线程安全问题加锁! 处理客户端…...
深度学习-全连接神经网络(过拟合,欠拟合。批量标准化)
七、过拟合与欠拟合 在训练深层神经网络时,由于模型参数较多,在数据量不足时很容易过拟合。而正则化技术主要就是用于防止过拟合,提升模型的泛化能力(对新数据表现良好)和鲁棒性(对异常数据表现良好)。 1. 概念认知 …...
访问Maven私服的教程
1.首先准备好maven私服的启动器,到bin目录下启动: 2.等待加载,加载过程比较长: 3.访问端口号: 4.仓库简介: 5.在maven的setting中 servers配置信息(设置私服访问的密码): 6.配置私服仓库地址: 7.配置上传地址(私服地址): 8.在自己的副项…...
Linux系统编程 day9 SIGCHLD and 线程
SIGCHLD信号 只要子进程信号发生改变,就会产生SIGCHLD信号。 借助SIGCHLD信号回收子进程 回收子进程只跟父进程有关。如果不使用循环回收多个子进程,会产生多个僵尸进程,原因是因为这个信号不会循环等待。 #include<stdio.h> #incl…...
Linux 内核中 cgroup 子系统 cpuset 是什么?
cpuset 是 Linux 内核中 cgroup(控制组) 的一个子系统,用于将一组进程(或任务)绑定到特定的 CPU 核心和 内存节点(NUMA 节点)上运行。它通过限制进程的 CPU 和内存资源的使用范围,优…...
乐视系列玩机---乐视2 x520 x528等系列线刷救砖以及刷写第三方twrp 卡刷第三方固件步骤解析
乐视2 x520 x528 x526等,搭载了高通骁龙652处理器,骁龙652的GPU性能甚至优于前一年的骁龙810,配备了3GB RAM和32GB ROM的存储空间, 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视2 x520系列黑砖线刷救砖的步骤 2💝💝💝----官方两种更新卡刷步骤以及刷…...
电容加速电路!
大家好,我是记得诚。 今天分享一个小电路:电容加速电路。 下面是一个普通的三极管开关电路,区别是多了一个C1,C1被称为加速电容。作用是:加速三极管VT1的开通和截止,做到快开快关。 工作原理:…...
MCP Host、MCP Client、MCP Server全流程实战
目录 准备工作 MCP Server 实现 调试工作 MCP Client 实现 MCP Host 配置 第一步:配置支持 function calling的 LLM 第二步:添加MCP Server 一般有两种方式,第一种json配置,第二种直接是Command形式,我这里采用Command形式 第三步:使用MCP Server 准备工作 安装…...
Win10一体机(MES电脑设置上电自动开机)
找个键盘,带线的那种,插到电脑上,电脑开机;连续点按F11;通过↑↓键选择Enter Setup 然后回车; 选择 smart settings ; 选择 Restore AC Power Loss By IO 回车; 将prower off 改为…...
强化学习和微调 区别如下
强化学习和微调 区别如下 定义与概念 强化学习**:是一种机器学习范式,强调智能体(agent)如何在环境中采取一系列行动,以最大化累积奖励**。智能体通过与环境进行交互,根据环境反馈的奖励信号来学习最优的行为策略。例如,机器人通过不断尝试不同的动作来学习如何在复杂环…...
【EasyPan】文件上传、文件秒传、文件转码、文件合并、异步转码、视频切割分析
【EasyPan】项目常见问题解答(自用&持续更新中…)汇总版 文件上传方法解析 一、方法总览 Transactional(rollbackFor Exception.class) public UploadResultDto uploadFile(...)核心能力: 秒传验证:通过MD5文件大小实现文…...
React18+ 项目搭建-从初始化、技术选型到开发部署的全流程规划
搭建一个 React 项目需要从项目初始化、技术选型到开发部署的全流程规划。以下是详细步骤和推荐的技术栈: 一、项目初始化 1. 选择脚手架工具 推荐工具: Vite(现代轻量级工具,支持 React 模板,速度快)&am…...
day3 打卡训练营
循环语句和判断语句之前已经会了,把列表的方法练一练 浙大疏锦行 python训练营介绍...
MySQL VS SQL Server:优缺点全解析
数据库选型、企业协作、技术生态、云数据库 1.1 MySQL优缺点分析 优点 开源免费 社区版完全免费,适合预算有限的企业 允许修改源码定制功能(需遵守GPL协议) 跨平台兼容性 支持Windows/Linux/macOS,适配混合环境部署 云服务商…...
【CPP】固定大小内存池
程序运行时,通常会频繁地进行内存的分配和释放操作。传统的内存分配方式(如使用new和delete运算符)可能会导致内存碎片的产生,并且每次分配和释放内存都有一定的时间开销。内存池通过在程序启动时一次性分配一大块内存或一次性分配…...
[数据结构]树和二叉树
概念 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集合。 树形结构中,子树之间不能有交集,否则就不是树形结构 双亲结点或父结点 :若一个结点含有子结点,则…...
监控页面卡顿PerformanceObserver
监控页面卡顿PerformanceObserver 性能观察器掘金 const observer new PerformanceObserver((list) > {}); observer.observe({entryTypes: [longtask], })...
Web开发-JavaEE应用JNDI注入RMI服务LDAP服务DNS服务高版本限制绕过
知识点: 1、安全开发-JavaEE-JNDI注入-LADP&RMI&DNS等 2、安全开发-JavaEE-JNDI注入-项目工具&手工原理等 演示案例-WEB开发-JavaEE-JNDI注入&LDAP&RMI服务&DNS服务&高版本限制绕过 JNDI全称为 Java Naming and DirectoryInterface&am…...
深度学习训练中的显存溢出问题分析与优化:以UNet图像去噪为例
最近在训练一个基于 Tiny-UNet 的图像去噪模型时,我遇到了经典但棘手的错误: RuntimeError: CUDA out of memory。本文记录了我如何从复现、分析,到逐步优化并成功解决该问题的全过程,希望对深度学习开发者有所借鉴。 训练数据&am…...
【Spring】单例模式的创建方式(Bean解析)
在Java中,单例模式(Singleton Pattern)确保一个类只有一个实例,并提供全局访问点。以下是实现单例的五种常见方式:懒汉式、饿汉式、双重检查锁、静态内部类和枚举,包括代码示例和优缺点分析。 1. 懒汉式&am…...
小小矩阵设计
在电气设计图中,矩阵设计的接线方法是通过结构化布局实现多灵活链接的技术,常用于信号切换、配电调压或更加复杂的控制场景。 今天聊一种在电气图纸中用到的一种简单矩阵接法,一眼就看明白,很大程度简化了程序控制点和继电器的使用…...
IOT项目——双轴追光系统
双轴太阳能追光系统 - ESP32实现 系统概述 这个系统使用: ESP32开发板2个舵机(水平方向和垂直方向)4个光敏电阻(用于检测光照方向)适当的电阻(用于光敏电阻分压) 接线示意图 --------------…...
深度学习基石:神经网络核心知识全解析(一)
神经网络核心知识全解析 一、神经网络概述 神经网络作为机器学习领域的关键算法,在现代生活中发挥着重要作用,广泛应用于图像识别、语音处理、智能推荐等诸多领域,深刻影响着人们的日常生活。它通过模拟人类大脑神经系统的结构和功能&#…...
什么是 金字塔缩放(Multi-scale Input)
金字塔缩放 什么是金字塔缩放(Multi-scale Input)什么场景下会用到金字塔缩放?图像识别目标跟踪图像压缩视频处理如何在计算机程序中实现金字塔缩放?准备数据缩小数据(构建金字塔的上层)存储数据使用数据(在程序中应用金字塔缩放)金字塔缩放的记忆卡片什么是金字塔缩放(M…...
从零开始配置 Zabbix 数据库监控:MySQL 实战指南
Zabbix作为一款开源的分布式监控工具,在监控MySQL数据库方面具有显著优势,能够为数据库的稳定运行、性能优化和故障排查提供全面支持。以下是使用Zabbix监控MySQL数据库的配置。 一、安装 Zabbix Agent 和 MySQL 1. 安装 Zabbix Agent services:zabbix…...
机器学习超参数优化全解析
机器学习超参数优化全解析 摘要 本文全面深入地剖析了机器学习模型中的超参数优化策略,涵盖了从参数与超参数的本质区别,到核心超参数(如学习率、批量大小、训练周期)的动态调整方法;从自动化超参数优化技术…...
【算法】双指针8道速通(C++)
1. 移动零 思路: 拿示例1的数据来举例,定义两个指针,cur和dest,cur表示当前遍历的元素,dest以及之前表示非零元素 先用cur去找非零元素,每找到一个非零元素,就让dest的下一个元素与之交换 单个…...
synchronized锁
在了解锁之前我们要先了解对象布局 什么是java对象布局 在JVM中,对象在内存中存储的布局可以分为三块区域,即实例化之后的对象 对象头:分配的空间是固定的12Byte,由Mark Word(标记字段)和Class Pointer&…...
实训Day-2 流量分析与安全杂项
目录 实训Day-2-1流量分析实战 实训目的 实训任务1 SYN半链接攻击流量分析 实训任务2 SQL注入攻击流量分析一 实训任务3 SQL注入攻击流量分析二 实训任务4 Web入侵溯源一 实训任务5 Web入侵溯源二 编辑 实训Day-2-1安全杂项实战 实训目的 实训任务1 流量分析 FTP…...
LOH 怎么进行深度标准化?
The panel of normals is applied by replacing the germline read depth of the sample with the median read depth of samples with the same genotype in our panel. 1.解释: panel of normal 正常组织,用于识别技术噪音 germline read depth: 胚系测序深度。根…...
[预备知识]3. 自动求导机制
自动求导机制 本章节介绍 PyTorch 的自动求导机制,包括计算图、反向传播和梯度计算的原理及实现。 1. 计算图原理 计算图是深度学习框架中的一个核心概念,它描述了计算过程中各个操作之间的依赖关系。 计算图由节点(节点)和边…...
蓝桥杯中的知识点
总结: 这次考的并不理想 比赛前好多知识点遗漏 但到此为止已经结束了 mod 是 模运算(Modulo Operation)的缩写,表示求两个数相除后的 余数 10mod31 (a % b) (7%21) 1e9代表1乘以10的9次方,…...
2023蓝帽杯初赛内存取证-6
这里需要用到pslist模块,结合一下查找关键词: vol.py -f memdump.mem --profile Win7SP1x64 pslist | grep -E "VeraCrypt" 将2023-06-20 16:47:41 UTC0000世界标准时间转换成北京时间: 答案:2023-06-21 00:47:41...
《MySQL 核心技能:SQL 查询与数据库概述》
MySQL 核心技能:SQL 查询与数据库概述 一、数据库概述1. 什么是数据库2.为什么要使用数据库3.数据库的相关概念3.1 数据库(DB):数据的“仓库”3.2 数据库管理系统(DBMS):数据库的“管家”3.3 SQ…...
三维几何变换
一、学习目的 了解几何变换的意义 掌握三维基本几何变换的算法 二、学习内容 在本次试验中,我们实现透视投影和三维几何变换。我们首先定义一个立方体作为我们要进行变换的三维物体。 三、具体代码 (1)算法实现 // 获取Canvas元素 con…...
TDengine 查询引擎设计
简介 TDengine 作为一个高性能的时序大数据平台,其查询与计算功能是核心组件之一。该平台提供了丰富的查询处理功能,不仅包括常规的聚合查询,还涵盖了时序数据的窗口查询、统计聚合等高级功能。这些查询计算任务需要 taosc、vnode、qnode 和…...
15.第二阶段x64游戏实战-分析怪物血量(遍历周围)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:14.第二阶段x64游戏实战-分析人物的名字 如果想实现自动打怪,那肯定…...
vue浅试(1)
先安装了vue nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置) 稍微了解了一下cursor cursor的使用 请出我们的老师: 提示词: 你是我的好朋友也是一个前端专家,你能向我传授前端知识,…...
VSCode连服务器一直处于Downloading
使用vscode的remote插件连接远程服务器时,部分服务器可能会出现一直处于Downloading VS Code Server的情况 早期的一些教程,如https://blog.csdn.net/chongbin007/article/details/126958840, https://zhuanlan.zhihu.com/p/671718415给出的方法是手动下…...
QGIS实用功能:加载天地图与下载指定区域遥感影像
QGIS 实用功能:加载天地图与下载指定区域遥感影像 目录标题 QGIS 实用功能:加载天地图与下载指定区域遥感影像一、安装天地图插件,开启地图加载之旅二、获取天地图密钥,获取使用权限三、加载天地图服务,查看地图数据四…...
mybatis-plus开发orm
1、mybatis 使用mybatis-generator自动生成代码 这个也是有系统在使用 2、mybatis-plus开发orm--有的系统在使用 MybatisPlus超详细讲解_mybatis-plus-CSDN博客...
ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库
1. ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库 1. ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库 1.1. 安装依赖1.2. 安装 osxcross 及 macOS SDK 1.2.1. 可能错误 1.3. 编译 cmake 类工程1.4. 编译 configure 类工程1.5. 单文件…...
抱佛脚之学SSM四
MyBatis基础 一个接口对应一个映射文件 在映射文件中指定对应接口指定的位置 sql语句中id对应方法名par..参数的类型,resul..返回值的类型 WEB-INF下的文件是受保护的,不能直接访问,只能通过请求转发的方式访问 SqlSessionFactory࿱…...
2.5 函数的拓展
1.匿名函数(简化代码) python中没有这个概念,通过lambda关键字可以简化函数的代码写法 2.lambda表达式 arguments lambda 参数列表 : 函数体 print(aarguments(参数)) #测试lambda #原本代码def sum1(x,y):return xyprint(sum1…...
深度学习--卷积神经网络数据增强
文章目录 一、数据增强1、什么是数据增强?2、为什么需要数据增强? 二、常见的数据增强方法1、图像旋转2、图像翻转3、图像缩放4、图像平移5、图像剪切6、图像亮度、对比度、饱和度调整7、噪声添加8、随机扰动 三、代码实现1、预处理2、使用数据增强增加训…...
Buffer of Thoughts: Thought-Augmented Reasoningwith Large Language Models
CODE: NeurIPS 2024 https://github.com/YangLing0818/buffer-of-thought-llm Abstract 我们介绍了思想缓冲(BoT),一种新颖而通用的思想增强推理方法,用于提高大型语言模型(大型语言模型)的准确性、效率和鲁棒性。具体来说,我们提出了元缓冲…...
mybatisX动态切换数据源直接执行传入sql
代码 mapper接口中方法定义如下,其中#dbName代表传入的数据源变量(取值可参考application.properties中spring.datasource.dynamic.datasource指定的数据源) DS("#dbName")List<LinkedHashMap<String, Object>> execu…...
N8N MACOS本地部署流程避坑指南
最近n8n很火,就想在本地部署一个,尝尝鲜,看说明n8n是开源软件,可以在本地部署,于是就尝试部署了下,大概用了1个多小时,把相关的过程记录一下: 1、基础软件包 abcXu-MacBook-m2-Air…...
搜索策略的基本概念
搜索是人工智能中的一个基本问题,是推理不可分割的一部分,它直接关系到智能系统的性能与运行效率,因而尼尔逊把它列为人工智能研究中的四个核心问题之一。在过去40多年中,人工智能界已对搜索技术开展了大量研究,取得了…...