关于clojurescript:论前端框架组件状态抽象方案-基于-ClojureScript-的-Respo-为例

Respo 是本文作者基于 ClojureScript 封装的 virtual DOM 微型 MVC 计划.本文应用的工具链基于 Clojure 的, 会有一些浏览方面的不便. 背景Backbone 以前的前端计划在文本作者的理解之外, 本文作者次要是 React 方向的教训.在 Backbone 期间, Component 的概念曾经比拟清晰了.Component 实例当中保留组件的部分状态, 而组件视图依据这个状态来进行同步.到 React 呈现, 根本造成了目前大家相熟的组件化计划.每个组件有部分状态, 视图主动依据状态进行自动更新, 以及专门形象出全局状态. React 之外还有 MVVM 计划, 不过本文作者认为 MVVM 偏差于模板引擎的强化计划.MVVM 后续走向 Svelte 那样的动态剖析和代码生成会更天然一些, 而不是运行时的 MVC. React 历史计划React 当中部分状态的概念较为明确, 组件挂载时初始化, 组件卸载时革除.能够明确, 状态是保留在组件实例上的. Source of Truth 在组件当中.与此相区别的计划是组件状态脱离组件, 存储在全局, 跟全局状态相似. 组件内存储的状态不便组件本身拜访和操作, 是大家非常习惯的写法.以往的 this.state 和当初的 useState 能够很容易拜访全局状态.而 React 组件中拜访全局状态, 须要用到 Context/Redux connect 之类的计划,有应用教训的会晓得, 这两头会波及到不少麻烦, 尽管大部分会被 Redux 封装在类库外部. ...

November 20, 2020 · 3 min · jiezi

新的-Vue-Functionbased-API-当中的看到的-Clojure-的影子

这次 Vue 大会看到了 Vue 新的 API 设计, 中间有一些觉得眼熟的写法,后面也看到了工业聚的一些解读, 大致知道是什么样的用法吧..当然现场演讲过 Vue 具体实现的优化是更复杂的, 比这个 API 要多.. Vue.js作者在VueConf的演讲视频出炉Vue Function-based API RFC 中文版本揭秘Vue-3.0最具潜力的API其中比较让我觉得眼熟的是 value(0) 还有特别是 state({count: 0}) 的用法, function useMouse() { const x = value(0) const y = value(0) const update = e => { x.value = e.pageX y.value = e.pageY } onMounted(() => { window.addEventListener('mousemove', update) }) onUnmounted(() => { window.removeEventListener('mousemove', update) }) return { x, y }}value() 返回的是一个 value wrapper (包装对象)。一个包装对象只有一个属性:.value ,该属性指向内部被包装的值。这是因为当包装对象被暴露给模版渲染上下文,或是被嵌套在另一个响应式对象中的时候,它会被自动展开 (unwrap) 为内部的值。 ...

June 12, 2019 · 4 min · jiezi

关于 ClojureScript 裸写 stateful React Component

目前的 ClojureScript React 绑定都是比较复杂的, 比如 Reagent, 做了不少的修改,我打算看看直接用 cljs 裸写, 按照 React 本身的语义, 会是什么样子,网上搜到几个版本的代码, 总之核心代码就是这样了(defn my-component [props context updater] (cljs.core/this-as this (js/React.Component.call this props context updater) ;; anything else you want to set-up. use goog.object/set on this this))(gobj/extend (.. my-component -prototype) js/React.Component.prototype)https://gist.github.com/peste…https://gist.github.com/peste...https://gist.github.com/thhel…最关键的部分就是定义一个子类继承 React.Component , 然后增加 render 方法, 参考:https://developer.mozilla.org…// Rectangle - subclassfunction Rectangle() { Shape.call(this); // call super constructor.}// subclass extends superclassRectangle.prototype = Object.create(Shape.prototype);Rectangle.prototype.constructor = Rectangle;最终得到的一个版本是这样,(def comp-input-area (let [Child (fn [props context updater] (this-as this (.call React/Component this props context updater) (set! (.-state this) (clj->js {:draft “initial thing”})) this))] (set! (.-prototype Child) (.create js/Object (.-prototype React/Component))) (set! (.. Child -prototype -constructor) React/Component) (set! (.. Child -prototype -render) (fn [] (this-as this (div {} (input {:value (^js .-draft (^js .-state this)), :onChange (fn [event] (.setState this (clj->js {:draft (.. event -target -value)})))}) (^js .-draft (^js .-state this)))))) Child))注意用 this-as 这个 macro 来声明 this, 这个在 cljs 是不能随便用的,https://stackoverflow.com/a/2…不过这个 macro 有坑, 我用 let 的时候, this 被绑定到 window 上去了,cljs 编译生成的代码存在一些问题, 感觉 this 怎么说其实还是很成问题的完整代码涉及到更多的 InterOp 用法, 不专门写了.大概的意思就是需要转很多类型, 在上面的例子当中也看到了.这样一来, 通过 macro 之类的手段在语法上做改进, 很难了.另外看到 JavaScript 有个 reify https://github.com/clojure/cl…按说可以简化语法, 而且在 Om 代码有到看类似的用法, 不管比较复杂.直接跟上面的例子对比, 初始化 state 的地方不好写.总之不好完全按照 React 的语义直接封装了.当日内 Hooks 出来有带来一些改变, 不是很确定能搞成什么样, 社区也在探索中.https://github.com/Lokeh/hook… ...

October 29, 2018 · 1 min · jiezi