Mithril 是一个现代化的 JavaScript 框架,用于构建单页面应用。它非常小巧(< 8kb gzip),且内置了路由和 XHR 工具。
很多知名公司,包括 Vimeo 和 Nike,以及开源平台 Lichess 等都在使用 Mithril。
如果你是有经验的前端开发者,想知道 Mithril 与其它库/框架的区别,请查看框架对比。
Mithril 支持 IE9 及以上的所有浏览器。
使用 Mithril 最简单的方式是直接从 CDN 引入 Mithril 文件,并按照本教程学习。本教程包含了大部分的 API,但只需花费你大概 10 分钟时间。
首先我们创建一个 HTML 文件:
<body>
<script src="//unpkg.com/mithril/mithril.js"></script>
<script>
var root = document.body
// your code goes here!
</script>
</body>
我们从最简单的开始,在页面中输出一段文本。添加下列代码到文件中:
var root = document.body
m.render(root, "Hello world")
下面来修改这段文本:
m.render(root, "My first app")
如你所见,创建和修改 HTML 用的是相同的代码。Mithril 会自动计算出最高效的方式来更新 HTML,并不会每次都重新创建 HTML。
我们把文本包裹在 <h1>
标签中:
m.render(root, m("h1", "My first app"))
m()
函数可以描述任何 HTML 结构。例如在 <h1>
标签上添加一个类:
m("h1", {class: "title"}, "My first app")
例如创建多个元素:
[
m("h1", {class: "title"}, "My first app"),
m("button", "A button"),
]
以及创建嵌套的元素:
m("main", [
m("h1", {class: "title"}, "My first app"),
m("button", "A button"),
])
也可以通过一个 Babel 插件来直接使用 HTML 语法创建元素:
// HTML syntax via Babel's JSX plugin
<main>
<h1 class="title">My first app</h1>
<button>A button</button>
</main>
组件是一个带 view
方法的对象:
var Hello = {
view: function() {
return m("main", [
m("h1", {class: "title"}, "My first app"),
m("button", "A button"),
])
}
}
然后使用 m.mount
来激活组件:
m.mount(root, Hello)
激活组件后就生成了这样的元素:
<main>
<h1 class="title">My first app</h1>
<button>A button</button>
</main>
m.mount
的功能和 m.render
类似。但 m.render
只会渲染一次 HTML,而 m.mount
会激活 Mithril 的自动重绘系统。我们通过添加一个事件,来帮助理解这一概念:
var count = 0 // added a variable
var Hello = {
view: function() {
return m("main", [
m("h1", {class: "title"}, "My first app"),
// changed the next line
m("button", {onclick: function() {count++}}, count + " clicks"),
])
}
}
m.mount(root, Hello)
我们在按钮上定义了 onclick
事件,点击按钮时会增加 count
变量的值。同时把 count
的值渲染到了按钮文本中。
现在点击按钮,按钮的文本会自动更新。因为我们用了 m.mount
,所以无需每次都调用 m.render
来修改按钮文本。
无需担心使用 m.mount
会带来性能问题。事实证明 Mithril 的渲染更新是非常快的,因为它只会涉及到 DOM 中需要更新的部分。例如上例中,点击按钮时,唯一需要更新的就是文本。
路由功能用于在多个页面之间相互跳转。
我们来创建一个组件,这个组件包含一个链接:
var Splash = {
view: function() {
return m("a", {href: "#!/hello"}, "Enter!")
}
}
该链接的 #!
部分称为 hashbang,/hello
部分则是路由路径。
要有多个页面,我们使用 m.route
:
m.route(root, "/splash", {
"/splash": Splash,
"/hello": Hello,
})
m.route
具有和 m.mount
相同的自动重绘功能。但 m.route
还具有 URL 感知功能,它能自动感知到带 !#
的 URL。
m.route
函数的第二个参数是默认路由,如果 URL 中的 hashbang 指向的路由未定义,那么将自动重定向到默认路由。
XHR 是与服务器通信的方式。
我们修改上面的点击计数器的例子,使它能把数据保存到服务器。我们需要调用 m.request
函数:
var count = 0
var increment = function() {
m.request({
method: "PUT",
url: "//rem-rest-api.herokuapp.com/api/tutorial/1",
data: {count: count + 1},
withCredentials: true,
})
.then(function(data) {
count = parseInt(data.count)
})
}
现在调用 increment
方法会把 count
的值发送到 /api/tutorial/1
接口,接口会返回更新后的 count
值。注意,count
变量只有在请求完成后才会更新。
我们把之前的组件中的事件处理替换成调用 increment
函数:
var Hello = {
view: function() {
return m("main", [
m("h1", {class: "title"}, "My first app"),
m("button", {onclick: increment}, count + " clicks"),
])
}
}
现在单击按钮就能把 count
值保存到服务器了。
我们已经介绍了如何创建和更新 HTML,如何为单页面应用创建组件和路由,以及如何通过 XHR 与服务器交互。
现在你已经熟悉了 Mithril API 的基础指示,继续阅读这个简单应用的教程,该教程会指导你构建一个真正的应用。