大握快排精准度和adc射程排名2017?

&p&要分「长期收益」和「短期收益」来回答这个题目。&/p&&blockquote&学前端编程,看哪些书籍好?&/blockquote&&h2&长期收益&/h2&&p&如果你关注的是长期收益,饥人谷推荐以下入门级的书籍:&/p&&p&1 《Just For Fun》中文名《只是为了好玩》&/p&&p&这本书让你知道最开始的牛逼程序员是怎样的,这是 Linux 作者的自传,他会告诉你他花了两个月重复看一本书,他会告诉你他是多么喜欢编程。就像武侠小说里学武功需要背祖师爷传下来的口诀一样,学编程也需要了解最开始的程序员是怎么写代码的。&/p&&p&记住你是在学「编程」,不是在学「前端」,前端只是编程的一个很小的分支。&/p&&p&学医的同学要先学基础医学,再去学某一科。&/p&&p&学编程也是一样的,先学编程基础,再去学前端分支。&/p&&p&2 《Code: The Hidden Language of Computer Hardware and Software》中文名《编码:隐匿在计算机软硬件背后的语言》&/p&&p&这本书告诉你计算机是如何「计算」的。当你在 JS 里面写一句 1+1,计算机是如何得出 2 的,你不想了解一下吗?&/p&&p&3 《&a href=&//link.zhihu.com/?target=https%3A//book.douban.com/subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&算法图解&i class=&icon-external&&&/i&&/a&》&/p&&p&这本书带你入门算法。当你在 JS 里写 array.sort() 的时候,到底发生了什么,你不想了解一下吗?&/p&&p&4 《&a href=&//link.zhihu.com/?target=https%3A//book.douban.com/subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图解HTTP&i class=&icon-external&&&/i&&/a&》&/p&&p&浏览器是如何获取到一份精美的网页的,你不想了解一下吗?&/p&&p&看完这几本入门书,你就可以去搜索一些更深入的书籍,去学习更深奥的编程技巧,当然你看完这几本书之后也可以直接学前端(见下文),因为你对基础知识已经有了一些理解了。&/p&&p&上面推荐的书虽然很好,但是看起来很费时间,如果你没有时间,可以看看下面的推荐。&/p&&p&&br&&/p&&h2&短期收益&/h2&&p&所谓短期收益就是让你快速掌握一些速成的技能,并不了解其原理。&/p&&p&不过你不要以为这很简单,在不理解原理的情况下想掌握一些技能,可能更难。&/p&&p&我们不打算推荐「高程」和「犀牛书」,因为很多人并没有办法在三个月内看完这么厚的书。&/p&&p&我们在这里推荐一些更容易坚持读完的书籍:&/p&&p&1 《&a href=&//link.zhihu.com/?target=http%3A//javascript.ruanyifeng.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript 标准参考教程(alpha)&i class=&icon-external&&&/i&&/a&》&/p&&blockquote&阮一峰的这本 JS 入门书比犀牛书、高程都更适合入门,因为更薄,而且可以手机观看。&br&本书全面介绍 JavaScript 核心语法,从最简单的开始讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。&br&本书适合初学者当作 JavaScript 语言的入门教程,也适合当作日常使用的参考手册。&/blockquote&&p&2 《JavaScript语言精粹》&/p&&p&推荐这本书的主要目的是让你知道 JS 真的很烂,你需要避免使用 JS 的烂语法,只使用 JS 的好语法。&/p&&p&3 《你不知道的 JavaScript》&/p&&p&深入理解 JS 细节,写得很好。&/p&&p&4 《基于MVC的JavaScript Web富应用开发》&/p&&p&这本书能让你入门 MVC 框架,然后再去理解 MVVM、FLUX 就容易很多。&/p&&p&好了,书不需要推荐很多,你在看的过程中多敲敲代码,多做做小项目,才能融汇贯通。&/p&&p&&br&&/p&&p&贪多,嚼不烂。&/p&&p&别怂,就是干!&/p&
要分「长期收益」和「短期收益」来回答这个题目。学前端编程,看哪些书籍好?长期收益如果你关注的是长期收益,饥人谷推荐以下入门级的书籍:1 《Just For Fun》中文名《只是为了好玩》这本书让你知道最开始的牛逼程序员是怎样的,这是 Linux 作者的自传,他…
&p&文字版:&a href=&https://link.zhihu.com/?target=https%3A//jscode.me/t/es-6/109& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&jscode.me/t/es-6/109&/span&&span class=&invisible&&&/span&&/a&&/p&&p&阮一峰的教程:&a href=&https://link.zhihu.com/?target=http%3A//es6.ruanyifeng.com& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&es6.ruanyifeng.com&/span&&span class=&invisible&&&/span&&/a&&/p&&p&&br&&/p&&p&目前没有找到比较全的 ES 6 新特性汇总(中文),于是就自己花了一下午收集了一下,不说 100% 全面,也至少收录了 90% 的新特性。&br&&/p&&figure&&img data-rawheight=&1704& src=&https://pic1.zhimg.com/v2-b7be6584d9abff093cb5b177d675832f_b.jpg& data-rawwidth=&2840& class=&origin_image zh-lightbox-thumb& width=&2840& data-original=&https://pic1.zhimg.com/v2-b7be6584d9abff093cb5b177d675832f_r.jpg&&&/figure&&br&&br&&p&这样学 ES 6 就方便了。图片中蓝色的链接指向中文学习资料。其中有些资料翻译不准确,我就自己帮它纠正翻译了。&/p&&blockquote&&p&文字版目前作为饥人谷学员的福利,过一段时间再分享给大家吧。&/p&&p&等不及的同学可以自行 Google 或查看&a href=&https://link.zhihu.com/?target=http%3A//kangax.github.io/compat-table/es6/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&英文版&/a&。&/p&&p&觉得我不地道的同学可以自己收集、翻译一下,我支持你。&/p&&p&既然我承诺了内部学员是福利,就要让他们感受到嘛 :)&/p&&/blockquote&&br&&p&请关注我们的专栏:&a href=&https://zhuanlan.zhihu.com/study-fe& class=&internal&&前端学习指南&/a&&/p&&br&&p&上一篇:《&a href=&https://zhuanlan.zhihu.com/p/?refer=study-fe& class=&internal&&ES 5 新特性汇总&/a&》&/p&&p&请期待下一篇:《ES 2016 新特性汇总》&/p&
文字版:阮一峰的教程: 目前没有找到比较全的 ES 6 新特性汇总(中文),于是就自己花了一下午收集了一下,不说 100% 全面,也至少收录了 90% 的新特性。 这样学 ES 6 就方便了。图片中蓝色的链接指向中文学习资…
&figure&&img src=&https://pic1.zhimg.com/v2-9bd4f2ecb9_b.jpg& data-rawwidth=&900& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic1.zhimg.com/v2-9bd4f2ecb9_r.jpg&&&/figure&&p&有很多小伙伴在开始学习Python的时候,都特别期待能用Python写一个爬虫脚本,&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&实验楼&/a&上有不少python爬虫的课程,这里总结7个实战项目,如果你想学习Python爬虫的话,可以挑选感兴趣的学习哦;&/p&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/969& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【python 网站信息爬虫】&/a&&/b&&/h2&&p&该项目使用 Python 语言及 scrapy 开发一个网络信息爬虫,爬取实验楼的课程数据,并将爬取的课程信息保存在一个txt文件中。&/p&&p&效果图:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-61bbadd9b9ed424b6cdf7cadd57b0d84_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&934& data-rawheight=&378& class=&origin_image zh-lightbox-thumb& width=&934& data-original=&https://pic4.zhimg.com/v2-61bbadd9b9ed424b6cdf7cadd57b0d84_r.jpg&&&/figure&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/869& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【python 二手房信息爬取与数据呈现】&/a&&/b&&/h2&&p&该项目以链家的二手房网站为目标,使用python爬取链家官网在售的二手房信息,并且使用matplotlib 绘图包对爬取的信息进行分析,绘制简单的图表。&/p&&p&部分效果图:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-fd77b9a4bffb7e3a79aaae0ec6b5a3cc_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1088& data-rawheight=&348& class=&origin_image zh-lightbox-thumb& width=&1088& data-original=&https://pic2.zhimg.com/v2-fd77b9a4bffb7e3a79aaae0ec6b5a3cc_r.jpg&&&/figure&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/813& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【给Python3爬虫做一个界面.妹子图网实战】&/a&&/b&&/h2&&p&该项目利用PyQt给妹子图网的爬虫做一个交互界面,从而对PyQt做界面有初步了解,同时也学习写爬虫;&/p&&p&效果图:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-588799bdab84ef7fe30f13_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1240& data-rawheight=&864& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic1.zhimg.com/v2-588799bdab84ef7fe30f13_r.jpg&&&/figure&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/763& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【Python网络爬虫实战--Scrapy框架学习】&/a&&/b&&/h2&&p&从一个简单的Scrapy项目入手,剖析爬虫的结构和Scrapy的运行规则,最后通过两个两个实战项目——「爬取实验楼课程信息」和「爬取电影网站信息」,带领大家从零基础入门,完全掌握使用Scrapy框架编写网络爬虫的技能。&/p&&p&课程列表:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-4eeacdcaf31fac30e5a8cb2_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&479& data-rawheight=&450& class=&origin_image zh-lightbox-thumb& width=&479& data-original=&https://pic1.zhimg.com/v2-4eeacdcaf31fac30e5a8cb2_r.jpg&&&/figure&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/595& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【Python3 实现淘女郎照片爬虫】&/a&&/b&&/h2&&p&该项目使用 Python 实现一个淘宝女郎图片收集爬虫。&/p&&p&爬取后的目录结构:&/p&&p&每个文件夹里都有一系列图片;&/p&&figure&&img src=&https://pic1.zhimg.com/v2-7da9cad8b57_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1159& data-rawheight=&520& class=&origin_image zh-lightbox-thumb& width=&1159& data-original=&https://pic1.zhimg.com/v2-7da9cad8b57_r.jpg&&&/figure&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/599& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【高德API+Python解决租房问题】&/a&&/b&&/h2&&p&该项目使用Python脚本爬取某租房网站的房源信息,利用高德的 js API 在地图上标出房源地点,划出距离工作地点1小时内可到达的范围。&/p&&p&最终效果图:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-2ee02ddb8f921c98a05b3bd2aeca1229_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1011& data-rawheight=&729& class=&origin_image zh-lightbox-thumb& width=&1011& data-original=&https://pic3.zhimg.com/v2-2ee02ddb8f921c98a05b3bd2aeca1229_r.jpg&&&/figure&&h2&&b&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/581& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【基于 Flask 及爬虫实现微信娱乐机器人】&/a&&/b&&/h2&&p&该项目基于 Flask Web 框架开发的娱乐级别的微信公众号后台,其中会爬取糗百网站的笑话,自动回复给用户;&/p&&p&效果图:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-458a196a3f2e8aa009d6900_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1080& data-rawheight=&1920& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic1.zhimg.com/v2-458a196a3f2e8aa009d6900_r.jpg&&&/figure&&h2&&b&最后:&/b&&/h2&&p&以上就是7个有关python爬虫的实战项目,你可以挑选感兴趣的进行学习哦;&/p&&p&其他:&/p&&ul&&li&更多实战项目,&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/courses/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&点击这里&/a&进行查看~&/li&&li&&a href=&https://link.zhihu.com/?target=https%3A//www.shiyanlou.com/paths/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&12条技术学习路径&/a&,带你零基础入门编程~&/li&&/ul&
有很多小伙伴在开始学习Python的时候,都特别期待能用Python写一个爬虫脚本,上有不少python爬虫的课程,这里总结7个实战项目,如果你想学习Python爬虫的话,可以挑选感兴趣的学习哦;该项目使用 Python 语言及 scrapy 开发一…
&figure&&img src=&https://pic1.zhimg.com/v2-d634245ddcbd147f_b.jpg& data-rawwidth=&1112& data-rawheight=&855& class=&origin_image zh-lightbox-thumb& width=&1112& data-original=&https://pic1.zhimg.com/v2-d634245ddcbd147f_r.jpg&&&/figure&&p&github 地址: &a href=&http://link.zhihu.com/?target=https%3A//github.com/VV-UI/VV-UI& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&VV-UI/VV-UI&/a&&/p&&p&演示地址: &a href=&http://link.zhihu.com/?target=https%3A//vv-ui.github.io/VV-UI/%23/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&vv-ui&/a&&/p&&p&文档地址:&a href=&http://link.zhihu.com/?target=https%3A//vv-ui.github.io/VV-UI/%23/skeleton& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&skeleton&/a&&/p&&h2&关于骨架屏介绍&/h2&&p&骨架屏的作用主要是在网络请求较慢时,提供基础占位,当数据加载完成,恢复数据展示。这样给用户一种很自然的过渡,不会造成页面长时间白屏或者闪烁等情况。 常见的骨架屏实现方案有&code&ssr&/code&服务端渲染和&code&prerender&/code&两种解决方案。这里主要通过代码为大家展示如何一步步做出这样一个骨架屏:&/p&&figure&&img src=&http://pic1.zhimg.com/v2-ad388e47e4fa436d3d6834_b.jpg& data-size=&small& data-rawwidth=&638& data-rawheight=&1124& class=&origin_image zh-lightbox-thumb& width=&638& data-original=&http://pic1.zhimg.com/v2-ad388e47e4fa436d3d6834_r.jpg&&&figcaption&饿了么骨架屏&/figcaption&&/figure&&h2&prerender 渲染骨架屏&/h2&&p&本组件库骨架屏的实现也是基于预渲染去实现的,有关于预渲染更详细的介绍请参考这篇文章:&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&处理 Vue 单页面 Meta SEO的另一种思路&/a& 下面我们主要介绍其实现步骤,首先我们也是需要配置webpack-plugin,不过已经有实现好的&a href=&http://link.zhihu.com/?target=https%3A//github.com/chrisvfritz/prerender-spa-plugin& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&prerender-spa-plugin&/a&可用&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kd&&var&/span& &span class=&nx&&path&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'path'&/span&&span class=&p&&)&/span&
&span class=&kd&&var&/span& &span class=&nx&&PrerenderSpaPlugin&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'prerender-spa-plugin'&/span&&span class=&p&&)&/span&
&span class=&nx&&module&/span&&span class=&p&&.&/span&&span class=&nx&&exports&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&c1&&// ...&/span&
&span class=&nx&&plugins&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&
&span class=&k&&new&/span& &span class=&nx&&PrerenderSpaPlugin&/span&&span class=&p&&(&/span&
&span class=&c1&&// Absolute path to compiled SPA&/span&
&span class=&nx&&path&/span&&span class=&p&&.&/span&&span class=&nx&&join&/span&&span class=&p&&(&/span&&span class=&nx&&__dirname&/span&&span class=&p&&,&/span& &span class=&s1&&'../dist'&/span&&span class=&p&&),&/span&
&span class=&c1&&// List of routes to prerender&/span&
&span class=&p&&[&/span&&span class=&s1&&'/'&/span&&span class=&p&&]&/span&
&span class=&p&&)&/span&
&span class=&p&&]&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&然后写好我们的骨架屏文件&code&main.skeleton.vue&/code& &/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span& &span class=&o&&&&/span&&span class=&nx&&template&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span& &span class=&kr&&class&/span&&span class=&o&&=&/span&&span class=&s2&&&main-skeleton&&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&w&/span&&span class=&o&&-&/span&&span class=&nx&&skeleton&/span& &span class=&nx&&height&/span&&span class=&o&&=&/span&&span class=&s2&&&80px&&/span&&span class=&o&&&&&/span&&span class=&err&&/w-skeleton&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span& &span class=&kr&&class&/span&&span class=&o&&=&/span&&span class=&s2&&&skeleton-container&&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span& &span class=&kr&&class&/span&&span class=&o&&=&/span&&span class=&s2&&&skeleton&&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&w&/span&&span class=&o&&-&/span&&span class=&nx&&skeleton&/span& &span class=&nx&&height&/span&&span class=&o&&=&/span&&span class=&s2&&&300px&&/span&&span class=&o&&&&&/span&&span class=&err&&/w-skeleton&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&nx&&w&/span&&span class=&o&&-&/span&&span class=&nx&&skeleton&/span& &span class=&nx&&height&/span&&span class=&o&&=&/span&&span class=&s2&&&45px&&/span&&span class=&o&&&&&/span&&span class=&err&&/w-skeleton&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span& &span class=&kr&&class&/span&&span class=&o&&=&/span&&span class=&s2&&&skeleton-bottom&&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&w&/span&&span class=&o&&-&/span&&span class=&nx&&skeleton&/span& &span class=&nx&&height&/span&&span class=&o&&=&/span&&span class=&s2&&&45px&&/span&&span class=&o&&&&&/span&&span class=&err&&/w-skeleton&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&err&&/template&&/span&
&/code&&/pre&&/div&&p&当初次进入页面的时候我们需要显示骨架屏,数据加载完,我们需要移除骨架屏:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span& &span class=&p&&&&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&id&/span&&span class=&o&&=&/span&&span class=&s&&&app&&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&mainSkeleton&/span& &span class=&na&&v-if&/span&&span class=&o&&=&/span&&span class=&s&&&!init&&/span&&span class=&p&&&&/&/span&&span class=&nt&&mainSkeleton&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&v-else&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&body&&/span&&span class=&p&&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
import mainSkeleton from './main.skeleton.vue'
export default {
name: 'app',
init: false
mounted () {
这里模拟数据请求
setTimeout(() =& {
this.init = true
components: {
mainSkeleton
&/code&&/pre&&/div&&h2&ssr 渲染骨架屏&/h2&&p&下面我用我灵魂画师的笔法,画出了大致的过程: &/p&&figure&&img src=&http://pic4.zhimg.com/v2-d634245ddcbd147f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1112& data-rawheight=&855& class=&origin_image zh-lightbox-thumb& width=&1112& data-original=&http://pic4.zhimg.com/v2-d634245ddcbd147f_r.jpg&&&/figure&&p&&br&&/p&&p&首先创建我们的&code&skeleton.entry.js&/code&&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&import&/span& &span class=&nx&&Vue&/span& &span class=&nx&&from&/span& &span class=&s1&&'vue'&/span&&span class=&p&&;&/span&
&span class=&kr&&import&/span& &span class=&nx&&Skeleton&/span& &span class=&nx&&from&/span& &span class=&s1&&'./skeleton.vue'&/span&&span class=&p&&;&/span&
&span class=&kr&&export&/span& &span class=&k&&default&/span& &span class=&k&&new&/span& &span class=&nx&&Vue&/span&&span class=&p&&({&/span&
&span class=&nx&&components&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&Skeleton&/span&
&span class=&p&&},&/span&
&span class=&nx&&template&/span&&span class=&o&&:&/span& &span class=&s1&&'&skeleton /&'&/span&
&span class=&p&&});&/span&
&/code&&/pre&&/div&&p&当然这里的&code&skeleton.vue&/code&使我们事先写好的骨架屏组件,看起来可能是这样:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span& &span class=&p&&&&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&skeleton-wrapper&&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&header&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&skeleton-header&&/span&&span class=&p&&&&/&/span&&span class=&nt&&header&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&skeleton-block&&/span&&span class=&p&&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&然后我们需要的是能把&code&skeleton.entry.js&/code&编译成服务端渲染可用的&code&bundle&/code&文件,所以我们需要有个编译骨架屏的&code&webpack.ssr.conf.js&/code&文件:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&const&/span& &span class=&nx&&path&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'path'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&merge&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'webpack-merge'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&baseWebpackConfig&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'./webpack.base.conf'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&nodeExternals&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'webpack-node-externals'&/span&&span class=&p&&);&/span&
&span class=&kd&&function&/span& &span class=&nx&&resolve&/span&&span class=&p&&(&/span&&span class=&nx&&dir&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&nx&&path&/span&&span class=&p&&.&/span&&span class=&nx&&join&/span&&span class=&p&&(&/span&&span class=&nx&&__dirname&/span&&span class=&p&&,&/span& &span class=&nx&&dir&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&nx&&module&/span&&span class=&p&&.&/span&&span class=&nx&&exports&/span& &span class=&o&&=&/span& &span class=&nx&&merge&/span&&span class=&p&&(&/span&&span class=&nx&&baseWebpackConfig&/span&&span class=&p&&,&/span& &span class=&p&&{&/span&
&span class=&nx&&target&/span&&span class=&o&&:&/span& &span class=&s1&&'node'&/span&&span class=&p&&,&/span&
&span class=&nx&&devtool&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&nx&&entry&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&app&/span&&span class=&o&&:&/span& &span class=&nx&&resolve&/span&&span class=&p&&(&/span&&span class=&s1&&'./src/skeleton.entry.js'&/span&&span class=&p&&)&/span&
&span class=&p&&},&/span&
&span class=&nx&&output&/span&&span class=&o&&:&/span& &span class=&nb&&Object&/span&&span class=&p&&.&/span&&span class=&nx&&assign&/span&&span class=&p&&({},&/span& &span class=&nx&&baseWebpackConfig&/span&&span class=&p&&.&/span&&span class=&nx&&output&/span&&span class=&p&&,&/span& &span class=&p&&{&/span&
&span class=&nx&&libraryTarget&/span&&span class=&o&&:&/span& &span class=&s1&&'commonjs2'&/span&
&span class=&p&&}),&/span&
&span class=&nx&&externals&/span&&span class=&o&&:&/span& &span class=&nx&&nodeExternals&/span&&span class=&p&&({&/span&
&span class=&nx&&whitelist&/span&&span class=&o&&:&/span& &span class=&sr&&/\.css$/&/span&
&span class=&p&&}),&/span&
&span class=&nx&&plugins&/span&&span class=&o&&:&/span& &span class=&p&&[]&/span&
&span class=&p&&});&/span&
&/code&&/pre&&/div&&p&接下来最终的步骤,就是编写我们的webpackPlugin,我们期望我们的webpackPlugin可以帮我们把入口文件编译成bundle,然后再通过&code&vue-server-renderer&/code&来render bundle,最终产出响应的html片段和css片段,这里贴出核心代码:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span& &span class=&c1&&// webpack start to work&/span&
&span class=&kd&&var&/span& &span class=&nx&&serverCompiler&/span& &span class=&o&&=&/span& &span class=&nx&&webpack&/span&&span class=&p&&(&/span&&span class=&nx&&serverWebpackConfig&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&mfs&/span& &span class=&o&&=&/span& &span class=&k&&new&/span& &span class=&nx&&MFS&/span&&span class=&p&&();&/span&
&span class=&c1&&// output to mfs&/span&
&span class=&nx&&serverCompiler&/span&&span class=&p&&.&/span&&span class=&nx&&outputFileSystem&/span& &span class=&o&&=&/span& &span class=&nx&&mfs&/span&&span class=&p&&;&/span&
&span class=&nx&&serverCompiler&/span&&span class=&p&&.&/span&&span class=&nx&&watch&/span&&span class=&p&&({},&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&,&/span& &span class=&nx&&stats&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&reject&/span&&span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&);&/span&
&span class=&k&&return&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&nx&&stats&/span& &span class=&o&&=&/span& &span class=&nx&&stats&/span&&span class=&p&&.&/span&&span class=&nx&&toJson&/span&&span class=&p&&();&/span&
&span class=&nx&&stats&/span&&span class=&p&&.&/span&&span class=&nx&&errors&/span&&span class=&p&&.&/span&&span class=&nx&&forEach&/span&&span class=&p&&(&/span&&span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&error&/span&&span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&);&/span&
&span class=&p&&});&/span&
&span class=&nx&&stats&/span&&span class=&p&&.&/span&&span class=&nx&&warnings&/span&&span class=&p&&.&/span&&span class=&nx&&forEach&/span&&span class=&p&&(&/span&&span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&warn&/span&&span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&);&/span&
&span class=&p&&});&/span&
&span class=&kd&&var&/span& &span class=&nx&&bundle&/span& &span class=&o&&=&/span& &span class=&nx&&mfs&/span&&span class=&p&&.&/span&&span class=&nx&&readFileSync&/span&&span class=&p&&(&/span&&span class=&nx&&outputPath&/span&&span class=&p&&,&/span& &span class=&s1&&'utf-8'&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&skeletonCss&/span& &span class=&o&&=&/span& &span class=&nx&&mfs&/span&&span class=&p&&.&/span&&span class=&nx&&readFileSync&/span&&span class=&p&&(&/span&&span class=&nx&&outputCssPath&/span&&span class=&p&&,&/span& &span class=&s1&&'utf-8'&/span&&span class=&p&&);&/span&
&span class=&c1&&// create renderer with bundle&/span&
&span class=&kd&&var&/span& &span class=&nx&&renderer&/span& &span class=&o&&=&/span& &span class=&nx&&createBundleRenderer&/span&&span class=&p&&(&/span&&span class=&nx&&bundle&/span&&span class=&p&&);&/span&
&span class=&c1&&// use vue ssr to render skeleton&/span&
&span class=&nx&&renderer&/span&&span class=&p&&.&/span&&span class=&nx&&renderToString&/span&&span class=&p&&({},&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&,&/span& &span class=&nx&&skeletonHtml&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&reject&/span&&span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&nx&&resolve&/span&&span class=&p&&({&/span&&span class=&nx&&skeletonHtml&/span&&span class=&o&&:&/span& &span class=&nx&&skeletonHtml&/span&&span class=&p&&,&/span& &span class=&nx&&skeletonCss&/span&&span class=&o&&:&/span& &span class=&nx&&skeletonCss&/span&&span class=&p&&});&/span&
&span class=&p&&}&/span&
&span class=&p&&});&/span&
&span class=&p&&});&/span&
&/code&&/pre&&/div&&p&最后一步,我们对产出的html片段, css片段进行组装,产出最终的html,所以我们需要监听webpack 的编译挂载之前的事件:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&compiler&/span&&span class=&p&&.&/span&&span class=&nx&&plugin&/span&&span class=&p&&(&/span&&span class=&s1&&'compilation'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&compilation&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&// add listener for html-webpack-plugin&/span&
&span class=&nx&&compilation&/span&&span class=&p&&.&/span&&span class=&nx&&plugin&/span&&span class=&p&&(&/span&&span class=&s1&&'html-webpack-plugin-before-html-processing'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&htmlPluginData&/span&&span class=&p&&,&/span& &span class=&nx&&callback&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&ssr&/span&&span class=&p&&(&/span&&span class=&nx&&webpackConfig&/span&&span class=&p&&).&/span&&span class=&nx&&then&/span&&span class=&p&&(&/span&&span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&ref&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&skeletonHtml&/span& &span class=&o&&=&/span& &span class=&nx&&ref&/span&&span class=&p&&.&/span&&span class=&nx&&skeletonHtml&/span&&span class=&p&&;&/span&
&span class=&kd&&var&/span& &span class=&nx&&skeletonCss&/span& &span class=&o&&=&/span& &span class=&nx&&ref&/span&&span class=&p&&.&/span&&span class=&nx&&skeletonCss&/span&&span class=&p&&;&/span&
&span class=&c1&&// insert inlined styles into html&/span&
&span class=&kd&&var&/span& &span class=&nx&&headTagEndPos&/span& &span class=&o&&=&/span& &span class=&nx&&htmlPluginData&/span&&span class=&p&&.&/span&&span class=&nx&&html&/span&&span class=&p&&.&/span&&span class=&nx&&lastIndexOf&/span&&span class=&p&&(&/span&&span class=&s1&&'&/head&'&/span&&span class=&p&&);&/span&
&span class=&nx&&htmlPluginData&/span&&span class=&p&&.&/span&&span class=&nx&&html&/span& &span class=&o&&=&/span& &span class=&nx&&insertAt&/span&&span class=&p&&(&/span&&span class=&nx&&htmlPluginData&/span&&span class=&p&&.&/span&&span class=&nx&&html&/span&&span class=&p&&,&/span& &span class=&p&&(&/span&&span class=&s2&&&&style&&&/span& &span class=&o&&+&/span& &span class=&nx&&skeletonCss&/span& &span class=&o&&+&/span& &span class=&s2&&&&/style&&&/span&&span class=&p&&),&/span& &span class=&nx&&headTagEndPos&/span&&span class=&p&&);&/span&
&span class=&c1&&// replace mounted point with ssr result in html&/span&
&span class=&kd&&var&/span& &span class=&nx&&appPos&/span& &span class=&o&&=&/span& &span class=&nx&&htmlPluginData&/span&&span class=&p&&.&/span&&span class=&nx&&html&/span&&span class=&p&&.&/span&&span class=&nx&&lastIndexOf&/span&&span class=&p&&(&/span&&span class=&nx&&insertAfter&/span&&span class=&p&&)&/span& &span class=&o&&+&/span& &span class=&nx&&insertAfter&/span&&span class=&p&&.&/span&&span class=&nx&&length&/span&&span class=&p&&;&/span&
&span class=&nx&&htmlPluginData&/span&&span class=&p&&.&/span&&span class=&nx&&html&/span& &span class=&o&&=&/span& &span class=&nx&&insertAt&/span&&span class=&p&&(&/span&&span class=&nx&&htmlPluginData&/span&&span class=&p&&.&/span&&span class=&nx&&html&/span&&span class=&p&&,&/span& &span class=&nx&&skeletonHtml&/span&&span class=&p&&,&/span& &span class=&nx&&appPos&/span&&span class=&p&&);&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&kc&&null&/span&&span class=&p&&,&/span& &span class=&nx&&htmlPluginData&/span&&span class=&p&&);&/span&
&span class=&p&&});&/span&
&span class=&p&&});&/span&
&span class=&p&&});&/span&
&/code&&/pre&&/div&&h2&关于:&/h2&&p&作者:monkeyWang&/p&&p&&br&&/p&&p&本文参考文章:&a href=&http://link.zhihu.com/?target=https%3A//xiaoiver.github.io/coding//%25E4%25B8%25BAvue%25E9%25A1%25B9%25E7%259B%25AE%25E6%25B7%25BB%25E5%258A%25A0%25E9%25AA%25A8%25E6%259E%25B6%25E5%25B1%258F.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&为vue项目添加骨架屏&/a&&/p&&p&&br&&/p&&p&本文源码详见:&a href=&http://link.zhihu.com/?target=https%3A//github.com/VV-UI/VV-UI& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&VV-UI/VV-UI&/a&&/p&&p&&br&&/p&&p&本人主页:&a href=&http://link.zhihu.com/?target=https%3A//monkeywangs.github.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&monkeyWang&/a&&/p&&p&&br&&/p&&p&微信公众号:会不定期推送前端技术文章,欢迎关注&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//weixin.qq.com/r/YiixqYjE89WMrczK931w& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&weixin.qq.com/r/YiixqYj&/span&&span class=&invisible&&E89WMrczK931w&/span&&span class=&ellipsis&&&/span&&/a& (二维码自动识别)&/p&
github 地址: 演示地址: 文档地址:关于骨架屏介绍骨架屏的作用主要是在网络请求较慢时,提供基础占位,当数据加载完成,恢复数据展示。这样给用户一种很自然的过渡,不会造成页面长时间白屏或者闪烁等情况。 常见的骨架屏实现方…
&p&你想复杂了,留个坑,明天再说。&/p&&p&============华丽的分割线===========&/p&&p&昨天本来下班想写的,但是一个妹子让帮忙解决一个问题,弄了一个多小时...这里补上。&/p&&p&其实这里先分析一下,你这里提了2个疑问:&/p&&p&(1) tabs 逻辑都写在一起,直接通过 show, hide 指令的方式进行实现;&/p&&p&(2)使用路由,主要的问题是返回的时候,route stack 回退的问题。&/p&&p&&b&第一种方案:什么React, Angular, Vue,拿起 “jQuery” 就是干&/b&&/p&&p&这个方案也可以进行,你描述的代码长,代码重复量大(DRY),其实是可以避免一部分的。&/p&&p&这里我会假设很多东西,因为你也没描述太多场景和问题。这里直接用伪代码描述:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&c1&&// 公用部分的数据逻辑&/span&
&span class=&c1&&// 视图的逻辑其实更加内聚更好,对外暴露只有公用的部分&/span&
&span class=&kd&&let&/span& &span class=&nx&&common&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&getData&/span&&span class=&p&&()&/span& &span class=&p&&{&/span& &span class=&p&&},&/span&
&span class=&nx&&paramsDeal&/span&&span class=&p&&()&/span& &span class=&p&&{&/span& &span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 渲染的整个容器&/span&
&span class=&c1&&// 这里不用提取 Tab 容器,因为逻辑比较简单,减少通信带来的开销&/span&
&span class=&kr&&class&/span& &span class=&nx&&TabApp&/span& &span class=&kr&&extends&/span& &span class=&nx&&Component&/span& &span class=&p&&{&/span&
&span class=&nx&&state&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&index&/span&&span class=&o&&:&/span& &span class=&mi&&0&/span& &span class=&c1&&// default&/span&
&span class=&p&&}&/span&
&span class=&nx&&handleChange&/span&&span class=&p&&(&/span&&span class=&nx&&index&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&setState&/span&&span class=&p&&({&/span& &span class=&nx&&index&/span& &span class=&p&&});&/span&
&span class=&p&&}&/span&
&span class=&nx&&render&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kr&&const&/span& &span class=&nx&&tabs&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&nx&&Tab1&/span&&span class=&p&&,&/span& &span class=&nx&&Tab2&/span&&span class=&p&&,&/span& &span class=&nx&&Tab3&/span&&span class=&p&&].&/span&&span class=&nx&&map&/span&&span class=&p&&(&/span&
&span class=&p&&(&/span&&span class=&nx&&Tab&/span&&span class=&p&&,&/span& &span class=&nx&&index&/span&&span class=&p&&)&/span& &span class=&o&&=&&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&Tab&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&err&&`&/span&&span class=&nx&&tab&/span&&span class=&o&&-&/span&&span class=&nx&&$&/span&&span class=&p&&{&/span&&span class=&nx&&Tab&/span&&span class=&p&&.&/span&&span class=&nx&&id&/span&&span class=&p&&}&/span&&span class=&err&&`&/span&&span class=&p&&}&/span&
&span class=&nx&&onChange&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&handleChange&/span&&span class=&p&&(&/span&&span class=&nx&&index&/span&&span class=&p&&)}&/span& &span class=&o&&/&&/span&
&span class=&p&&)&/span&
&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&p&&{&/span&&span class=&nx&&tabs&/span&&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&p&&{&/span&&span class=&o&&&&/span&&span class=&nx&&ViewApp&/span& &span class=&nx&&index&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&state&/span&&span class=&p&&.&/span&&span class=&nx&&index&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 渲染的内容容器&/span&
&span class=&kr&&class&/span& &span class=&nx&&ViewApp&/span& &span class=&kr&&extends&/span& &span class=&nx&&Component&/span& &span class=&p&&{&/span&
&span class=&nx&&render&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kr&&const&/span& &span class=&p&&{&/span&&span class=&nx&&index&/span&&span class=&p&&}&/span& &span class=&o&&=&/span& &span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&props&/span&
&span class=&kr&&const&/span& &span class=&nx&&Views&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&nx&&View1&/span&&span class=&p&&,&/span& &span class=&nx&&View2&/span&&span class=&p&&,&/span& &span class=&nx&&View3&/span&&span class=&p&&]&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&p&&{&/span&&span class=&nx&&Views&/span&&span class=&p&&[&/span&&span class=&nx&&index&/span&&span class=&p&&]}&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 每个 Tab 子组件&/span&
&span class=&kr&&const&/span& &span class=&nx&&Tab1&/span& &span class=&o&&=&/span& &span class=&p&&({&/span& &span class=&nx&&onChange&/span& &span class=&p&&})&/span& &span class=&o&&=&&/span& &span class=&p&&{}&/span&
&span class=&kr&&const&/span& &span class=&nx&&Tab2&/span& &span class=&o&&=&/span& &span class=&p&&({&/span& &span class=&nx&&onChange&/span& &span class=&p&&})&/span& &span class=&o&&=&&/span& &span class=&p&&{}&/span&
&span class=&kr&&const&/span& &span class=&nx&&Tab3&/span& &span class=&o&&=&/span& &span class=&p&&({&/span& &span class=&nx&&onChange&/span& &span class=&p&&})&/span& &span class=&o&&=&&/span& &span class=&p&&{}&/span&
&span class=&c1&&// 每个 View 子组件&/span&
&span class=&kr&&const&/span& &span class=&nx&&View1&/span& &span class=&o&&=&/span& &span class=&nx&&_&/span& &span class=&o&&=&&/span& &span class=&p&&{}&/span&
&span class=&kr&&const&/span& &span class=&nx&&View2&/span& &span class=&o&&=&/span& &span class=&nx&&_&/span& &span class=&o&&=&&/span& &span class=&p&&{}&/span&
&span class=&kr&&const&/span& &span class=&nx&&View3&/span& &span class=&o&&=&/span& &span class=&nx&&_&/span& &span class=&o&&=&&/span& &span class=&p&&{}&/span&
&/code&&/pre&&/div&&p&基本上这个方案就是把整个业务写到一起,但是通过一点组织来解决部分问题,比如单文件文件内容过多,组件基本的公用上的问题。对于请求层,基本上你能在 `TabApp` 这个容器里面做,这样下面子树的纯度还是比较高的。当然,代码不一定是可以运行的,只是一种描述。Vue 的话应该是差不多的,不过组件的模板渲染那里会不一样。这种情况下,你需要自己持久化当前 tab 的选项,下次用户刷新才能恢复之前状态。&/p&&p&&b&第二种方案:路由&/b&&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&kr&&class&/span& &span class=&nx&&TabApp&/span& &span class=&kr&&extends&/span& &span class=&nx&&Component&/span& &span class=&p&&{&/span&
&span class=&nx&&handleLeave&/span&&span class=&p&&()&/span& &span class=&p&&{&/span& &span class=&p&&}&/span&
&span class=&nx&&render&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kr&&const&/span& &span class=&nx&&tabs&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&nx&&Tab1&/span&&span class=&p&&,&/span& &span class=&nx&&Tab2&/span&&span class=&p&&,&/span& &span class=&nx&&Tab3&/span&&span class=&p&&].&/span&&span class=&nx&&map&/span&&span class=&p&&(&/span&
&span class=&p&&(&/span&&span class=&nx&&tab&/span&&span class=&p&&,&/span& &span class=&nx&&index&/span&&span class=&p&&)&/span& &span class=&o&&=&&/span& &span class=&o&&&&/span&&span class=&nx&&TabRoute&/span& &span class=&nx&&name&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&nx&&index&/span&&span class=&p&&}&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&err&&`&/span&&span class=&nx&&tabRoute&/span&&span class=&o&&-&/span&&span class=&nx&&$&/span&&span class=&p&&{&/span&&span class=&nx&&tab&/span&&span class=&p&&.&/span&&span class=&nx&&id&/span&&span class=&p&&}&/span&&span class=&err&&`&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&&span class=&p&&{&/span&&span class=&nx&&tabs&/span&&span class=&p&&}&/span&&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&p&&{&/span&&span class=&cm&&/* 这里嵌入 View 组件以及组件逻辑 */&/span&&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&&span class=&p&&{&/span&&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&props&/span&&span class=&p&&.&/span&&span class=&nx&&children&/span&&span class=&p&&}&/span&&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&其中你需要知道 Leave 的事件钩子,然后点击返回的时候直接切回上一个父级路由,其实你说的一直返回也可以从设计上解决嘛,给个直接回去的按钮,哈哈!这个的好处是你不用自己去维护切换状态。&/p&&p&&b&下面是一些其他 idea&/b&&/p&&p&&b&(1) 组件组合&/b&&/p&&p&这个比起第一种方案是修改外置,这样修改的时候只修改子组件就行了,不用修改容器类,其实在业务稳定的情况下,基本修改都是局部的修改,这种情况就要避免去修改整体,树的修改越低影响越小。容器可以控制一些公用的行为。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&kr&&class&/span& &span class=&nx&&TabApp&/span& &span class=&kr&&extends&/span& &span class=&nx&&Component&/span& &span class=&p&&{&/span&
&span class=&nx&&render&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kr&&const&/span& &span class=&nx&&tabs&/span& &span class=&o&&=&/span& &span class=&nx&&React&/span&&span class=&p&&.&/span&&span class=&nx&&Children&/span&&span class=&p&&.&/span&&span class=&nx&&map&/span&&span class=&p&&((&/span&&span class=&nx&&child&/span&&span class=&p&&,&/span& &span class=&nx&&index&/span&&span class=&p&&)&/span& &span class=&o&&=&&/span& &span class=&nx&&child&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&div&/span&&span class=&o&&&&/span&
&span class=&p&&{&/span&&span class=&nx&&tabs&/span&&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&err&&/div&&/span&
&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&kr&&class&/span& &span class=&nx&&App&/span& &span class=&kr&&extends&/span& &span class=&nx&&Component&/span& &span class=&p&&{&/span&
&span class=&nx&&render&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&Main&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&TabApp&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&Tab1&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&mi&&0&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&o&&&&/span&&span class=&nx&&Tab2&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&mi&&1&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&o&&&&/span&&span class=&nx&&Tab3&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&mi&&2&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&o&&&&/span&&span class=&err&&/TabApp&&/span&
&span class=&o&&&&/span&&span class=&nx&&ViewApp&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&View1&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&mi&&0&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&o&&&&/span&&span class=&nx&&View2&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&mi&&1&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&o&&&&/span&&span class=&nx&&View3&/span& &span class=&nx&&key&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&mi&&2&/span&&span class=&p&&}&/span& &span class=&o&&/&&/span&
&span class=&o&&&&/span&&span class=&err&&/ViewApp&&/span&
&span class=&o&&&&/span&&span class=&err&&/Main&&/span&
&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&b&(2) 动态组件&/b&&/p&&p&这个其实和我的第一种方案有点像,这个就不贴代码了...可以查查就有思路了。&/p&&p&总体来说代码的耦合要看组织,组件的切换的话,其实本质上就是替换,无论什么样的替换方式都会有自己的问题,所以选个自己喜欢的。因为你可能还有 loading、error、default 等逻辑,远比这复杂。&/p&
你想复杂了,留个坑,明天再说。============华丽的分割线===========昨天本来下班想写的,但是一个妹子让帮忙解决一个问题,弄了一个多小时...这里补上。其实这里先分析一下,你这里提了2个疑问:(1) tabs 逻辑都写在一起,直接通过 show, hide 指令的方…
&figure&&img src=&https://pic1.zhimg.com/v2-94bfab3679bc717ed4a1_b.jpg& data-rawwidth=&1200& data-rawheight=&625& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic1.zhimg.com/v2-94bfab3679bc717ed4a1_r.jpg&&&/figure&&h2&&b&前言&/b&&/h2&&p&&b&总括:&/b& 本文通过实例讲解CSS中最大的难点之一,行内元素的布局,主要是挖掘line-height和vertical-align两个属性在布局方面的使用。&/p&&ul&&li&原文博客地址:&a href=&https://link.zhihu.com/?target=http%3A//blog.damonare.cn//%25E6%25B7%25B1%25E5%%25E7%E8%25A7%25A3%25E8%25A1%258C%25E5%E5%E7%25B4%25A0%25E5%25B8%%25B1%2580/%23more& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&深入理解行内元素的布局&/a&&/li&&li&知乎专栏&&简书专题:&a href=&https://zhuanlan.zhihu.com/damonare& class=&internal&&前端进击者(知乎)&/a&&&&a href=&https://link.zhihu.com/?target=http%3A//www.jianshu.com/collection/bbaa63e264f5& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&前端进击者(简书)&/a&&/li&&li&博主博客地址:&a href=&https://link.zhihu.com/?target=http%3A//damonare.cn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Damonare的个人博客&/a&&/li&&/ul&&p&&b&白茶清欢无别事,我在等风,也在等你。&/b& &/p&&h2&&b&正文&/b&&/h2&&p&讲道理line-height和vertical-align 这对基是十分低调的,日常开发中碰到的很多莫名其妙的bug很大一部分都是这俩货搞出来了的,但很少有人知道这对基的罪恶,因为可能花式改写一下CSS代码问题就解决了。实际上搞明白这俩东西才能让我们在布局工作中游刃有余。本文接下来就通过这对基的关系来了解内联元素具体的布局问题~we are刨根问底拦不住~ &/p&&p& 读这篇文章之前请确定您有以下知识基础:&/p&&ul&&li&line-height的数字值是和font-size大小相关的;&/li&&li&vertical-align的百分比值是和line-height值相关的;&/li&&/ul&&h2&&b&引出vertical-align&/b&&/h2&&p&首先来看一个 :&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&test&&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&img&/span& &span class=&na&&src&/span&&span class=&o&&=&/span&&span class=&s&&&https://sfault-avatar.b0.upaiyun.com/344/542/-b2_huge256&&/span& &span class=&na&&alt&/span&&span class=&o&&=&/span&&span class=&s&&&&&/span&&span class=&p&&&&&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&Xx&span class=&p&&&/&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
background:
height: 50
background:
&/code&&/pre&&/div&&p&&a href=&https://link.zhihu.com/?target=https%3A//jsfiddle.net/Damonare/5oLvd0z4/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&下面无实例内容的话戳这里&/a&&/p&&p& 如上代码片段result所示,图片下面有一明显的红色条条, 什么鬼,很诡异不是么,我&code&要的是&/code&img充&code&满整个&/code&div啊!!!好吧,我加了一个额外的inline元素填&code&写内&/code&容Xx,发现原来多出来的那一块正好是文字的下半空白部分。吆喝,这么巧?实际上,如果将这里的Xx内容去掉,只剩下img,那个条条依然存在,表现行为好像父元素div里面除了img元素还有一个空白的元素一样,&code& 姑且&/code&叫它空白节点吧(肉眼中不存在却在影响着布局),这个是比较诡异的一个表现,查标准没找到有相关的说明&code&。但请将&/code&这个空白节点先记住,我们的重点是研究条条是咋出来的。这条条看上去貌似是文本和图片垂直方向上对齐生成的,那么这就引粗来一个问题,inline元素默认的垂直方向的对齐方式是什么&code&样的?也就是vertical&/code&-align的默认值是啥?&/p&&p& OK, I know you kn&code&ow。vertical-al&/code&ign默认值是baseline,OK,那就先来挖一挖vertical-align具体是个什么鬼。&/p&&h2&&b&Vertical-align(1)&/b&&/h2&&p&&code&vertical-align&/code&这个属性我感觉是CSS中最复杂的属性之一了...好多问题概念也让人看不懂...一方面它是作用在inline元素和table-cell元素身上,属性值特别多,另一方面该属性规范里并没有一个定论,导致一些属性不同浏览器的实现也不同,所以兼容性问题很多。对于一些 &a href=&https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/CSS/Replaced_element& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&可替换元素&/a&,比如&code&textarea&/code&, HTML标准没有说明它的基线,这意味着对其使用这个关键字,各浏览器表现可能不一样。我们这里先研究一下它的默认值baseline。&/p&&p&baseline字面意思就是基线,何为基线?首先请记住下面这几个概念:&/p&&ul&&li&基线:小写字母'x'的下边缘所在的那条线;&/li&&li&x-height: 小写字母'x'的高度;&/li&&li&ex: 1ex就是一个小写字母'x'的高度,类似em单位,注意,ex和em都是相对单位;&/li&&/ul&&p&我们看下CSS标准里怎么说的:&a href=&https://link.zhihu.com/?target=https%3A//www.w3.org/TR/CSS2/visudet.html%23propdef-vertical-align& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&相关标准链接&/a&&/p&&blockquote&The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.&/blockquote&&p&中文翻译如下:&/p&&blockquote&'inline-block'元素的基线是标准流中最后一个line box(行盒)的基线, 除非这个line box里面既没有in-flow line boxes(行内框)或者本身’overflow’属性的计算值不是’visible’, 这种情况下基线是该元素margin底边缘。&/blockquote&&p&那么上面现象就很容易解释的通了,我们知道img元素默认的表现形式和inline-block元素一样,它的基线就是margin底边缘,而&code&inline元素本身是有高度的&/code&,两者基线对齐自然就如上面那样表现了。 &/p&&p& 好吧,等会,到这里,我们发现实际又多了俩概&code&念——inline元素的高&/code&度&code&问题和标准里说的line &/code&box(IFC)。&/p&&p&首先我们先来看下inline元素的高度问题,即——line-height属性。&/p&&h2&&b&Line-height&/b&&/h2&&p&CSS中起高度作用的只有height和line-height两个属性吧。&b&如果一个元素没设置height那么其最终的高度一定是由line-height决定的。&/b&之前inline元素的高度我以为是文字内容撑开的,但实际研究了下并不是这样的,看下面的 :&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nc&&.demo1&/span&&span class=&p&&{&/span&
&span class=&nb&&font-size&/span&&span class=&o&&:&/span& &span class=&m&&20px&/span&&span class=&p&&;&/span&
&span class=&nb&&line-height&/span&&span class=&o&&:&/span& &span class=&m&&0&/span&&span class=&p&&;&/span&
&span class=&nb&&border&/span&&span class=&o&&:&/span& &span class=&m&&1px&/span& &span class=&nb&&solid&/span& &span class=&nb&&blue&/span&&span class=&p&&;&/span&
&span class=&nb&&background&/span&&span class=&o&&:&/span& &span class=&nb&&red&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&nc&&.demo2&/span&&span class=&p&&{&/span&
&span class=&nb&&font-size&/span&&span class=&o&&:&/span& &span class=&m&&0&/span&&span class=&p&&;&/span&
&span class=&nb&&line-height&/span&&span class=&o&&:&/span& &span class=&m&&20px&/span&&span class=&p&&;&/span&
&span class=&nb&&border&/span&&span class=&o&&:&/span& &span class=&m&&1px&/span& &span class=&nb&&solid&/span& &span class=&nb&&red&/span&&span class=&p&&;&/span&
&span class=&nb&&background&/span&&span class=&o&&:&/span& &span class=&nb&&yellow&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&HTML代码:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&span&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&demo1&&/span&&span class=&p&&&&/span&测试&span class=&p&&&/&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&span&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&demo2&&/span&&span class=&p&&&&/span&测试&span class=&p&&&/&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&&a href=&https://link.zhihu.com/?target=https%3A//jsfiddle.net/Damonare/54ucnkht& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&下面没内容戳这&/a&或者自行拷贝代码本地测试&/p&&p&如上可证明,inline元素的高度决定者是line-height,并不是文字内容撑开的。?&/p&&p&CSS规范里对&a href=&https://link.zhihu.com/?target=https%3A//www.w3.org/TR/CSS2/visudet.html%23propdef-line-height& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&line-height&/a&的默认值有这么一句话:&/p&&blockquote&We recommend a used value for 'normal' between 1.0 to 1.2.&/blockquote&&p&只是推荐... 是不是说实际上各个浏览器对于line-height的默认值实现不一定是一样的,但都介于1.0-1.2之间。具体各大浏览器的实现值待查证。这里需要记住line-height的默认值是啥就OK。&/p&&h2&&b&IFC&/b&&/h2&&p&在之前的博文&a href=&https://link.zhihu.com/?target=http%3A//blog.damonare.cn//CSS%25E7%259B%%25AD%%25A8%25A1%25E5%259E%258B/%23more& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CSS的盒子模型&/a&里面,有拓展过相关知识,简短的介绍了下BFC和IFC,相较于BFC,IFC要复杂得多,&a href=&https://link.zhihu.com/?target=https%3A//www.w3.org/TR/CSS2/visuren.html%23inline-formatting& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&规范&/a&里IFC的篇幅也要比BFC多得多。&/p&&p&简要总结下BFC,即块级元素可能会触发块级格式上下文(BFC),在块级格式上下文中,块级盒子竖直方向排列,不受上下文外部元素影响,自成一方世界。块容器盒指的是那些包含元素的盒子,&b&块容器盒可能包含其它块级盒,也可能生成一个行内格式上下文(IFC)。&/b& &/p&&p&但块容器盒要么只包含行内盒,要么只包含块级盒。但通常会同时包含两者。在这种情况下,将创建匿名块盒来包含毗邻的行内级盒。&/p&&p&看个 :&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&//demo1
&span class=&p&&&&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
Some inline text
&span class=&p&&&&/span&&span class=&nt&&p&/span&&span class=&p&&&&/span&followed by a paragraph&span class=&p&&&/&/span&&span class=&nt&&p&/span&&span class=&p&&&&/span&
followed by more inline text.
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&p&/span&&span class=&p&&&&/span&
Some inline text
&span class=&p&&&&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&followed by a paragraph&span class=&p&&&/&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&
followed by more inline text.
&span class=&p&&&/&/span&&span class=&nt&&p&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&如上,&b&demo1将创建两个匿名块盒&/b&,一个包含 &code&p&/code&前面的文本 (&code&Some inline text&/code&), 一个包含 &code&p&/code& 后面的文本(&code&followed by more inline text&/code&)。&/p&&p&&b&demo2将生成一个行内格式上下文&/b&,生成一个匿名行盒(line box),里面包含两个匿名行内盒(inline box),&code&Some inline text&/code&和&code&followed by more inline text.&/code&和一个span行内盒。&/p&&p&OK,至于怎么触发块级格式上下文请看&a href=&https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&块格式化上下文&/a&。这里只为了说明IFC而介绍下BFC。&/p&&blockquote&当元素的 CSS 属性 &code&&a href=&https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/CSS/display& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&display&/a&&/code& 的计算值为 &code&inline&/code&, &code&inline-block&/code& 或 &code&inline-table&/code&时,称它为行内级元素。&br&行内级元素生成行内级盒(&i&inline-level boxes)&/i&,参与&a href=&https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/CSS/Inline_formatting_context& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&行内格式化上下文(inline formatting context)&/a&。同时参与生成行内格式化上下文的行内级盒称为行内盒(&i&Inline boxes)。&/i&&/blockquote&&p&&a href=&https://link.zhihu.com/?target=https%3A//www.w3.org/TR/CSS2/visuren.html%23inline-formatting& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&规范&/a&里IFC文字很多,提炼下我们需要的:&/p&&blockquote&如果一个矩形区域,包含着一些排成一条线的盒子,称为line box。&br&一个line box的宽度,由他的包含块(containg block)和floats的存在情况决定。line box的高度,由你给出的代码决定。(line-height),&b&即所有inline box的最大高度差。&/b&&br&当盒子的高度小于父级盒子高度时,&b&垂直方向的对齐'vertical-align'属性决定。&/b&&/blockquote&&h2&&b&Vertical-align(2)&/b&&/h2&&p&在上面的vertical-align(1)中主要了解了什么是baseline,以及它是如何确定的。我们继续研究这个属性,看下面说明表格:&/p&&p&&b&值描述&/b&baseline默认。元素放置在父元素的基线上。top把元素的顶端与行中最高元素的顶端对齐text-top把元素的顶端与父元素字体的顶端对齐middle把此元素放置在父元素的中部。bottom把元素的顶端与行中最低的元素的顶端对齐。text-bottom把元素的底端与父元素字体的底端对齐。&/p&&p&除了baseline我们已经很了解之外,其它几个属性我们貌似也能看懂,唯一的问题可能是父元素的顶端低端都是什么鬼? 需要确定一下,好的再次拿我们第一个例子来讲解,但我们需要变一下,加点东西进去:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&demo&&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&span&/span& &span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&'line-box'&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&img&/span& &span class=&na&&src&/span&&span class=&o&&=&/span&&span class=&s&&&https://sfault-avatar.b0.upaiyun.com/344/542/-b2_huge256&&/span& &span class=&na&&alt&/span&&span class=&o&&=&/span&&span class=&s&&&&&/span&&span class=&p&&&&&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&Xx&span class=&p&&&/&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&span&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
background:
.line-box {
background:
line-height: 200
.line-box img {
vertical-align: text-
.line-box span {
margin-left: 20
&/code&&/pre&&/div&&p&&a href=&https://link.zhihu.com/?target=http%3A//jsfiddle.net/Damonare/ck07neus/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&实例&/a&&/p&&p&&script async src=&&a href=&https://link.zhihu.com/?target=https%3A//jsfiddle.net/Damonare/ck07neus/embed/html%2Ccss%2Cresult/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&jsfiddle.net/Damonare/c&/span&&span class=&invisible&&k07neus/embed/html,css,result/&/span&&span class=&ellipsis&&&/span&&/a&&&&/script&&/p&&p&通过IFC部分我们知道,&a href=&https://link.zhihu.com/?target=https%3A//jsfiddle.net/Damonare/5oLvd0z4/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&之前的例子&/a&实际上有&b&生成一个匿名行盒(&/b&line box),虽然他可以继承父元素的属性,但我们没法直观的去操作它 ,OK,把这个匿名行盒变成可控的span元素就好了 ,如上demo所示。&/p&&p&我们通过设置line box的line-height来控制line-box的高度,然后设置img的vertical-align属性值,来观察具体的对齐方式。OK,读者你可以自行本地测试或是直接更改fiddle内容来看效果。但这里很容易有个误区,就是父元素的middle,top这些值是怎么确定的?如上,我们通过更改img元素的vertical-align的值,来观察区别,表面上看着好像是父元素根据&code&Xx&/code&内容来进行确定的,实则不然。我们再来看一个例子:&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//jsfiddle.net/Damonare/gkqq3dvp/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&下面没内容戳这&/a&&/p&&p&&script async src=&&a href=&https://link.zhihu.com/?target=http%3A//jsfiddle.net/Damonare/gkqq3dvp/embed/html%2Ccss%2Cresult/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&jsfiddle.net/Damonare/g&/span&&span class=&invisible&&kqq3dvp/embed/html,css,result/&/span&&span class=&ellipsis&&&/span&&/a&&&&/script&&/p&&p&上面例子中,我们更改了&code&Xx&/code&的对齐方式,发现了很奇特的现象?&code&?,&/code&当Xx&code&设置为text-bot&/code&to&code&m或是text-&/code&top&b&的时候父元素(ling box)被&/b&撑大了 ,但这另一方面这也证明了,父元素的基线和中线等&code&并不&/code&是由文本Xx决定的,谁决定的呢?前&b&&code&面提过的&/code&那个空&/b&白节点&code&决定的&/code&!这个空白节点实际上是理解内联元素布局的重点!不知道它的存在,很多问题是搞不清&code&楚的。那&/code&么这个空白节点又到底是怎么影响布局的呢?前面说过基线的决&code&定&/code&着是小写字母x,这个时候问题就来了,可能你早就想问了,不同字体&code&下&/code&面的小写字母x底部边缘肯定是有区别的啊,好&code&,我们在研究下font&/code&-family。&/p&&h2&&b&Font-family&/b&&/h2&&p&我们再来看一个 :&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//jsfiddle.net/Damonare/kyse4v44/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&下面没示例内容请戳这&/a&&/p&&p&&script async src=&&a href=&https://link.zhihu.com/?target=http%3A//jsfiddle.net/Damonare/kyse4v44/embed/html%2Ccss%2Cresult/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&jsfiddle.net/Damonare/k&/span&&span class=&invisible&&yse4v44/embed/html,css,result/&/span&&span class=&ellipsis&&&/span&&/a&&&&/script&&/p&&p&关于字体具体的知识可以看&a href=&https://zhuanlan.zhihu.com/p/?group_id=307520& class=&internal&&这篇博文&/a&,我简单的总结一下重点。首先字体是有一个&b&字体度量&/b&的概念的,&/p&&ul&&li&一款字体会定义一个 &a href=&https://link.zhihu.com/?target=http%25253A//designwithfontforge.com/zh-CN/The_EM_Square.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&em-square&/a&,它是用来盛放字符的金属容器。这个 em-square 一般被设定为宽高均为 1000 相对单位,不过也可以是
相对单位。&/li&&li&字体度量都是基于这个相对单位设置的,包括 ascender、descender、capital height、x-height 等。注意这里面的值是可以超出em-square范围的。&/li&&li&在浏览器中,上面的 1000 相对单位会按照你需要的 font-size 缩放。&/li&&/ul&&p&看上面的例子我们也能看出来,实际上一个&b&内联元素是有两个高度的&code&content-area&/code&高度(background-color实际渲染的那个高度)和 virtual-area 高度(实际区域占空间的高度也就是line-height)。&/b& &/p&&h2&&b&结论&/b&&/h2&&ul&&li&所有的内联元素都有两个高度&/li&&ul&&li&基于字体度量的 content-area&/li&&li&virtual-area(也就是 line-height )&/li&&/ul&&li&内联元素都有一个&code&空白节点&/code&存在着来确定基线等概念;&/li&&li&基线的确定和字体有关,和内部的内联元素无关;&/li&&li&IFC很难懂;&/li&&li&line-box(行盒) 的高度的受其子元素的 line-height 和 vertical-align 的影响;&/li&&li&我们貌似没法用CSS来更改字体度量。&/li&&/ul&&p&题目确实有些标题党的嫌疑了,实际上也没有挖很深,比如vertical-align在inline-table元素的作用效果以及sup,sub等其他的属性值,以及line-height具体的属性值如何生效的都没有涉及。我想把这篇文章重点放在布局上,而且篇幅也有限。没涉及的请自行查阅资料吧,在此说声抱歉。 &/p&&p&?以上。&/p&&h2&&b&后记&/b&&/h2&&p& 从刚开始做前端,身边CSS简单易学但很坑的声音就不绝于耳,很多人也说HTML、CSS一星期就能学会,现在渐渐觉得真是谬论。是,单纯掌握浮动,定位,对齐,居中等基础能解决一大半的布局问题,甚至百分之百,因为很多情况真的是变个写法莫名其妙就实现了想要的结果。可能这也是很多人说CSS坑的原因,但实际上很多开发者是不看CSS标准的,模仿个网站或是看着视频写个demo就觉得掌握了CSS,远远不是这样的。渐渐觉得深挖CSS要比深挖JavaScript难的多...你觉得CSS坑?谁让你不看标准呢.... ♀&/p&
前言总括: 本文通过实例讲解CSS中最大的难点之一,行内元素的布局,}

我要回帖

更多关于 ar480精准射程多少 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信