mithril.js是什么
Mithril is a modern client-side Javascript framework for building Single Page Applications. It's small (< 8kb gzip), fast and provides routing and XHR utilities out of the box.
Mithril 是一个客户端 javascript MVC 框架,即它是一个工具,使应用程序代码分为数据层(Model), UI 层(View),黏合层(Controller)。
mithril.js特点
- 轻量级。总共1200行代码,gzip 之后只有几kb,无依赖;api非常少
-
快速。虚拟dom和编译模版;智能redrawing
上图为官方给出的对比图,但是他为什么会这么小呢?其实是因为它做了比较少的事情。事实上mithril.js仅仅提供了以下几个功能
- 基于 HyperScript 构建 Virtual DOM
- DOM diff
- 双向绑定
- AJAX
- 路由
- 兼容 JSX
mithril.js和vue2的对比
相同:
- 它们都使用虚拟DOM和生命周期方法
- 两者都通过组件组织视图
不同:
- 模版
// vue 的模版
.temp-demo-wrap
p.temp-demo-title hello word
// mithril模版
m('div', {class: 'temp-demo-wrap'}, [
m('p', {class: 'temp-demo-title'}, 'hello word')
])
- Vue提供双向数据绑定和状态管理,而mithril是没有的这个部分的
简单的使用和demo展示
- 基本的使用
- 安装
npm install mithril --save
- 构建你的第一个app
// index.js
var m = require("mithril")
m.render(document.body, "hello world")
- 用mithril.js实现一个简单的点击请求成功后累加的demo
var root = document.body
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)
})
}
var Hello = {
view: function() {
return m("main", [
m("h1", {
class: "title"
}, "My first app"),
m("button", {
onclick: increment
}, count + " clicks"),
])
}
}
m.mount(root, Hello)
mithril.js 关键概念
- 虚拟DOM
- components(所有带有view的都是一个mithril的组件,可以
m()
来调用)
// comp.js
m.m_factory({
viewModel: function () {
// ...
},
controller: function () {
// ....
},
view: function (ctrl, param) {
return m('div.m-demo-components', [
m('h3', {
onclick: param.show.bind(param.ctrl),
style: {
'background-color': '#fff'
}
})
])
}
})
var comp = require(./componemts/comp.js)
m.m_factory({
viewModel: {
list: [],
show: function () {
console.log('show')
},
getList: function () {
m.request({
methods: 'get',
url: '',
data: {}
}).then((data) => {
this.list = data.list || []
})
}
},
controller: function () {
var vm = this.viewModel
vm.getList()
},
view: function (ctrl) {
var dataList = ctrl.list
return m('div', [
m('p', 'test'),
m(comp, {
ctrl: ctrl,
show: ctrl.show
})
])
}
})
- 生命周期(oninit, oncreate, onbeforeupdate, onupdate, onbeforeremove, onremove)
- key:允许在NodeList内重新排序DOM元素的机制,并且随着数据项在列表内移动,将列表中的特定数据项映射到从其派生的各个DOM元素。参考:https://mithril.js.org/keys.html
- 自动重新绘制系统(调用m.mount或m.route时,自动重新绘制系统变为启用状态;但如果您的应用程序仅通过m.render调用进行引导,则它将保持禁用状态)
使用后的一些总结
- 推荐使用第一种写法,虽然它是非强制的(下面两种写法结果是一样的)
var MyComponent = {
view: function() {
return m("main", [
m("h1", "Hello world"),
])
}
}
var MyComponent = {
view: function() {
return (
Hello world
)
}
}
- 没有任何关于动画的API,如果要做动画只能通过钩子自己去实现。例如onbeforeremove这个钩子可以在元素删除之前
- 路由是hash的模式
- m.fragment 创建一个不存在的临时节点(类比document.createDocumentFragment())
m("ul", [
m("li", "child 1"),
m("li", "child 2"),
groupVisible ? m.fragment({oninit: log}, [
// a fragment containing two elements
m("li", "child 3"),
m("li", "child 4"),
]) : null
])
- 仅提供基本的一些方法并不是一个强大的很全面的框架。解决基本的温饱问题,但是没有“华丽的服饰”提供
为什么可以考虑选择它
Mithril 本体目前还非常活跃,现在的它能够解决基本的问题,例如数据控制dom更新,路由,XHR;但周围生态极其贫乏,与 Vue、React 相比处于劣势。如果需要构建重量级 SPA 可能会差一点。但由于本体非常小,学习成本低,可以接入到任何网页实现部分组件化,所以还是非常值得推荐的。而且也有了生产环境使用案例,像 vimeo,nike,Flarum 都在产品中使用了。