setup()
),解决复杂组件代码分散的问题,支持更灵活的逻辑复用(如自定义 Hook),对 TypeScript 支持更友好。data
、methods
等选项分类组织代码,适合简单组件,但逻辑复杂时代码可读性下降。Proxy
替代 Object.defineProperty
,支持动态属性监听和数组索引修改。v-model
则不包含相关代码)。delete
、has
等操作;通过 ES Module 静态分析,移除未使用的代码。例如,未使用 transition
组件时,相关代码不会打包。
useEffect
)、函数组件支持状态管理、减少类组件的复杂度。value
+ onChange
),数据流可控。ref
获取),适合简单场景。key
标识元素唯一性、类型不同则直接替换子树。key
提高复用效率,避免不必要的 DOM 操作。React.memo
、useMemo
/useCallback
缓存计算结果。React.lazy
+ Suspense
实现按需加载。react-window
处理长列表渲染。Proxy
代理对象,结合 Reflect
反射操作实现数据劫持。Proxy
可拦截对象的所有操作(如 get
、set
、deleteProperty
),自动追踪依赖并触发更新。Proxy
无需预先定义属性(Vue2 需 Vue.set
)。javascript
data
、methods
),复杂组件难以维护。useFetch
)封装可复用逻辑。ref
(基本类型包装)、reactive
(对象代理)、toRefs
(解构响应式对象)。TEXT
、CLASS
),仅对比变化的属性。v-model
则剔除相关代码。portal
技术将组件渲染到指定 DOM 节点(如 body
),解决模态框层级问题。Promise
管理异步组件,通过插槽展示加载状态(如骨架屏)。createGlobalState
createGlobalState
是 VueUse 库中用于创建全局响应式状态的核心工具,其实现巧妙结合了 闭包、Vue3 响应式系统 和 effectScope
机制。以下是其核心实现逻辑与原理的深度解析:
state
)保存全局状态实例,确保全局唯一性。首次调用时通过 stateFactory
初始化状态,后续调用直接返回已存在的实例。
javascript
effectScope
的作用effectScope(true)
创建一个独立的副作用作用域(detached: true
),将 stateFactory
中生成的响应式状态(如 ref
、computed
、watch
)自动收集到该作用域中。scope.stop()
时,该作用域内所有副作用(如 watch
监听)会被自动清理,避免内存泄漏。__SSR__
常量区分客户端与服务端环境。在服务端,状态会被挂载到请求级别的上下文对象(ssrContext
),确保每个请求的隔离性。
javascript
watch
),可能导致内存泄漏。effectScope
优势:通过作用域统一管理副作用生命周期,无需手动调用 stop()
,适合需要自动清理的场景(如组件卸载)。onScopeDispose()
注册清理回调,确保作用域停止时自动释放资源:
javascript
createGlobalState
无复杂中间件或 DevTools 集成,适合简单全局状态(如用户 token、主题配置)。useGlobalState()
访问,无需通过 Props 或 Provide/Inject 传递。SSR 兼容性
类型安全
性能优化
createGlobalState
的实现核心在于 闭包的单例模式 + effectScope
的副作用管理,既保留了 Vue3 响应式系统的自动化优势,又通过作用域机制规避了内存泄漏风险。其轻量级特性使其成为小型项目或简单全局状态管理的理想选择,但在复杂场景(如持久化、状态分片)中仍需结合 Pinia 等专业库。useState
、useEffect
的状态,确保调用顺序一致。useRef
捕获最新值。React.memo
或 shouldComponentUpdate
优化。Proxy
),开发者无感知更新。setState
),强调不可变数据。v-if
),内置优化。html
jsx
useContext
+ useReducer
实现全局状态管理:
javascript
const data = { count: 0 };
const proxy = new Proxy(data, {
get(target, key) {
track(target, key); // 依赖收集
return Reflect.get(target, key);
},
set(target, key, value) {
Reflect.set(target, key, value);
trigger(target, key); // 触发更新
return true;
}
});
let initialized = false;
let state: any;
const scope = effectScope(true);
return () => {
if (!initialized) {
state = scope.run(() => stateFactory())!;
initialized = true;
}
return state;
};
if (__SSR__ && getCurrentInstance()) {
const ssrContext = useSSRContext();
// 将状态绑定到 SSR 上下文,避免跨请求污染
}
const useGlobalTimer = createGlobalState(() => {
const interval = ref<NodeJS.Timeout>();
const start = () => { /* 启动定时器 */ };
const stop = () => { clearInterval(interval.value) };
onScopeDispose(stop); // 作用域销毁时自动清理
return { start, stop };
});
<input v-model="text" />
<script setup>
const text = ref('');
</script>
const [text, setText] = useState('');
<input value={text} onChange={(e) => setText(e.target.value)} />
const StateContext = createContext();
const App = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StateContext.Provider value={{ state, dispatch }}>
<ChildComponent />
</StateContext.Provider>
);
};