最全面的前端开发指南

HTML

语义

HTML5为我们提供了很多旨在精确描述内容的语义元素。确保你可以从它丰富的词汇中获益。


  1. <!-- bad --> 
  2. <div id="main"> 
  3.   <div class="article"> 
  4.     <div class="header"> 
  5.       <h1>Blog post</h1> 
  6.       <p>Published: <span>21st Feb, 2015</span></p> 
  7.     </div> 
  8.     <p>…</p> 
  9.   </div> 
  10. </div> 
  11.  
  12. <!-- good --> 
  13. <main> 
  14.   <article> 
  15.     <header> 
  16.       <h1>Blog post</h1> 
  17.       <p>Published: <time datetime="2015-02-21">21st Feb, 2015</time></p> 
  18.     </header> 
  19.     <p>…</p> 
  20.   </article> 
  21. </main> 

你需要理解你正在使用的元素的语义。用一种错误的方式使用语义元素比保持中立更糟糕。


  1. <!-- bad --> 
  2. <h1> 
  3.   <figure> 
  4.     <img alt=Company src=logo.png> 
  5.   </figure> 
  6. </h1> 
  7.  
  8. <!-- good --> 
  9. <h1> 
  10.   <img alt=Company src=logo.png> 
  11. </h1> 

简洁

保持代码的简洁。忘记原来的XHTML习惯。


  1. <!-- bad --> 
  2. <!doctype html> 
  3. <html lang=en> 
  4.   <head> 
  5.     <meta http-equiv=Content-Type content="text/html; charset=utf-8" /> 
  6.     <title>Contact</title> 
  7.     <link rel=stylesheet href=style.css type=text/css /> 
  8.   </head> 
  9.   <body> 
  10.     <h1>Contact me</h1> 
  11.     <label> 
  12.       Email address: 
  13.       <input type=email placeholder=you@email.com required=required /> 
  14.     </label> 
  15.     <script src=main.js type=text/javascript></script> 
  16.   </body> 
  17. </html> 
  18.  
  19. <!-- good --> 
  20. <!doctype html> 
  21. <html lang=en> 
  22.   <meta charset=utf-8> 
  23.   <title>Contact</title> 
  24.   <link rel=stylesheet href=style.css> 
  25.  
  26.   <h1>Contact me</h1> 
  27.   <label> 
  28.     Email address: 
  29.     <input type=email placeholder=you@email.com required> 
  30.   </label> 
  31.   <script src=main.js></script> 
  32. </html> 

可访问性

可访问性不应该是以后再想的事情。提高网站不需要你成为一个WCAG专家,你完全可以通过修复一些小问题,从而造成一个巨大的变化,例如:

  • 学习正确使用alt 属性
  • 确保链接和按钮被同样地标记(不允许<div>)
  • 不专门依靠颜色来传递信息
  • 明确标注表单控件

  1. <!-- bad --> 
  2. <h1><img alt="Logo" src="logo.png"></h1> 
  3.  
  4. <!-- good --> 
  5. <h1><img alt="My Company, Inc." src="logo.png"></h1> 

语言

当定义语言和字符编码是可选择的时候,总是建议在文档级别同时声明,即使它们在你的HTTP标头已经详细说明。比任何其他字符编码更偏爱UTF-8。


  1. <!-- bad --> 
  2. <!doctype html> 
  3. <title>Hello, world.</title> 
  4. <!-- good --> 
  5. <!doctype html> 
  6. <html lang=en> 
  7.   <meta charset=utf-8> 
  8.   <title>Hello, world.</title> 
  9. </html> 

性能

除非有正当理由才能在内容前加载脚本,不要阻塞页面的渲染。如果你的样式表很重,开头就孤立那些绝对需要得样式,并在一个单独的样式表中推迟二次声明的加载。两个HTTP请求显然比一个慢,但是感知速度是最重要的因素。


  1. <!-- bad --> 
  2. <!doctype html> 
  3. <meta charset=utf-8> 
  4. <script src=analytics.js></script> 
  5. <title>Hello, world.</title> 
  6. <p>...</p> 
  7.  
  8. <!-- good --> 
  9. <!doctype html> 
  10. <meta charset=utf-8> 
  11. <title>Hello, world.</title> 
  12. <p>...</p> 
  13. <script src=analytics.js></script> 

CSS

分号

虽然分号在技术上是CSS一个分隔符,但应该始终把它作为一个终止符。


  1. /* bad */ 
  2. div { 
  3.   color: red 
  4.  
  5. /* good */ 
  6. div { 
  7.   color: red; 

盒子模型

盒子模型对于整个文档而言最好是相同的。全局性的* { box-sizing: border-box; }就非常不错,但是不要改变默认盒子模型的特定元素,如果可以避免的话。


  1. /* bad */ 
  2. div { 
  3.   width: 100%; 
  4.   padding: 10px; 
  5.   box-sizing: border-box; 
  6.  
  7. /* good */ 
  8. div { 
  9.   padding: 10px; 

不要更改元素的默认行为,如果可以避免的话。元素尽可能地保持在自然的文档流中。例如,删除图像下方的空格而不改变其默认显示:


  1. /* bad */ 
  2. img { 
  3.   display: block; 
  4.  
  5. /* good */ 
  6. img { 
  7.   vertical-align: middle; 

同样,如果可以避免的话,不要关闭元素流。


  1. /* bad */ 
  2. div { 
  3.   width: 100px; 
  4.   position: absolute; 
  5.   right: 0; 
  6.  
  7. /* good */ 
  8. div { 
  9.   width: 100px; 
  10.   margin-left: auto; 

定位

在CSS中有许多定位元素的方法,但应该尽量限制以下属性/值。按优先顺序排列:


  1. display: block; 
  2. display: flex; 
  3. position: relative; 
  4. position: sticky; 
  5. position: absolute; 
  6. position: fixed; 

选择器

最小化紧密耦合到DOM的选择器。当选择器有多于3个结构伪类,后代或兄弟选择器的时候,考虑添加一个类到你想匹配的元素。


  1. /* bad */ 
  2. div:first-of-type :last-child > p ~ * 
  3.  
  4. /* good */ 
  5. div:first-of-type .info 

当你不需要的时候避免过载选择器。


  1. /* bad */ 
  2. img[src$=svg], ul > li:first-child { 
  3.   opacity: 0; 
  4.  
  5. /* good */ 
  6. [src$=svg], ul > :first-child { 
  7.   opacity: 0; 

特异性

不要让值和选择器难以覆盖。尽量少用id,并避免!important。


  1. /* bad */ 
  2. .bar { 
  3.   color: green !important; 
  4. .foo { 
  5.   color: red; 
  6.  
  7. /* good */ 
  8. .foo.bar { 
  9.   color: green; 
  10. .foo { 
  11.   color: red; 

覆盖

覆盖样式使得选择器和调试变得困难。如果可能的话,避免覆盖样式。


  1. /* bad */ 
  2. li { 
  3.   visibility: hidden; 
  4. li:first-child { 
  5.   visibility: visible; 
  6.  
  7. /* good */ 
  8. li + li { 
  9.   visibility: hidden; 

继承

不要重复可以继承的样式声明。


  1. /* bad */ 
  2. div h1, div p { 
  3.   text-shadow: 0 1px 0 #fff; 
  4.  
  5. /* good */ 
  6. div { 
  7.   text-shadow: 0 1px 0 #fff; 

简洁

保持代码的简洁。使用简写属性,没有必要的话,要避免使用多个属性。


  1. /* bad */ 
  2. div { 
  3.   transition: all 1s; 
  4.   top: 50%; 
  5.   margin-top: -10px; 
  6.   padding-top: 5px; 
  7.   padding-right: 10px; 
  8.   padding-bottom: 20px; 
  9.   padding-left: 10px; 
  10.  
  11. /* good */ 
  12. div { 
  13.   transition: 1s; 
  14.   top: calc(50% - 10px); 
  15.   padding: 5px 10px 20px; 

语言

英语表达优于数学公式。


  1. /* bad */ 
  2. :nth-child(2n + 1) { 
  3.   transform: rotate(360deg); 
  4.  
  5. /* good */ 
  6. :nth-child(odd) { 
  7.   transform: rotate(1turn); 

浏览器引擎前缀

果断地删除过时的浏览器引擎前缀。如果需要使用的话,可以在标准属性前插入它们。


  1. /* bad */ 
  2. div { 
  3.   transform: scale(2); 
  4.   -webkit-transform: scale(2); 
  5.   -moz-transform: scale(2); 
  6.   -ms-transform: scale(2); 
  7.   transition: 1s; 
  8.   -webkit-transition: 1s; 
  9.   -moz-transition: 1s; 
  10.   -ms-transition: 1s; 
  11.  
  12. /* good */ 
  13. div { 
  14.   -webkit-transform: scale(2); 
  15.   transform: scale(2); 
  16.   transition: 1s; 

动画

视图转换优于动画。除了opacity 和transform,避免动画其他属性。


  1. /* bad */ 
  2. div:hover { 
  3.   animation: move 1s forwards; 
  4. @keyframes move { 
  5.   100% { 
  6.     margin-left: 100px; 
  7.   } 
  8.  
  9. /* good */ 
  10. div:hover { 
  11.   transition: 1s; 
  12.   transform: translateX(100px); 

单位

可以的话,使用无单位的值。如果使用相对单位,那就用rem 。秒优于毫秒。


  1. /* bad */ 
  2. div { 
  3.   margin: 0px; 
  4.   font-size: .9em; 
  5.   line-height: 22px; 
  6.   transition: 500ms; 
  7.  
  8. /* good */ 
  9. div { 
  10.   margin: 0; 
  11.   font-size: .9rem; 
  12.   line-height: 1.5; 
  13.   transition: .5s; 

颜色

如果你需要透明度,使用rgba。另外,始终使用十六进制格式。


  1. /* bad */ 
  2. div { 
  3.   color: hsl(103, 54%, 43%); 
  4.  
  5. /* good */ 
  6. div { 
  7.   color: #5a3; 

绘画

当资源很容易用CSS复制的时候,避免HTTP请求。


  1. /* bad */ 
  2. div::before { 
  3.   content: url(white-circle.svg); 
  4.  
  5. /* good */ 
  6. div::before { 
  7.   content: ""; 
  8.   display: block; 
  9.   width: 20px; 
  10.   height: 20px; 
  11.   border-radius: 50%; 
  12.   background: #fff; 

Hacks

不要使用Hacks。


  1. /* bad */ 
  2. div { 
  3.   // position: relative; 
  4.   transform: translateZ(0); 
  5.  
  6. /* good */ 
  7. div { 
  8.   /* position: relative; */ 
  9.   will-change: transform; 

JavaScript

性能

可读性,正确性和可表达性优于性能。JavaScript基本上永远不会是你的性能瓶颈。图像压缩,网络接入和DOM重排来代替优化。如果从本文中你只能记住一个指导原则,那么毫无疑问就是这一条。


  1. // bad (albeit way faster) 
  2. const arr = [1, 2, 3, 4]; 
  3. const len = arr.length; 
  4. var i = -1; 
  5. var result = []; 
  6. while (++i < len) { 
  7.   var n = arr[i]; 
  8.   if (n % 2 > 0) continue; 
  9.   result.push(n * n); 
  10.  
  11. // good 
  12. const arr = [1, 2, 3, 4]; 
  13. const isEven = n => n % 2 == 0; 
  14. const square = n => n * n; 
  15.  
  16. const result = arr.filter(isEven).map(square); 

无状态

尽量保持函数纯洁。理论上,所有函数都不会产生副作用,不会使用外部数据,并且会返回新对象,而不是改变现有的对象。


  1. // bad 
  2. const merge = (target, ...sources) => Object.assign(target, ...sources); 
  3. merge({ foo: "foo" }, { bar: "bar" }); // => { foo: "foo", bar: "bar" } 
  4.  
  5. // good 
  6. const merge = (...sources) => Object.assign({}, ...sources); 
  7. merge({ foo: "foo" }, { bar: "bar" }); // => { foo: "foo", bar: "bar" } 

本地化

尽可能地依赖本地方法。


  1. // bad 
  2. const toArray = obj => [].slice.call(obj); 
  3.  
  4. // good 
  5. const toArray = (() => 
  6.   Array.from ? Array.from : obj => [].slice.call(obj) 
  7. )(); 

强制性

如果强制有意义,那么就使用隐式强制。否则就应该避免强制。


  1. // bad 
  2. if (x === undefined || x === null) { ... } 
  3.  
  4. // good 
  5. if (x == undefined) { ... } 

循环

不要使用循环,因为它们会强迫你使用可变对象。依靠array.prototype 方法。


  1. // bad 
  2. const sum = arr => { 
  3.   var sum = 0; 
  4.   var i = -1; 
  5.   for (;arr[++i];) { 
  6.     sum += arr[i]; 
  7.   } 
  8.   return sum; 
  9. }; 
  10.  
  11. sum([1, 2, 3]); // => 6 
  12.  
  13. // good 
  14. const sum = arr => 
  15.   arr.reduce((x, y) => x + y); 
  16.  
  17. sum([1, 2, 3]); // => 6 

如果不能避免,或使用array.prototype 方法滥用了,那就使用递归。


  1. // bad 
  2. const createDivs = howMany => { 
  3.   while (howMany--) { 
  4.     document.body.insertAdjacentHTML("beforeend", "<div></div>"); 
  5.   } 
  6. }; 
  7. createDivs(5); 
  8.  
  9. // bad 
  10. const createDivs = howMany => 
  11.   [...Array(howMany)].forEach(() => 
  12.     document.body.insertAdjacentHTML("beforeend", "<div></div>") 
  13.   ); 
  14. createDivs(5); 
  15.  
  16. // good 
  17. const createDivs = howMany => { 
  18.   if (!howMany) return; 
  19.   document.body.insertAdjacentHTML("beforeend", "<div></div>"); 
  20.   return createDivs(howMany - 1); 
  21. }; 
  22. createDivs(5); 

这里有一个通用的循环功能,可以让递归更容易使用。

参数

忘记arguments 对象。余下的参数往往是一个更好的选择,这是因为:

你可以从它的命名中更好地了解函数需要什么样的参数

真实数组,更易于使用。


  1. // bad 
  2. const sortNumbers = () => 
  3.   Array.prototype.slice.call(arguments).sort(); 
  4.  
  5. // good 
  6. const sortNumbers = (...numbers) => numbers.sort(); 

应用

忘掉apply()。使用操作符。


  1. const greet = (first, last) => `Hi ${first} ${last}`; 
  2. const person = ["John", "Doe"]; 
  3.  
  4. // bad 
  5. greet.apply(null, person); 
  6.  
  7. // good 
  8. greet(...person); 

绑定

当有更惯用的做法时,就不要用bind() 。


  1. // bad 
  2. ["foo", "bar"].forEach(func.bind(this)); 
  3.  
  4. // good 
  5. ["foo", "bar"].forEach(func, this); 
  6.  
  7. // bad 
  8. const person = { 
  9.   first: "John", 
  10.   last: "Doe", 
  11.   greet() { 
  12.     const full = function() { 
  13.       return `${this.first} ${this.last}`; 
  14.     }.bind(this); 
  15.     return `Hello ${full()}`; 
  16.   } 
  17.  
  18. // good 
  19. const person = { 
  20.   first: "John", 
  21.   last: "Doe", 
  22.   greet() { 
  23.     const full = () => `${this.first} ${this.last}`; 
  24.     return `Hello ${full()}`; 
  25.   } 

函数嵌套

没有必要的话,就不要嵌套函数。


  1. // bad 
  2. [1, 2, 3].map(num => String(num)); 
  3.  
  4. // good 
  5. [1, 2, 3].map(String); 

合成函数

避免调用多重嵌套函数。使用合成函数来替代。


  1. const plus1 = a => a + 1; 
  2. const mult2 = a => a * 2; 
  3.  
  4. // bad 
  5. mult2(plus1(5)); // => 12 
  6.  
  7. // good 
  8. const pipeline = (...funcs) => val => funcs.reduce((a, b) => b(a), val); 
  9. const addThenMult = pipeline(plus1, mult2); 
  10. addThenMult(5); // => 12 

缓存

缓存功能测试,大数据结构和任何奢侈的操作。


  1. // bad 
  2. const contains = (arr, value) => 
  3.   Array.prototype.includes 
  4.     ? arr.includes(value) 
  5.     : arr.some(el => el === value); 
  6. contains(["foo", "bar"], "baz"); // => false 
  7.  
  8. // good 
  9. const contains = (() => 
  10.   Array.prototype.includes 
  11.     ? (arr, value) => arr.includes(value) 
  12.     : (arr, value) => arr.some(el => el === value) 
  13. )(); 
  14. contains(["foo", "bar"], "baz"); // => false 

变量

const 优于let ,let 优于var。


  1. // bad 
  2. var me = new Map(); 
  3. me.set("name", "Ben").set("country", "Belgium"); 
  4.  
  5. // good 
  6. const me = new Map(); 
  7. me.set("name", "Ben").set("country", "Belgium"); 

条件

IIFE 和return 语句优于if, else if,else和switch语句。


  1. // bad 
  2. var grade; 
  3. if (result < 50) 
  4.   grade = "bad"; 
  5. else if (result < 90) 
  6.   grade = "good"; 
  7. else 
  8.   grade = "excellent"; 
  9.  
  10. // good 
  11. const grade = (() => { 
  12.   if (result < 50) 
  13.     return "bad"; 
  14.   if (result < 90) 
  15.     return "good"; 
  16.   return "excellent"; 
  17. })(); 

对象迭代

如果可以的话,避免for…in。


  1. const shared = { foo: "foo" }; 
  2. const obj = Object.create(shared, { 
  3.   bar: { 
  4.     value: "bar", 
  5.     enumerable: true 
  6.   } 
  7. }); 
  8.  
  9. // bad 
  10. for (var prop in obj) { 
  11.   if (obj.hasOwnProperty(prop)) 
  12.     console.log(prop); 
  13.  
  14. // good 
  15. Object.keys(obj).forEach(prop => console.log(prop)); 

map对象

在对象有合法用例的情况下,map通常是一个更好,更强大的选择。


  1. // bad 
  2. const me = { 
  3.   name: "Ben", 
  4.   age: 30 
  5. }; 
  6. var meSize = Object.keys(me).length; 
  7. meSize; // => 2 
  8. me.country = "Belgium"; 
  9. meSize++; 
  10. meSize; // => 3 
  11.  
  12. // good 
  13. const me = new Map(); 
  14. me.set("name", "Ben"); 
  15. me.set("age", 30); 
  16. me.size; // => 2 
  17. me.set("country", "Belgium"); 
  18. me.size; // => 3 

Curry

Curry虽然功能强大,但对于许多开发人员来说是一个外来的范式。不要滥用,因为其视情况而定的用例相当不寻常。


  1. // bad 
  2. const sum = a => b => a + b; 
  3. sum(5)(3); // => 8 
  4.  
  5. // good 
  6. const sum = (a, b) => a + b; 
  7. sum(5, 3); // => 8 

可读性

不要用看似聪明的伎俩混淆代码的意图。


  1. // bad 
  2. foo || doSomething(); 
  3.  
  4. // good 
  5. if (!foo) doSomething(); 
  6.  
  7. // bad 
  8. void function() { /* IIFE */ }(); 
  9.  
  10. // good 
  11. (function() { /* IIFE */ }()); 
  12.  
  13. // bad 
  14. const n = ~~3.14; 
  15.  
  16. // good 
  17. const n = Math.floor(3.14); 

代码重用

不要害怕创建小型的,高度可组合的,可重复使用的函数。


  1. // bad 
  2. arr[arr.length - 1]; 
  3.  
  4. // good 
  5. const first = arr => arr[0]; 
  6. const last = arr => first(arr.slice(-1)); 
  7. last(arr); 
  8.  
  9. // bad 
  10. const product = (a, b) => a * b; 
  11. const triple = n => n * 3; 
  12.  
  13. // good 
  14. const product = (a, b) => a * b; 
  15. const triple = product.bind(null, 3); 

依赖性

最小化依赖性。第三方是你不知道的代码。不要只是因为几个可轻易复制的方法而加载整个库:


  1. // bad 
  2. var _ = require("underscore"); 
  3. _.compact(["foo", 0])); 
  4. _.unique(["foo", "foo"]); 
  5. _.union(["foo"], ["bar"], ["foo"]); 
  6.  
  7. // good 
  8. const compact = arr => arr.filter(el => el); 
  9. const unique = arr => [...Set(arr)]; 
  10. const union = (...arr) => unique([].concat(...arr)); 
  11.  
  12. compact(["foo", 0]); 
  13. unique(["foo", "foo"]); 
  14. union(["foo"], ["bar"], ["foo"]); 

作者:小峰

来源:51CTO

时间: 2024-10-01 00:07:05

最全面的前端开发指南的相关文章

干货!前端开发指南20+

废话少说,直接上干货! 1. CSS介质查询和范围选择器 如果你有看过Patrick Clancey最近写的那篇关于A List Apart的文章"mod queries",那么将会更好地理解这一点.它是一个工具或者说是指南,可以很好的帮助读者去了解这些CSS选择器,以及如何使用它们在网页布局中布置未知数量的项目. 2.抛弃JavaScript 通过智能警告,提示这些组件可能不是语义的或所有用户都可以访问的,这个网站集成了大量不同的技术,展示了如果只使用HTML,CSS和Sass,可以

设计理论:制作网页前端开发的文档

前端开发的文档相信大多数情况下都没有后端的服务描述详细,而大多数测试也仅仅在黑盒测试,所以很多情况下对这片文档的描述都廖廖无几. 前端文档缺失的原因 前端开发的文档相信大多数情况下都没有后端的服务描述详细,而大多数测试也仅仅在黑盒测试,所以很多情况下对这片文档的描述都廖廖无几. * 前端开发的代码分散--没有规范化,没有很好的设计,大多数人仍以业务为主的开发方式.* 测试人员对前端仍然处于黑盒测试,有没有文档都不影响到他们的测试进程.* 一旦业务定型,用传统方式的文档模式,很难复制到前端开发来.

php开发指南:缓存详解

我们可以在HTML页面利用meta tag和PHP程序中通过header来控制.例如: 代码如下 header('Cache-Control:max-age=86400, must-revalidate');//24小时 header('Last-Modified:'.gmdate('D, d M Y H:i:s').'GMT'); header('Expires:'.gmdate('D, d M Y H:i:s', time() + '86400').'GMT'); echo '我不刷新';再

Google Web App开发指南第三章:案例研究

旅程计划应用(Wayfindit: Trip Planner App) 在大多数情况下,Wayfindit的应用必须有很好的易用性.旅行是一件很复杂的事情,不管是商业旅行还是休假旅行,一个顺利的旅程要求从家门到目的都没有意外之忧.Wayfindit的应用要能给旅行者提供所需信息,并且要快而准确.这意味着它需要一个最小的.直观的.响应式界面,能在前端提供有关内容的重要信息--HTML5的地理感知和离线存储特性实现. 一个完美的袖珍指南 它就装在你的口袋里或者包里,即时提供信息.它拥有本地存储和地理

如何打造一个令人愉悦的前端开发环境(一)

文章来源 最近几年,前端发展越来越迅速,各种萌新加入了前端这个大家庭,大有赶IOS.超Android的趋势呀!同时,萌新们提出了各种前端工作问题,除了最基础的html.css.js三板斧之外,最让人头疼的应该是关于环境的配置问题,所以以环境作为切入点,开始一系列的前端开发环境配置文章. 主要会涉及到打包.构建.编程工具.debug等等前端环境,以及前后端分离.Nodejs中间层使用伸展面. 工欲善其事必先利其器 以编程工具而言WebStorm.sublime.Atom.VS Code.Brack

ASP.NET Aries 开源开发框架:开发指南(一)

前言: 上周开源了Aries开发框架后,好多朋友都Download了源码,在运行过程里,有一些共性的问题会问到. 所以本篇打算写一下简单的开发指南,照顾一下不是太看的懂源码的同学,同时也会讲解一下框架原理. 开源的文章或源码获取地址见上一篇文章:开源:ASP.NET Aries 开发框架   关于框架: 首先,这是一套开发框架,它类同于WebForm.MVC..NET Core. 相比webform,mvc,.NET Core 它简化了后端很多东西,它也加强了前端一些功能,默认集成的功能和界面,

Knockout应用开发指南 第一章:入门

原文:Knockout应用开发指南 第一章:入门 1    Knockout简介 (Introduction) Knockout是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化. Knockout有如下4大重要概念: 声明式绑定 (Declarative Bindings):使用简明易读的语法很容易地将模型(model)数据关联到DOM元素上. UI界面自动刷新 (Automatic UI Refresh):当您的模型状态(model state)改变时,您的UI

二、Angular 2.0开发指南以及搭建开发环境

自第一章讲Angular2.0的简单开发入门,我们了解到ng2的开发实践是围绕着web-component来展开的,ng2中更加强化了Component的概念,弱化了指令的概念(实际上Component是复杂指令).同时我们学习到web-component中数据和视图是如何互相影响的,即Input和Output的概念,数据通过Input往view以及view里的子组件传递,view及其子组件通过Ouput来改变数据(VM通过数据绑定机制实现互通,View <- data-bindings ->

推荐20个很有帮助的 Web 前端开发教程

在平常的搜索中,我碰到过很多有趣的信息,应用程序和文档,我把它们整理在下面这个列表.这是收藏的遇到的有用内容的一个伟大的方式,可以在你需要的时候方便查阅.相信你会在这个列表中发现对你很有用的资料. 1. CSS Vocabulary 一个伟大的指向和点击的小应用程序,让你加快速度掌握 CSS 语法的各个不同部分,学习各个属性的正确的名称. 2. Liquidapsive 一个简单的信息化布局,通过选择框的方式,可以让你在响应式,自适应,流动和静态布局中选择,所以你可以看到四大布局类型之间的区别.