补充:

思考以后觉得使用 $ = React.DOM 来写 $.div {} 的语法更好
而且不会遇到 this 被绑架的问题, 更贴近官方文档里的写法.
所以下面的方案大家先看看熟悉下, 再考虑下是否直接用 $.div 实际编程


Facebook 的 React, 不熟悉情况自己看文档..
React 是在 JS 代码中使用模版生成的 Virtual DOM 的, 但是用了 .jsx 文件
.jsx 特殊之处是代码里可以直接嵌入 HTML, 再预处理为 .js 内容
作为括号厌恶者, 我非常在乎有没有 CoffeeScript 语法可以完成这个事情
网站找到几个:

atom/react-coffee

https://github.com/atom/react-coffee (仓库不存在了...)

目测是 CommonJS 规范加载:

class Welcome extends Component
  render: ->
    @div ->
      @text "Hello"
      @span @props.name

component = new Welcome(name: "World")
element = component.buildElement()

atom/reactionary

https://github.com/atom/reactionary

element =
  div className: "greeting", key: "fancy-key",
    div className: "header",
      h1 "Hello World"
    div className: "body",
      p "Each and every one of you"

elucidata/react-coffee

https://github.com/elucidata/react-coffee

目测 CommonJS 规范:

{div}= React.DOM

class UserChip extends React.Component
  @staticMethod: -> # becomes a static method on the React Component
    "hello"

  render: ->
    (div null, "Hello")

module.exports= UserChip.toComponent()

snd/react-kup

https://github.com/snd/react-kup

目测 CommonJS

# react-kup doesn't come with react.
# require your favorite version ...
react = require 'react'
# ... and tell react kup to use it
reactKup = require('react-kup')(react)
# react-kup has been tested against react@0.10.0-rc1
# which is recommended

HelloMessage = React.createClass
  render: ->
    that = this
    reactKup (k) ->
      k.div "Hello #{that.props.name}"

mountNode = document.getElementById('example')
component = new HelloMessage({name: 'John'})

React.renderComponent component, mountNode

yang/reactive-coffee

https://github.com/yang/reactive-coffee

main = ->
  currentTask = rx.cell(tasks.at(0)) # "View model" of currently selected task

  $('body').append(
    div {class: 'task-manager'}, [
      h1 {}, bind -> ["#{tasks.length()} task(s) for today"]
      ul {class: 'tasks'}, tasks.map (task) ->
        li {class: 'task'}, [
          input {type: 'checkbox', init: -> @change => task.isDone.set(@is(':checked'))}
          span {class: 'descrip'}, bind -> [
            "#{task.descrip.get()} (#{task.priority.get()})"
          ]
          a {href: 'javascript: void 0', init: -> @click => currentTask.set(task)}, [
            'Edit'
          ]
        ]
      button {init: -> @click => tasks.push(new Task('Task', 'none', false))}, [
        'Add new task'
      ]
      taskEditor {
        task: bind -> currentTask.get()
        onSubmit: (descrip, priority) ->
          currentTask.get().descrip.set(descrip)
          currentTask.get().priority.set(priority)
      }
    ]
  )

jsdf/coffee-react

https://github.com/jsdf/coffee-react
https://github.com/jsdf/coffee-react-transform

需要预处理..

NeatComponent = React.createClass
  render: ->
    {showTitle, neat} = @props

    <div className="neat-component">
      {<h1>A Component is I</h1> if showTitle}
      Coffeescript really saves a lot of typing...
      {<p>is this component neat?<br />{neat}x{times}</p> for times in [1..10]}
    </div>

以上来自 Google 和 GitHub 搜索, 以后要有遇到再添加.

最后, 加上我做的比较粗糙的版本: https://github.com/jiyinyiyong/coffee-react-dom

Comment = React.createClass
  render: ->
    props = @props
    dom -> @div class: 'comment',
      @h2 class: 'comment-author', props.author
      props.children

返回博客首页: http://blog.tiye.me


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者