能否脱离React使用MobX?原生JS使用遇错求解决方案
在原生JavaScript中使用MobX的问题与解决方案
好问题!先直接给你结论:是的,你写的这种MobX语法确实没法在无打包/转译的原生JS环境下直接运行,不过咱们可以通过调整使用方式来解决,或者换用更适合原生环境的替代方案。
先说说你遇到的两个错误原因
1. @observable 引发的语法错误
@observable 属于ES装饰器语法,目前绝大多数浏览器还未原生支持这个特性(只有部分浏览器开启实验性标志后才能用,完全不适合生产环境),所以直接写会被浏览器判定为非法字符。
2. exports is not defined 错误
你引用的CDN版本是针对Node.js环境的CommonJS模块格式,而浏览器不认识Node.js的exports/require模块语法,自然会抛出这个错误。
不用打包/转译,也能在原生JS里用MobX
其实MobX提供了适合浏览器的UMD/ES模块版本,只要调整引入方式和写法,就能直接用:
步骤1:引入正确的MobX CDN版本
选择UMD格式的CDN链接(比如MobX 6.x的UMD版本),在HTML中这样引入:
<script src="https://cdn.jsdelivr.net/npm/mobx@6.10.0/dist/mobx.umd.min.js"></script>
这个版本会把MobX挂载到全局的mobx对象上,浏览器能直接识别。
步骤2:改用非装饰器语法定义Store
放弃@observable装饰器,改用MobX提供的makeAutoObservable或makeObservableAPI手动定义可观察对象,示例代码:
class MyStore { data = 'foo'; constructor() { // 自动将类的属性和方法转为可观察/动作 mobx.makeAutoObservable(this); } } const myStore = new MyStore(); // 测试可观察性 console.log(myStore.data); // 输出 'foo' // 修改数据要放在动作里(或runInAction) mobx.runInAction(() => { myStore.data = 'bar'; }); console.log(myStore.data); // 输出 'bar'
这样就完全避开了装饰器和模块语法的问题,在原生浏览器环境下就能正常运行。
替代方案:轻量响应式库
如果觉得MobX还是有点重,或者不想调整写法,这些轻量库更适合原生JS环境:
1. Vue Reactivity 模块
Vue的响应式系统可以单独抽离出来使用,体积小、API简洁,支持ES模块引入:
<script type="module"> import { reactive, watch } from 'https://unpkg.com/@vue/reactivity@3.3.4/dist/reactivity.esm-browser.js'; // 创建响应式对象 const myStore = reactive({ data: 'foo' }); // 监听数据变化 watch(() => myStore.data, (newVal) => { console.log('数据更新了:', newVal); }); // 修改数据 myStore.data = 'bar'; // 会触发watch的回调 </script>
2. 手写简易响应式
如果需求非常简单,自己用Proxy写个发布订阅式的响应系统也不难,核心逻辑就是用Proxy监听对象变化,通知订阅者:
function reactive(obj) { const subscribers = new Set(); return new Proxy(obj, { set(target, key, value) { target[key] = value; // 通知所有订阅者 subscribers.forEach(cb => cb(target[key])); return true; }, get(target, key) { return target[key]; } }); } // 使用示例 const store = reactive({ data: 'foo' }); // 订阅变化 store.subscribe = (cb) => subscribers.add(cb); store.subscribe((newVal) => console.log('数据变了:', newVal)); store.data = 'bar'; // 触发订阅回调
内容的提问来源于stack exchange,提问作者chitzui
相关产品推荐
相关产品推荐

