--> -->
这里面是纯原生,没有使用webpack之类的打包,所以引用了很多组件js,当然你也可以写到一个里面,但是那实在不好看也不好拓展。
使用了less,为了偷懒,你让我在工程里面使用原生CSS,臣妾真的做不到了。
less
less的内容就不做过多展示,这个有兴趣在下方去源码里面看吧,这里略过了。
js
大头来了,我这里会直接贴出代码,然后在路由那里说一下,为什么我不多说呢,因为MithrilJS真的太简单了(我会告诉你我懒得说么)。。。
header.js
const Header = (function() {
return {
view(v) {
const titles = ['首页', '分享', '设计', '绘画', '摄影']
const hrefs = ['#!/', '#!/share']
const selectedIndex = v.attrs.selectedIndex
return m("header", [
m("h1", "KOOJEE"),
m('section.titles',
titles.map((title, index) => m('a', {class: 'title' + (selectedIndex === index ? ' selected' : ''), href: hrefs[index] || '#'}, titles[index])
)
),
])
}
}
})()
这里使用了自运行函数,为了是避免变量名污染。
组件就是个对象,组件DOM结构实在view这个属性值下的一个函数返回,函数可携带vnode对象,用来传参等等,获取参数使用v.attrs。
其他就是常规内容,渲染了一个header标签,里面包了一个h1标签,包了一个section.titles标签,section.titles里面根据titles数组生成了5个a.title标签。
这就是header了。
footer.js
const Footer = (function() {
return {
view() {
return m(
'footer'
)
}
}
})()
目前没东西,所以渲染了一个空的footer标签用来占位。
homepage.js
const Homepage = (function() {
const h2 = '最终选择了生活……'
const h3 = '宁愿向着远方哭泣,不愿望着当下诧异。'
let contentImgs = ['Bitmap1.png', 'Bitmap2.png', 'Bitmap3.png', 'Bitmap4.png']
let arts = [
{
img: 'Bitmap5.png',
main: '经历',
desc: '我在东方等你,不济那远去的夕阳。',
},
{
img: 'Bitmap6.png',
main: '兴趣',
desc: '给个游戏,能躺半年。',
},
{
img: 'Bitmap7.png',
main: '性格',
desc: '热辣似火,妖娆弄人?不不不,就是呆萌。',
},
{
img: 'Bitmap8.png',
main: '态度',
desc: '你到底准备用什么态度和姑奶奶说话?',
},
]
const Content = {
onbeforeremove(v) {
v.dom.classList.add("exit")
return new Promise(function(resolve) {
setTimeout(resolve, 500)
})
},
view() {
return m('main#homepage.fancy',
m('section.content-center', [
m('h2', h2),
m('h3', h3),
contentImgs.map((contentImg, index) => m('img', {class: 'img' + index, src: assetsPath + contentImg, alt: 'content-img'}))
])
)
}
}
return {
view(v) {
return [
m(Header, {selectedIndex: 0}),
m(Content),
m(Footer),
]
}
}
})()
因为将来要使用数据驱动,所以把数据提出去,方便后续服务器请求数据操作。
这里使用了m函数的组件模式,如上例子中的:m(Header, {selectedIndex: 0}),就是homepage组件里面包含了一个Header组件,并且给Header组件传参了,这个参数的使用在上面Header组件那里可以看到。
注意这里有个内部的Content组件,这个是用来做动画的,比如你页面内路由切换时,为了看起来更舒服,可以做个过渡动画,Homepage组件自带fancy类的CSS,然后Homepage的Content组件在声明周期onbeforeremove即将要消失的时候添加了一个exit类的CSS,具体两个CSS如下:
.fancy {animation:fade-in 0.5s;}
@keyframes fade-in {
from {opacity:0;}
to {opacity:1;}
}
.exit {animation:fade-out 0.5s;}
@keyframes fade-out {
from {opacity:1;}
to {opacity:0;}
}
了解CSS的同学就知道是什么动画了,对,就是淡入与淡出,分别0.5s。
说到这里,刚好顺带过一下MithrilJS的声明周期,如下:
用法与view一样,放在对象的属性上,对应值是函数,都可以获取vnode。
- oninit
- 初始化时候,方便放一些准备用的数据,或者用来网络请求。此时可以拿到vnode,但是不一定拿得到真实DOM,所以这里不推荐进行相关的DOM操作,比如:vnode.dom。
- oncreate
- 创建成功,此时可以拿到真实DOM了。
- onupdate
- DOM渲染刷新后。业务有刷新变动数据时候使用。
- onbeforeremove
- DOM销毁前。常用,比如我们的离开动画。
- onremove
- DOM销毁后。一样不建议进行真实DOM操作,用来销毁垃圾数据可以使用。
- onbeforeupdate
- DOM渲染刷新前。业务有刷新变动数据时候使用。
share.js
const Share = (function() {
let bannerSrc = 'https://wbroom-blog.oss-cn-hangzhou.aliyuncs.com/public/assets/share-bannre.png'
const Content = {
onbeforeremove(v) {
v.dom.classList.add("exit")
return new Promise(function(resolve) {
setTimeout(resolve, 500)
})
},
view() {
return m('main#share.fancy', [
m(`img.share-banner[class="lazy" src="//p2.ttnews.xyz/loading.gif" data-original=${bannerSrc}]`),
m('section.arts',
[1,1,1,1,1,1].map((item, index) => m('figure.art', [
m(`img.head[alt=${index}]`, {src: 'https://wbroom-blog.oss-cn-hangzhou.aliyuncs.com/public/assets/Bitmap1.png'}),
m('figcaption.main', '别看,看也没博文。'),
m('span.time', '耶稣生日的那天'),
m('section.ctrl', [
m('span', '点赞(1000)'),
m('span', '评论(1000)'),
m('span', '浏览(100000)')
])
]))
),
m('section.pagination', '页码(待处理)'),
])
}
}
return {
view(v) {
return[
m(Header, {selectedIndex: 1}),
m(Content),
m(Footer),
]
}
}
})()
与homepage大同小异,只是堆页面,放置一些图片,页码也还没做~
注意,一样要设置进场动画与离场动画。
app.js
const rootPath = 'https://wbroom-blog.oss-cn-hangzhou.aliyuncs.com/'
const publicPath = rootPath + "public/"
const assetsPath = publicPath + "assets/"
m.route(document.body, '/', {
"/": Homepage,
'/share': Share,
})
这个就是常说的入口js了,由于存在JS对象的依赖关系,所以上面的组件不得不先加载,然后最后加载入口js。
第一:做一些全局的数据,比如本项目里面需要用到的图片资源basic路径等。
第二:路由的简单配置。
注意,MithrilJS没有类似Vue的router-view这种组件,它还是建议把组件配到大组件里面,这个缺点就是如果业务的路由组件非常深入,就相对麻烦,但是优点还是简单!
这里配置根路径地址就是Homepage组件,当路由切换到share时候,就是Share组件显示了。
同样的,MithrilJS的路由标记像这样:#!/share,默认是使用#!,当然,你可以通过类似m.route.prefix("#")来修改路由标记,但是个人觉得意义不大。起码别人逛你网站的时候,懂行的一眼就看出来你用的是MithrilJS写的页面,恩,厉害!
到最后,index.html解析所有的内容后,就渲染出文章开头的页面了,点击切换时候还有淡入淡出的效果(上面的链接看不到,因为Vue版本我还没加路……)。
OK,简单,快速,小巧的一个牛逼纯JS框架MithrilJS,带你们走了一遍简单的。
MithrilJS当然也是支持ES6,以及JSX的,本人不是很喜欢JSX的写法,所以采用了原生的,而要用以上两个,都需要去配置下webpack,这里不做过多介绍了。
如果想看源码,请到下面的GitHub源码里面,找到mi分支即可,默认master分支是Vue版本哦。
项目源码:Github:https://github.com/ZweiZhao/WBRoom
喜欢我的文章,请关注一波啊,定期更新技术文章,满满的都是干货!
閱讀更多 慕課網 的文章