狀態管理方案對比與決策

1. 狀態管理的基本概念

現代前端應用隨著功能復雜度提升,狀態管理已成為架構設計的核心挑戰。狀態管理本質上解決的是數據的存儲、變更追蹤和響應式更新問題,以確保UI與底層數據保持同步。

核心挑戰:

  • 狀態共享與組件通信
  • 可預測的狀態變更
  • 性能優化與重渲染控制
  • 異步狀態處理
  • 開發體驗與調試便利性

2. 主流狀態管理方案對比

Redux

核心原理:
基于單向數據流和不可變狀態的Flux架構實現。全局維護一個狀態樹,通過dispatch action觸發reducer函數來更新狀態。

// Store 創建
import { createStore } from 'redux';const initialState = { counter: 0 };
const reducer = (state = initialState, action) => {switch (action.type) {case 'INCREMENT':return { ...state, counter: state.counter + 1 };default:return state;}
};const store = createStore(reducer);// 使用示例
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState()); // { counter: 1 }// React組件中使用
import { useSelector, useDispatch } from 'react-redux';function Counter() {const counter = useSelector((state) => state.counter);const dispatch = useDispatch();return (<div><span>{counter}</span><button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button></div>);
}

優勢:

  • 可預測性高:狀態變更過程清晰可追蹤
  • 強大的開發者工具生態支持(Redux DevTools)
  • 中間件系統便于擴展(redux-thunk, redux-saga等)
  • 大型社區和豐富的學習資源
  • 適合復雜狀態邏輯和多人協作場景

缺陷:

  • 模板代碼較多(actions, reducers, selectors)
  • 學習曲線陡峭
  • 小型應用顯得過度工程化
  • 異步處理需要額外中間件

MobX

核心原理:
基于可觀察對象(Observable)實現響應式狀態管理,通過注解或函數包裝使普通對象具備響應式特性。

// 定義狀態
import { makeObservable, observable, action, computed } from 'mobx';
import { observer } from 'mobx-react-lite';class CounterStore {constructor() {makeObservable(this, {count: observable,increment: action,doubleCount: computed});}count = 0;increment() {this.count++;}get doubleCount() {return this.count * 2;}
}const counterStore = new CounterStore();// React組件中使用
const CounterView = observer(() => {return (<div><span>Count: {counterStore.count}</span><span>Double: {counterStore.doubleCount}</span><button onClick={() => counterStore.increment()}>+</button></div>);
});

優勢:

  • 更少的模板代碼,直觀的API
  • 優秀的性能表現,精確的組件重渲染控制
  • 面向對象編程模型,更接近傳統開發思維
  • 自動追蹤依賴關系,無需手動優化

缺陷:

  • 狀態變更不夠明確,調試難度較高
  • 學習響應式概念有一定門檻
  • 裝飾器語法在JavaScript生態中標準化程度不高
  • 需要謹慎處理observable對象以避免性能問題

Recoil

核心原理:
Facebook開發的專為React設計的原子化狀態管理庫,通過atom和selector概念構建狀態依賴圖。

// 定義狀態
import { atom, selector, useRecoilState, useRecoilValue } from 'recoil';const counterState = atom({key: 'counterState',default: 0,
});const doubleCountState = selector({key: 'doubleCountState',get: ({get}) => {const count = get(counterState);return count * 2;},
});// React組件中使用
function Counter() {const [count, setCount] = useRecoilState(counterState);const doubleCount = useRecoilValue(doubleCountState);return (<div><span>Count: {count}</span><span>Double: {doubleCount}</span><button onClick={() => setCount(count + 1)}>+</button></div>);
}

優勢:

  • 原子化狀態設計,精細控制組件訂閱
  • 與React Concurrent Mode兼容設計
  • 內置對異步狀態和派生狀態的支持
  • 類React Hooks的API設計,學習成本低
  • 良好的代碼分離支持,適合代碼分割

缺陷:

  • 相對年輕,生態系統和社區支持有限
  • 需要RecoilRoot上下文包裹
  • 大型應用中atom鍵名管理挑戰
  • 未明確支持服務端渲染

Zustand

核心原理:
基于hook的輕量級狀態管理庫,通過創建獨立store并提供選擇性訂閱機制。

// 創建store
import create from 'zustand';const useStore = create((set) => ({count: 0,increment: () => set((state) => ({ count: state.count + 1 })),
}));// React組件中使用
function Counter() {const count = useStore((state) => state.count);const increment = useStore((state) => state.increment);return (<div><span>{count}</span><button onClick={increment}>+</button></div>);
}

優勢:

  • 極簡API設計,幾乎無模板代碼
  • 不需要Provider包裹組件
  • 中間件系統支持(redux-devtools, immer, persist等)
  • 優秀的性能表現,內置狀態訪問優化
  • 支持多store設計

缺陷:

  • 對大型狀態結構的管理不如Redux系統化
  • 狀態共享模式需要自行設計
  • 相對較新,生產環境驗證案例較少
  • 文檔相對簡潔

3. 實例分析:不同場景下的狀態管理選擇

場景一:大型企業應用

特點:多人協作、復雜業務邏輯、嚴格的狀態變更控制需求

最佳選擇:Redux + Redux Toolkit

// 使用Redux Toolkit簡化Redux開發
import { createSlice, configureStore } from '@reduxjs/toolkit';const counterSlice = createSlice({name: 'counter',initialState: { value: 0 },reducers: {increment: (state) => {// RTK允許在reducer中直接修改狀態,內部使用Immerstate.value += 1;}}
});export const { increment } = counterSlice.actions;
const store = configureStore({reducer: {counter: counterSlice.reducer}
});

實施原因

  • 明確的狀態管理模式便于團隊協作和規范執行
  • 完備的中間件生態滿足復雜業務需求
  • DevTools提供完整的狀態變更追蹤,便于調試
  • Redux Toolkit減少樣板代碼,降低學習門檻

場景二:中型SPA應用

特點:中等復雜度、注重開發效率、需要精細控制渲染性能

最佳選擇:MobX

// 使用MobX狀態樹(MST)增強類型安全和結構化狀態
import { types, flow, onSnapshot } from 'mobx-state-tree';const UserStore = types.model('UserStore', {users: types.array(types.model({id: types.identifier,name: types.string})),loading: types.optional(types.boolean, false)}).actions(self => ({fetchUsers: flow(function* () {self.loading = true;try {const response = yield fetch('/api/users');const data = yield response.json();self.users = data;} finally {self.loading = false;}})}));const store = UserStore.create({ users: [] });
onSnapshot(store, snapshot => console.log('New state:', snapshot));

實施原因

  • 響應式設計顯著減少重渲染,提升應用性能
  • 更自然的編程模型降低開發負擔
  • 衍生值和反應能力簡化狀態依賴管理
  • 良好封裝的異步流程處理

場景三:輕量級應用或組件庫

特點:注重體積和啟動性能、簡潔明了的API需求

最佳選擇:Zustand

// 創建多個獨立store并實現通信
import create from 'zustand';
import { devtools, persist } from 'zustand/middleware';// 用戶認證store
const useAuthStore = create(persist(devtools((set) => ({user: null,login: (userData) => set({ user: userData }),logout: () => set({ user: null })})),{ name: 'auth-storage' })
);// 購物車store
const useCartStore = create((set, get) => ({items: [],addItem: (item) => set((state) => ({ items: [...state.items, item] })),checkout: async () => {const authStore = useAuthStore.getState();if (!authStore.user) {throw new Error('Must login first');}// 處理結賬邏輯...}
}));

實施原因

  • 極簡API設計最小化學習成本
  • 無Provider要求簡化應用結構
  • 包體積小,適合性能敏感場景
  • 靈活的store設計適合按功能模塊拆分狀態

場景四:實驗性功能或需要細粒度狀態控制

特點:需要React并發特性、原子化狀態需求

最佳選擇:Recoil

// 實現復雜的異步數據流和結構化狀態處理
import { atom, selector, selectorFamily, useRecoilValue } from 'recoil';// 基礎狀態
const userIdState = atom({key: 'userId',default: 1
});// 異步派生狀態
const userInfoQuery = selectorFamily({key: 'userInfo',get: (userId) => async () => {const response = await fetch(`/api/users/${userId}`);return response.json();}
});// 組合多個狀態
const userWithPostsSelector = selector({key: 'userWithPosts',get: async ({get}) => {const userId = get(userIdState);const user = await get(userInfoQuery(userId));const postsResponse = await fetch(`/api/users/${userId}/posts`);const posts = await postsResponse.json();return { ...user, posts };}
});function UserProfile() {const userData = useRecoilValue(userWithPostsSelector);// 渲染用戶數據...
}

實施原因

  • 原子化設計減少不必要的重渲染
  • 內置異步狀態處理簡化數據獲取邏輯
  • 與React Suspense自然集成
  • 適合實驗性功能和新特性嘗試

4. 項目選型決策框架

4.1 評估維度權重模型

評估維度ReduxMobXRecoilZustand
可預測性★★★★★★★★☆☆★★★★☆★★★★☆
性能優化★★★☆☆★★★★★★★★★☆★★★★★
學習曲線★★☆☆☆★★★☆☆★★★★☆★★★★★
開發效率★★☆☆☆★★★★☆★★★★☆★★★★★
調試能力★★★★★★★★☆☆★★★★☆★★★★☆
社區支持★★★★★★★★★☆★★★☆☆★★★☆☆
擴展能力★★★★★★★★☆☆★★★☆☆★★★★☆
代碼量★★☆☆☆★★★★☆★★★★☆★★★★★

4.2 選型決策

  1. 項目規模判斷

    • 大型企業級應用 → Redux + RTK
    • 中小型應用 → 繼續評估
  2. 團隊因素考量

    • 團隊熟悉Redux生態 → Redux + RTK
    • 傾向OOP編程模式 → MobX
    • 習慣React Hooks → Zustand/Recoil
  3. 性能需求評估

    • 復雜UI與大量狀態依賴 → MobX/Recoil
    • 對包大小和啟動速度敏感 → Zustand
  4. 狀態復雜度分析

    • 深層嵌套狀態結構 → Redux + Immer
    • 獨立原子化狀態需求 → Recoil
    • 簡單扁平狀態結構 → Zustand
  5. 開發體驗優先級

    • 強調簡潔API和快速開發 → Zustand
    • 注重可測試性和狀態追蹤 → Redux
    • 需要細粒度控制和異步流程 → MobX/Recoil

5. 關鍵樣例分析

5.1 異步狀態處理對比

Redux (使用Redux Toolkit):

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';export const fetchUsers = createAsyncThunk('users/fetchUsers',async () => {const response = await fetch('/api/users');return response.json();}
);const usersSlice = createSlice({name: 'users',initialState: {entities: [],loading: false,error: null},reducers: {},extraReducers: (builder) => {builder.addCase(fetchUsers.pending, (state) => {state.loading = true;}).addCase(fetchUsers.fulfilled, (state, action) => {state.loading = false;state.entities = action.payload;}).addCase(fetchUsers.rejected, (state, action) => {state.loading = false;state.error = action.error.message;});}
});

MobX:

import { makeAutoObservable, runInAction } from 'mobx';class UsersStore {users = [];loading = false;error = null;constructor() {makeAutoObservable(this);}async fetchUsers() {this.loading = true;this.error = null;try {const response = await fetch('/api/users');const data = await response.json();runInAction(() => {this.users = data;this.loading = false;});} catch (error) {runInAction(() => {this.error = error.message;this.loading = false;});}}
}

Zustand:

import create from 'zustand';const useUsersStore = create((set) => ({users: [],loading: false,error: null,fetchUsers: async () => {set({ loading: true, error: null });try {const response = await fetch('/api/users');const users = await response.json();set({ users, loading: false });} catch (error) {set({ error: error.message, loading: false });}}
}));

Recoil:

import { atom, selector, useRecoilValueLoadable } from 'recoil';const usersQueryAtom = atom({key: 'UsersQuery',default: null,
});const usersResultSelector = selector({key: 'UsersResult',get: async ({get}) => {get(usersQueryAtom); // 觸發依賴追蹤const response = await fetch('/api/users');if (!response.ok) {throw new Error('Network error');}return response.json();}
});function UsersList() {const usersLoadable = useRecoilValueLoadable(usersResultSelector);switch(usersLoadable.state) {case 'loading':return <div>Loading...</div>;case 'hasError':return <div>Error: {usersLoadable.contents.message}</div>;case 'hasValue':return (<ul>{usersLoadable.contents.map(user => (<li key={user.id}>{user.name}</li>))}</ul>);}
}

5.2 狀態共享和模塊化設計

Redux (使用Redux Toolkit):

// 定義多個狀態切片
const userSlice = createSlice({/*...*/});
const cartSlice = createSlice({/*...*/});
const orderSlice = createSlice({/*...*/});// 合并到根reducer
const rootReducer = combineReducers({user: userSlice.reducer,cart: cartSlice.reducer,order: orderSlice.reducer
});// 創建store
const store = configureStore({reducer: rootReducer
});// 狀態選擇器
const selectCartTotal = (state) => {return state.cart.items.reduce((total, item) => total + item.price * item.quantity, 0);
};// 跨狀態操作
const checkoutThunk = () => (dispatch, getState) => {const state = getState();// 檢查用戶是否已登錄if (!state.user.isLoggedIn) {dispatch(openLoginModal());return;}// 將購物車內容轉為訂單const order = {items: state.cart.items,total: selectCartTotal(state),userId: state.user.id};dispatch(createOrder(order));dispatch(clearCart());
};

Zustand (模塊化設計):

// 創建多個獨立但可互操作的store
const useUserStore = create((set) => ({/*...*/}));
const useCartStore = create((set, get) => ({/*...*/}));
const useOrderStore = create((set, get) => ({/*...*/}));// 創建派生狀態
const useCartTotal = () => {return useCartStore(state => state.items.reduce((total, item) => total + item.price * item.quantity, 0));
};// 跨store操作
function useCheckout() {const userState = useUserStore();const { items, clearCart } = useCartStore();const { createOrder } = useOrderStore();const total = useCartTotal();return () => {if (!userState.isLoggedIn) {userState.openLoginModal();return;}const order = {items,total,userId: userState.id};createOrder(order);clearCart();};
}

6. 未來趨勢

6.1 狀態管理發展方向

  1. React狀態原生化

    • React內置hooks如useReducer和useContext不斷增強
    • 狀態管理逐漸向框架層面整合,減少外部依賴
  2. 原子化狀態模型崛起

    • 細粒度狀態控制成為主流設計模式
    • 更精確的組件重渲染控制與優化
  3. 去中心化狀態架構

    • 從全局單一狀態樹轉向模塊化、獨立狀態設計
    • 按需加載狀態邏輯,更好支持代碼分割
  4. 不可變數據結構優化

    • 像Immer這樣的不可變性工具成為標配
    • 平衡不可變性和性能的新方案涌現
  5. 異步狀態處理標準化

    • 異步狀態管理模式趨于統一和簡化
    • 與React Suspense等新特性深度整合

6.2 項目遷移與混合方案

狀態管理遷移策略:

  1. 漸進式遷移

    • 識別應用中獨立的功能模塊
    • 從非核心功能開始替換狀態管理方案
    • 設計適配層以確保新舊狀態管理方案協同工作
  2. 混合狀態架構

// Redux核心狀態與Zustand局部狀態混合使用示例// 全局Redux狀態
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';const store = configureStore({reducer: rootReducer
});// Zustand局部狀態
import create from 'zustand';const useLocalFormState = create((set) => ({formData: {},updateField: (field, value) => set(state => ({formData: { ...state.formData, [field]: value }}))
}));// 組件中的混合使用
function ComplexForm() {// 全局Redux狀態const user = useSelector(state => state.user);const dispatch = useDispatch();// 局部Zustand狀態const { formData, updateField } = useLocalFormState();const handleSubmit = () => {// 提交前驗證可訪問兩種狀態if (!user.isLoggedIn) {dispatch(redirectToLogin());return;}dispatch(submitFormAction({...formData,userId: user.id}));};// 渲染表單...
}

7. 結語

狀態管理選型應基于項目規模、團隊特點、性能要求和業務復雜度進行綜合評估,不存在"銀彈"般的解決方案。

同時隨著前端生態不斷演進,保持對狀態管理新趨勢的理解與實踐嘗試,也能幫助團隊在復雜應用開發中作出更明智的技術選擇。

實踐應該從小規模嘗試開始,同時確保團隊完全理解所選方案的優缺點,并建立清晰的狀態設計規范,以確保長期的代碼可維護性。

8. 參考資源

官方文檔和指南

  • Redux

    • Redux官方文檔
    • Redux Toolkit指南
    • Redux風格指南
  • MobX

    • MobX官方文檔
    • MobX-State-Tree指南
    • MobX響應式原理解析
  • Recoil

    • Recoil官方文檔
    • Recoil入門指南
    • Recoil核心概念
  • Zustand

    • Zustand GitHub倉庫
    • Zustand使用指南
    • Zustand中間件文檔

深度技術文章和博客

  • 比較現代React狀態管理庫
  • Redux、MobX與Context API: 何時選擇什么?
  • React狀態管理性能對比
  • Recoil原子化狀態設計理念分析
  • 為什么Zustand正在超越Redux
  • 異步狀態管理實踐

教程

  • Redux完全指南 (Maximilian Schwarzmüller)
  • MobX與React: 構建響應式應用
  • Recoil從入門到精通
  • Zustand實用教程
  • React Query與狀態管理整合

示例項目和代碼庫

  • Redux Real-World示例
  • MobX-TodoMVC
  • Recoil示例集合
  • Zustand實戰項目
  • 不同狀態管理方案對比項目

工具和擴展

  • Redux DevTools
  • MobX DevTools
  • Recoilize開發者工具
  • React Query DevTools
  • Immer.js - 不可變數據處理庫

社區資源和論壇

  • React官方討論狀態管理的Issue
  • React狀態管理最佳實踐調查結果
  • 狀態管理技術討論組
  • React狀態管理性能基準測試
  • 2023年React狀態管理趨勢報告

書籍

  • 《Learning Redux》- Daniel Bugl
  • 《Managing React State》- Cory House
  • 《MobX Quick Start Guide》- Pavan Podila & Michel Weststrate
  • 《React設計模式與最佳實踐》- Michele Bertoli

如果你覺得這篇文章有幫助,歡迎點贊收藏,也期待在評論區看到你的想法和建議!👇

終身學習,共同成長。

咱們下一期見

💻

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86692.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86692.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86692.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Fetch與Axios:區別、聯系、優缺點及使用差異

Fetch與Axios&#xff1a;區別、聯系、優缺點及使用差異 文章目錄 Fetch與Axios&#xff1a;區別、聯系、優缺點及使用差異一、聯系二、區別1. 瀏覽器支持與兼容性2. 響應處理3. 請求攔截和響應攔截4. 錯誤處理 三、優缺點1. Fetch API優點缺點 2. Axios優點缺點 四、使用上的差…

【Docker】快速入門與項目部署實戰

我們在部署一個項目時&#xff0c;會出現一系列問題比如&#xff1a; 命令太多了&#xff0c;記不住軟件安裝包名字復雜&#xff0c;不知道去哪里找安裝和部署步驟復雜&#xff0c;容易出錯 其實上述問題不僅僅是新手&#xff0c;即便是運維在安裝、部署的時候一樣會覺得麻煩…

Java面試題尚硅谷版第1季

1、寫出如下代碼運行結果 1.1、 使用局部變量表和操作數棧解題 1.2、使用前置和后置遞增解題 2、寫一個單例模式 2.1、考察知識點 2.2、單例模式實現 3、類加載和初始化順序 package classload;public class Father {private int i test();private static int j method();st…

關于Qt阻斷樣式繼承的解決辦法

引言 在使用 Qt 開發桌面應用時&#xff0c;借助樣式表&#xff08;StyleSheet&#xff09;來統一定義界面風格是非常常見的做法。通常&#xff0c;你會在主程序中通過 qApp->setStyleSheet(...) 或者直接給某個父控件設置樣式表&#xff0c;讓所有的子控件都采用相同的配色…

鼠標右鍵添加新建某種文件的方法

場景 我經常用到.emmx&#xff0c;.eddx文件&#xff0c;電腦上裝的是wpsX億圖&#xff08;因為有wps會員&#xff09;&#xff0c;沒有開億圖會員。 然后問題就是&#xff0c;思維導圖和流程圖我都能正常開&#xff0c;正常編輯&#xff0c;但鼠標右鍵沒有新建這兩個文件的按…

Inxpect安全雷達傳感器與控制器:動態檢測 + 抗干擾技術重構工業安全防護體系

Inxpect 推出工業安全領域新型智能傳感器與控制器&#xff0c;其核心產品為雷達掃描儀&#xff0c;具備動態調整檢測區域、抗干擾能力強等特點&#xff0c;可精準檢測危險區域人員進入或存在情況&#xff0c;適用于移動機器人等場景。 Inxpect安全雷達傳感器核心功能 動態檢測…

【AI學習】李廣密與階躍星辰首席科學家張祥雨對談:多模態發展的歷史和未來

仔細閱讀了文章《專訪張祥雨&#xff1a;多模態推理和自主學習是未來的 2 個 「GPT-4」 時刻》 https://mp.weixin.qq.com/s/892QuRPH9uP6zN6dS-HZMw 非常贊嘆的一篇文章&#xff0c;說清楚了NLP、CV發展中的許多重大問題&#xff0c;讀來醍醐灌頂&#xff01;這樣的文章&…

C++中std::deque詳解和實戰工程代碼示例

C中std::deque詳解和實戰工程代碼示例 std::deque&#xff08;雙端隊列&#xff09;是 C 標準庫中的一個序列容器&#xff0c;與 std::vector 類似&#xff0c;但它支持從頭部和尾部高效地插入和刪除元素。它底層采用分段連續空間實現&#xff0c;兼具靈活性與性能。 一、基本…

【AI大模型入門指南】概念與專有名詞詳解 (二)

【AI大模型入門指南】概念與專有名詞詳解 &#xff08;二&#xff09; 一 、前言 當你和聊天機器人聊得天花亂墜時&#xff0c;當你用文字讓AI生成精美圖片時&#xff0c;當手機相冊自動幫你分類照片時 —— 這些看似智能的操作背后&#xff0c;都藏著 AI 大模型的身影。 本…

AIStor 的模型上下文協議 (MCP) 服務器:管理功能

在本系列的上一篇博文中&#xff0c;我們討論了 MinIO AIStor 的模型上下文協議 (MCP) 服務器的基本用戶級功能。我們學習了如何使用人類語言命令查看存儲桶的內容、分析對象并標記它們以便將來處理&#xff0c;以及如何通過 LLM&#xff08;例如 Anthropic Claude&#xff09;…

期權末日輪實值期權盈利未平倉怎么辦?

本文主要介紹期權末日輪實值期權盈利未平倉怎么辦&#xff1f;期權末日輪實值期權盈利未平倉該怎么辦&#xff0c;需要明確幾個關鍵點&#xff1a;末日輪指的是期權到期日臨近的時候&#xff0c;通常指最后一周&#xff0c;尤其是最后一天&#xff0c;這時候時間價值衰減很快&a…

C++/Qt 聯合編程中的定時器使用陷阱:QObject::startTimer 報錯詳解

在 Qt 開發中&#xff0c;QTimer 是一個常用的工具類&#xff0c;用于處理定時事件。但不少開發者在 C/Qt 聯合編程&#xff0c;尤其是在工具類、靜態類、線程中使用定時器時&#xff0c;會遇到如下令人困惑的報錯&#xff1a; QObject::startTimer: Timers can only be used …

CentOS7.9 查詢運維安全日志,排查惡意用戶

1、查看系統版本 cat /etc/redhat-release uname -a 2、查看所有賬號 cat /etc/shadow 3、修改 root 密碼 passwd 3、查看賬號ID id jinzhi 4、查看登錄日志 lastlog 5、查看操作日志 cat .bash_history sudo cat /home/yunwei/.bash_history sudo grep root /va…

多模態大語言模型arxiv論文略讀(117)

Training-free Zero-shot Composed Image Retrieval via Weighted Modality Fusion and Similarity ?? 論文標題&#xff1a;Training-free Zero-shot Composed Image Retrieval via Weighted Modality Fusion and Similarity ?? 論文作者&#xff1a;Ren-Di Wu, Yu-Yen L…

如何正確的配置eureka server集群

將 Eureka Server 實例的 hostname 都配置成相同的值&#xff0c;在 Eureka Server 集群環境下同樣是不推薦且通常會導致嚴重問題的&#xff0c; 核心問題&#xff1a;Eureka Server 集群的工作機制 Eureka Server 集群通過相互注冊&#xff08;Peering&#xff09;來實現高可…

AI支持下的-ArcGIS數據處理、空間分析、可視化及多案例綜合應用

查看原文>>> 從入門到精通-AI支持下的-ArcGIS數據處理、空間分析、可視化及多案例綜合應用 結合ArcGIS和GPT的優勢&#xff0c;本文重點進行AI大模型應用、ArcGIS工作流程及功能、Prompt使用技巧、AI助力工作流程、AI助力數據讀取與處理、AI助力空間分析、AI助力遙感…

vue3-ts: v-model 和 props 的關系

在 Vue.js 中&#xff0c;v-model 是一個語法糖&#xff0c;它實際上是 :value 和 input 事件的組合。 當你使用 v-model 綁定一個組件時&#xff0c;默認情況下&#xff0c;組件會通過 props 接收 value 這個 prop&#xff0c; 并通過觸發 input 事件來更新父組件中的數據。 …

學車筆記 變擋

超15就可以加一檔了 有些人對手動擋的檔位有一些誤解_嗶哩嗶哩_bilibili 獻給所有新司機.開手動檔擺脫頓挫的根本方法.學會看轉速!沒那么復雜!_嗶哩嗶哩_bilibili 減速到怠速降一檔

STM32的DMA簡介

STM32的DMA簡介 一、DMA概述 DMA&#xff08;Direct Memory Access&#xff0c;直接存儲器存取&#xff09;是一種硬件機制&#xff0c;它允許外設和存儲器之間或者存儲器和存儲器之間進行高速數據傳輸&#xff0c;而無需CPU的干預。這種機制可以極大地節省CPU資源&#xff0c…

Spring-AOP知識點

一、AOP簡介 1.AOP概念 2.AOP思想實現方案 3.AOP相關概念 二、基于xml配置AOP 1.快速入門 2.AOP配置詳解 3.AOP原理剖析 三、基于注解配置AOP 1.快速入門 2.注解方式AOP配置詳解 抽取切點表達式