xml地图|网站地图|网站标签 [设为首页] [加入收藏]
4正式发布,变量教程
分类:web前端

CSS 变量教程

2017/05/10 · CSS · 变量

原文出处: 阮一峰   

今年三月,微软宣布 Edge 浏览器将支持 CSS 变量。

这个重要的 CSS 新功能,所有主要浏览器已经都支持了。本文全面介绍如何使用它,你会发现原生 CSS 从此变得异常强大。

图片 1

React.js深入学习详细解析

2016/07/16 · JavaScript · ReactJS

本文作者: 伯乐在线 - winty 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

今天,继续深入学习react.js。

目录:

一、JSX介绍

二、React组件生命周期详解

三、属性、状态的含义和用法

四、React中事件的用法

五、组件的协同使用

六、React中的双向绑定

 一、JSX介绍

①定义

JSX=JavaScript XML,是一种在React组件内部构建标签的类XML语法。React在不使用JSX的情况下一样可以工作,但是使用JSX可以提高组件的可读性,增强JS语义,结构清晰,抽象程度高,代码模块化。因此推荐在React中使用JSX。

②特点

1、元素名首字母大写

2、符合嵌套规则

3、可以写入求值表达式

4、驼峰式命名

5、不能使用javascript原生函数的一些关键词,如for和class。需要替换成htmlFor和className

③使用方法

1、使用动态值:JSX将两个花括号之间的内容{…}渲染为动态值,花括号指明了一个javascript上下文环境,花括号里面可以是一个变量,也可以是函数。 例如:

JavaScript

var name=“winty”; <p>{name}</p>

1
2
3
var name=“winty”;
 
<p>{name}</p>

JavaScript

function date(d){ return [ d.getFullYear(), d.getMonth()+1, d.getDate() ].join('-); }; <p>{date(new Date()}</p>

1
2
3
4
5
6
7
8
function date(d){
  return [
    d.getFullYear(),
    d.getMonth()+1,
    d.getDate()
  ].join('-);
};
<p>{date(new Date()}</p>

2.注释:首先,在子节点中注释要用大括号包裹起来,然后就可以单行注释/**/,也可以多行注释//。

JavaScript

var Hello=React.createClass({ render:function(){ return <p name="winty"> //set name Hello ,World /* 多行注释 多行注释 */ </p> } });

1
2
3
4
5
6
7
8
9
10
11
var Hello=React.createClass({
     render:function(){
         return <p name="winty"> //set name
                  Hello ,World
                  /*
                    多行注释
                    多行注释
                  */
                  </p>
           }
   });

3.使用CSS内联样式

JavaScript

var style={ color:#000; }; React.render(<div style={style}>....</div>,document.body);

1
2
3
4
var style={
    color:#000;
};
React.render(<div style={style}>....</div>,document.body);

4.使用条件判断

JavaScript

//方法1,三目运算符 var Hello=React.createClass({ render:function(){ return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p> } }); //方法2,if-else语句 var Hello1=React.createClass({ getName:function(){ if(this.props.name) return this.props.name; else return "LuckyWinty"; render:function(){ return <p>Hello,{this.getName}</p> } }); //方法3,使用逻辑||运算符 var Hello3=React.createClass({ render:function(){ return <p>Hello,{this.props.name||"LuckyWinty"}</p> } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//方法1,三目运算符
var Hello=React.createClass({
     render:function(){
        return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p>
     }
});
 
//方法2,if-else语句
var Hello1=React.createClass({
     getName:function(){
          if(this.props.name)
            return this.props.name;
          else
            return "LuckyWinty";
     render:function(){
        return <p>Hello,{this.getName}</p>
     }
});
//方法3,使用逻辑||运算符
var Hello3=React.createClass({
     render:function(){
        return <p>Hello,{this.props.name||"LuckyWinty"}</p>
     }
});

④非DOM属性介绍

JSX中有3个非DOM属性,分别是:dangerouslySetInnerHTML、ref、key。

dangerouslySetInnerHTML:在JSX中直接插入HTML代码,但是如果能避免使用这个属性则尽量避免使用。

不合时宜的使用 innerHTML 可能会导致 cross-site scripting (XSS) 攻击。 净化用户的输入来显示的时候,经常会出现错误,不合适的净化也是导致网页攻击 的原因之一。

在彻底的理解安全问题后果并正确地净化数据之后,生成只包含唯一 key __html 的对象,并且对象的值是净化后的数据。例如:

JavaScript

function createMarkup() { return {__html: 'First · Second'}; }; <div dangerouslySetInnerHTML={createMarkup()} />

1
2
3
4
function createMarkup() {
  return {__html: 'First &middot; Second'};
};
<div dangerouslySetInnerHTML={createMarkup()} />

ref:父组件引用子组件,你可以通过在属性中设置期望的引用名来定义一个引用。例如:

JavaScript

... render:function(){ return <div> <input ref="MyInput" .../> </div> } ... //然后你就可以在组件中的任何地方使用this.refs.myInput获取这个引用了

1
2
3
4
5
6
7
8
...
render:function(){
  return <div>
           <input ref="MyInput" .../>
           </div>
}
...
//然后你就可以在组件中的任何地方使用this.refs.myInput获取这个引用了

key:是一个可选的唯一标识符,通过给组件设置一个独一无二的键,并确保它在一个渲染周期中保持一致,使得React能够更只能地决定应该重用一个组件还是销毁并重建一个组件,进而提高渲染性能。例如:

JavaScript

var Hello3=React.createClass({ render:function(){ return <ul> <li key="1">1</li> <li key="2">2</li> <li key="3">3</li> </ul> } });

1
2
3
4
5
6
7
8
9
var Hello3=React.createClass({
     render:function(){
        return <ul>
                <li key="1">1</li>
                <li key="2">2</li>
                <li key="3">3</li>
         </ul>
     }
});

更多详细信息请参考:

 

二、React组件生命周期详解

组件本质上就是状态机,输入确定,输出一定确定。状态和结果一一对应,从而使程序变得直观。状态发生转换时会触发不同的钩子函数,从而让开发者有机会做出响应。可以用事件的思路来理解状态,但是事件与事件之间互相独立,但是不同状态之间可能会互相影响。

组件的所有状态结合起来就成了组件的生命周期。即:初始化阶段->运行中阶段->销毁阶段。

不同生命周期内可以自定义的函数

初始化阶段:

①getDefaultProps:获取默认属性,只调用一次,是在createClass之后调用的。实例之间共享引用

②getInitialState:初始化每个实例的特有初始化状态

③componentWillMount:mout就是装载的意思,这个方法的意思就是说组件即将被装载到页面中,也是render之前最后一次修改状态的机会

④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上。只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。

⑤componentDidMount:组件被装载后才会被调用,也就是说调用这个方法的时候,组件已经被渲染到了页面上,这个时候可以修改DOM

这五个函数的执行顺序就是从上到下的。需要注意的是getDefaultProps只会在组件的第一个实例被初始化的时候被调用,也就是说第二个实例之后都是从getInitialState开始调用。同一个组件的所有实例的默认属性都是一样的。

主要测试代码:

JavaScript

<script type="text/babel"> var Hello=React.createClass({ getDefaultProps:function(){ console.log("getDefaultProps, 1"); }, getInitialState:function(){ console.log("getInitialState, 2"); return null; }, componentWillMount:function(){ console.log("componentWillMount, 3"); }, render:function(){ console.log("render, 4"); return <p>Hi,LuckyWinty!</p> }, componentDidMount:function(){ console.log("componentDidMount, 5"); }, }); React.render(<Hello></Hello>,document.body); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script type="text/babel">
    var Hello=React.createClass({
      getDefaultProps:function(){
          console.log("getDefaultProps, 1");
      },
      getInitialState:function(){
          console.log("getInitialState, 2");
          return null;
      },
      componentWillMount:function(){
          console.log("componentWillMount, 3");
      },
      render:function(){
          console.log("render, 4");
          return <p>Hi,LuckyWinty!</p>
      },
      componentDidMount:function(){
          console.log("componentDidMount, 5");
      },
    });
    React.render(<Hello></Hello>,document.body);
</script>

运行结果:

图片 2

运行中阶段:

①componentWillReceiveProps:这个函数在组件即将接收到属性时触发的,或者是父组件的属性发生变化时,属性在传送到组件之前,开发者有机会通过这个函数去处理属性。比如修改,更新内部状态等。

②shouldComponentUpdate:当组件接收到新属性或者新状态的时候触发的。这个是一个疑问函数,也就是说我们可以告诉react不去更新某个组件。因为有时候属性或者状态并不会导致组件发生更新。在组件不需要更新的情况下,手动使shouldComponentUpdate返回false,这样react就不需要再经过render和diff算法去判断是否要更新,从而提高性能。

③componentWillUpdate:render触发之前触发,更新组件,不能修改属性和状态

④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上,只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。

⑤componentDidUpdate:render之后,真正的DOM被渲染之后调用

备注:这五个函数的执行顺序也是从上到下的。这个的测试代码已上传至:

销毁阶段:

①componentWillUnmount:这个函数在销毁操作真正执行之前调用,给开发者最后的机会进行一些清理工作。

三、属性、状态的含义和用法

属性的含义:

props=properties,属性是不可以由组件自己进行修改的,组件的属性是由父组件传递进来的。

属性的用法:

一、键值对

XHTML

<Hello name="winty"/> 字符串 <Hello name={123}/> 大括号包裹的求值表达式 <Hello name={[1,2,3]}/> 传入数组 <Hello name={winty}/> 变量

1
2
3
4
<Hello name="winty"/>   字符串
<Hello name={123}/>    大括号包裹的求值表达式
<Hello name={[1,2,3]}/>   传入数组
<Hello name={winty}/>   变量

二、展开定义(个人认为就是对象式定义)

JavaScript

var props={ one:"123", two:"22" }

1
2
3
4
var props={
   one:"123",
   two:"22"
}

这样定义的话,理论上使用应该是one={props.one}这样调用,但是这样写起来比较繁琐,而且如果数据被修改,就需要对应修改相应的赋值,并且无法动态地设置属性,所以react中添加了一种展开语法:

<Hello {…props}/>    //也就是三个点加上对象名称。

这样使用展开语法,react就会自动把对象中的变量和值当作是属性的赋值,所以Hello实际上就拿到了one、two两个属性,如果没有三个点的话,Hello拿到的实际上就是props对象,使用的时候还需要自己从中取出变量和值

三、调用react提供的setProps()函数(几乎不用)

JavaScript

var instance=React.render(<HelloWorld></HelloWorld>,document.body); instance.setProps({name:"winty"});

1
2
var instance=React.render(<HelloWorld></HelloWorld>,document.body);
instance.setProps({name:"winty"});

状态的含义:

state,状态是由事物自行处理、不断变化的

状态的用法:

getInitialState:初始化实例的状态

setState:更新组件状态,一旦更新了状态,那么就会触发diff算法,检查内容是否发生变化,若有变化则更新组件,否则就不用。

属性和状态对比

相似点:都是纯JS对象、都会触发render更新、都具有确定性。

图片 3

属性和状态区分:组件在运行时需要修改的数据就是状态

四、React中事件的用法

事件处理函数:React绑定事件处理器的方法和HTML语法非常类似,所有的事件在命名上与原生的javascript规范一致,并且会在相同的情境下触发。

编写函数

handleClick:function(){

}

绑定

onClick={this.handleClick}

各类事件详细说明:

①移动设备上的触摸事件:onTouchCancel、onTouchEnd、onTouchMove、onTouchStart

②键盘类事件:onKeyDown、onKeyPress、onKeyUp

③剪切类事件:onCopy、onCut、onPaste

④表单类:onChange//内容变化即触发、onInput//输入框、onSubmit//禁止表单默认跳转行为

⑤事件:onFocus、onBlur

⑥UI元素类:onScroll

⑦鼠标滚动事件:onWheel

⑧鼠标类型:onClick、onContextMenu//右键菜单、onDoubleClick //双击、onMouseDown、onMouseEnter、onMouseLeave、onMouseMove、onMouseOut、onMouseOver、onMouseUp

⑨拖拽事件:onDrop、onDrag、onDragEnd、onDragEnter、onDragExit、onDragLeave、onDragOver、onDragStart

事件对象介绍

使用方法:就是在编写事件对象处理函数的时候,添加一个参数。拿到这个对象之后,就通过对象的属性来可以获取一些信息。

例如:

JavaScript

handleChange:function(event){ console.log(event.target.value); }

1
2
3
handleChange:function(event){
    console.log(event.target.value);
}

示例中,event就是事件对象,event.target就是事件对象的属性,就是对应的DOM元素,拿到这个元素之后再获取它的值。

事件对象属性

通用属性:

图片 4

其他不同类型的事件有不同的属性,简单了解一下

图片 5

知道了事件的一些属性,我们就可以很方便地在React中获取这些属性,进行一些逻辑的处理,实现一些复杂的业务功能、页面效果等。

例如:我们可以利用鼠标事件属性,实时显示鼠标在某个区域的坐标:

JavaScript

<script type="text/jsx"> var HelloWorld = React.createClass({ getInitialState: function () { return { x: 0, y: 0 } }, handleMouseMove: function (event) { this.setState({ x: event.clientX, y: event.clientY }); }, render: function () { return <div onMouseMove={this.handleMouseMove} style={{ height: '500px', width: '500px', backgroundColor: 'gray' }}> {this.state.x + ', ' + this.state.y} </div>; }, }); React.render(<HelloWorld></HelloWorld>, document.body); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script type="text/jsx">
        var HelloWorld = React.createClass({
            getInitialState: function () {
                return {
                    x: 0,
                    y: 0
                }
            },
            handleMouseMove: function (event) {
                this.setState({
                    x: event.clientX,
                    y: event.clientY
                });
            },
            render: function () {
                return <div onMouseMove={this.handleMouseMove} style={{
                    height: '500px',
                    width: '500px',
                    backgroundColor: 'gray'
                }}>
                {this.state.x + ', ' + this.state.y}
                </div>;
            },
        });
        React.render(<HelloWorld></HelloWorld>, document.body);
    </script>

五、组件的协同使用

组件协同使用的定义:组件的协同本质上就是对组件的一种组织、管理方式。

组件协同使用的目的:逻辑清晰、代码模块化、封装细节、代码可复用。

组件协同使用的方式:

①组件嵌套使用:也就是说,用一个父组件把子组件包裹起来,本质就是父子关系。如下图描述:

图片 6

实例代码:

JavaScript

var React = require('react'); var CommentList=require('./CommentList.jsx'); var CommentForm=require('./commentFrom.jsx'); var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> //这是一个组件 <CommentForm /> //这是另一个组件 </div> ); } }); module.exports = CommentBox;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var React = require('react');
var CommentList=require('./CommentList.jsx');
var CommentForm=require('./commentFrom.jsx');
 
var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList />   //这是一个组件
        <CommentForm />    //这是另一个组件
      </div>
    );
  }
});
 
module.exports = CommentBox;

父子组件之间的通信:

父组件->子组件:通过属性,父组件把数据通过属性来传递给子组件

子组件->父组件:本质上,子组件不能向父组件通信。但是可以间接地通过触发事件来通信,也就是委托。

嵌套组合缺点:

父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护

无法掌握所有细节,使用者只知道组件用法,不知道实现细节,遇到问题难以修复

②Mixin:也就是可以把相同的代码抽象出来,封装成一个函数,然后再调用。

Mixin的目的:横向抽离出组件的相似代码

相似概念:面向切向面编程、插件

实例代码:

JavaScript

var Time=React.createClass({ mixins:[IntervalMixin(1000)], getInitialState:function(){ return {secondElapsed:0}; }, onTick:function(){ this.setState({secondElapsed:this.state.secondElapsed+1}); }, render:function(){ return ( <div>Seconds Elapsed:{this.state.secondsElapsed}</div> ); } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Time=React.createClass({
    mixins:[IntervalMixin(1000)],
    getInitialState:function(){
       return {secondElapsed:0};
    },
    onTick:function(){
    this.setState({secondElapsed:this.state.secondElapsed+1});
    },
    render:function(){
    return (
       <div>Seconds Elapsed:{this.state.secondsElapsed}</div>
    );
    }
});

mixin相当简单,它们就是混合进组件类中的对象而已。React在这方面实现得更加深入,它能防止静默函数覆盖,同时还支持多个mixin混合。但是这些功能在别的系统中可能引起冲突。例如:

JavaScript

React.createClass({ mixins:[{ getInitialState:function(){ return {a:1}} }], getInitialState:function(){ return {b:2}} });

1
2
3
4
5
6
React.createClass({
    mixins:[{
      getInitialState:function(){  return {a:1}}
    }],
    getInitialState:function(){  return {b:2}}
});

这样在mixin和组件类中同时定义了getInitialState方法,得到的初始state是{a:1,b:2}.如果mixin中的方法和组件类中的方法返回的对象中存在重复的键,React会抛出一个错误来警示这个问题。

 六、React中的双向绑定

React创立的理念跟angular那些框架就是不同的,React是单向数据绑定的。那么怎么实现像angular那样的双向绑定效果呢?看代码:

XHTML

<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <title>React中的双向数据绑定</title> </head> <body> <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script> <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script> <script type="text/jsx"> var BindingMixin = { handleChange: function(key) { var that = this var newState = {} return function(event) { newState[key] = event.target.value that.setState(newState) } } } var BindingExample = React.createClass({ mixins: [React.addons.LinkedStateMixin], getInitialState: function() { return { text: '', comment: '', } }, render: function() { return <div> <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} /> <textarea valueLink={this.linkState('comment')}></textarea> <h3>{this.state.text}</h3> <h3>{this.state.comment}</h3> </div> } }) React.render(<BindingExample></BindingExample>, document.body); </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>React中的双向数据绑定</title>
</head>
<body>
    <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script>
    <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script>
    <script type="text/jsx">
        var BindingMixin = {
            handleChange: function(key) {
                var that = this
                var newState = {}
                return function(event) {  
                    newState[key] = event.target.value
                    that.setState(newState)
                }
            }
        }
        var BindingExample = React.createClass({
            mixins: [React.addons.LinkedStateMixin],
            getInitialState: function() {
                return {
                    text: '',
                    comment: '',
                }
            },
            render: function() {
                return <div>
                    <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} />
                    <textarea valueLink={this.linkState('comment')}></textarea>
                    <h3>{this.state.text}</h3>
                    <h3>{this.state.comment}</h3>
                </div>
            }
        })
        React.render(<BindingExample></BindingExample>, document.body);
    </script>
</body>
</html>

效果图(没有CSS样式,有点不优雅,见谅):

图片 7

更多学习demo已上传至:

参考资料:

《React引领未来的用户界面开发框架》

极客学院视频课程

打赏支持我写出更多好文章,谢谢!

打赏作者

webpack 4正式发布,速度最高可提升98%

2018/02/27 · CSS

原文出处: Sean T. Larkin   译文出处:众成翻译/怡红公子   

一、变量的声明

声明变量的时候,变量名前面要加两根连词线(--)。

CSS

body { --foo: #7F583F; --bar: #F7EFD2; }

1
2
3
4
body {
  --foo: #7F583F;
  --bar: #F7EFD2;
}

上面代码中,body选择器里面声明了两个变量:--foo--bar

它们与colorfont-size等正式属性没有什么不同,只是没有默认含义。所以 CSS 变量(CSS variable)又叫做“CSS 自定义属性”(CSS custom properties)。因为变量与自定义的 CSS 属性其实是一回事。

你可能会问,为什么选择两根连词线(--)表示变量?因为$foo被 Sass 用掉了,@foo被 Less 用掉了。为了不产生冲突,官方的 CSS 变量就改用两根连词线了。

各种值都可以放入 CSS 变量。

CSS

:root{ --main-color: #4d4e53; --main-bg: rgb(255, 255, 255); --logo-border-color: rebeccapurple; --header-height: 68px; --content-padding: 10px 20px; --base-line-height: 1.428571429; --transition-duration: .35s; --external-link: "external link"; --margin-top: calc(2vh + 20px); }

1
2
3
4
5
6
7
8
9
10
11
12
13
:root{
  --main-color: #4d4e53;
  --main-bg: rgb(255, 255, 255);
  --logo-border-color: rebeccapurple;
 
  --header-height: 68px;
  --content-padding: 10px 20px;
 
  --base-line-height: 1.428571429;
  --transition-duration: .35s;
  --external-link: "external link";
  --margin-top: calc(2vh + 20px);
}

变量名大小写敏感,--header-color--Header-Color是两个不同变量。

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

图片 8 图片 9

1 赞 3 收藏 评论

代号: _Legato

今天我们愉快的宣布 webpack 4(Legato)正式发布了!你可以使用 yarn 或者 npm 获得它:

JavaScript

$> yarn add webpack --dev

1
$> yarn add webpack --dev

或者

JavaScript

$> npm i webpack --save-dev

1
$> npm i webpack --save-dev

二、var() 函数

var()函数用于读取变量。

CSS

a { color: var(--foo); text-decoration-color: var(--bar); }

1
2
3
4
a {
  color: var(--foo);
  text-decoration-color: var(--bar);
}

var()函数还可以使用第二个参数,表示变量的默认值。如果该变量不存在,就会使用这个默认值。

CSS

color: var(--foo, #7F583F);

1
color: var(--foo, #7F583F);

第二个参数不处理内部的逗号或空格,都视作参数的一部分。

CSS

var(--font-stack, "Roboto", "Helvetica"); var(--pad, 10px 15px 20px);

1
2
var(--font-stack, "Roboto", "Helvetica");
var(--pad, 10px 15px 20px);

var()函数还可以用在变量的声明。

CSS

:root { --primary-color: red; --logo-text: var(--primary-color); }

1
2
3
4
:root {
  --primary-color: red;
  --logo-text: var(--primary-color);
}

注意,变量值只能用作属性值,不能用作属性名。

CSS

.foo { --side: margin-top; /* 无效 */ var(--side): 20px; }

1
2
3
4
5
.foo {
  --side: margin-top;
  /* 无效 */
  var(--side): 20px;
}

上面代码中,变量--side用作属性名,这是无效的。

关于作者:winty

图片 10

前端工程师,前端爱好者。博客: 个人主页 · 我的文章 · 1 ·  

图片 11

为什么叫 Legato?

首先我们会开始一个新传统:为我们以后的每个大版本设定代号!因此,我们决定将命名这个特权给予我们最大的 OpenCollective 捐赠者:trivago

当我们向其发出请求后他们是这么回复我们的:

[在 trivago] 我们通常以音乐主题来命名我们的项目。例如,我们之前的 JS 框架叫 “Harmony”,我们的新框架叫“Melody”。PHP 的话我们使用基于 Symfony 上层封装,我们叫它“Orchestra”。 Legato 意味着毫无间隙地连续演奏每个节奏。 这点和 Webpack 很像,Webpack 将我们的前端资源(JS,CSS甚至更多)无间隙的打包在一起。因此我们相信 “Legato” 这个代号会适合 Webpack。 ——  Patrick Gotthardt

我们得知后也非常地激动,因为新版 Webpack 中我们所做的每一个更新目的都在于此,为了当大家在使用 Webpack 的时候敏捷连续毫无顿挫感。非常感谢过去的这些年 trivago 对 webpack 的无私捐赠支持,更感谢其为 webpack 4 命名!

引申阅读:trivago 帮助保护 webpack 的未来

三、变量值的类型

如果变量值是一个字符串,可以与其他字符串拼接。

CSS

--bar: 'hello'; --foo: var(--bar)' world';

1
2
--bar: 'hello';
--foo: var(--bar)' world';

利用这一点,可以 debug(例子)。

CSS

body:after { content: '--screen-category : 'var(--screen-category); }

1
2
3
body:after {
  content: '--screen-category : 'var(--screen-category);
}

如果变量值是数值,不能与数值单位直接连用。

CSS

.foo { --gap: 20; /* 无效 */ margin-top: var(--gap)px; }

1
2
3
4
5
.foo {
  --gap: 20;
  /* 无效 */
  margin-top: var(--gap)px;
}

上面代码中,数值与单位直接写在一起,这是无效的。必须使用calc()函数,将它们连接。

CSS

.foo { --gap: 20; margin-top: calc(var(--gap) * 1px); }

1
2
3
4
.foo {
  --gap: 20;
  margin-top: calc(var(--gap) * 1px);
}

如果变量值带有单位,就不能写成字符串。

CSS

/* 无效 */ .foo { --foo: '20px'; font-size: var(--foo); } /* 有效 */ .foo { --foo: 20px; font-size: var(--foo); }

1
2
3
4
5
6
7
8
9
10
11
/* 无效 */
.foo {
  --foo: '20px';
  font-size: var(--foo);
}
 
/* 有效 */
.foo {
  --foo: 20px;
  font-size: var(--foo);
}

️‍ 有什么更新?

webpack 4 有太多的新东西可以说了,但是我不可能在本文中列举所有的内容,否则这篇文章就要推迟很久才能发布了。因此下面我会和大家分享一些我觉得有趣的更新内容,如果大家想要看所有的更新的话可以查阅 webpack 4 的更新日志

四、作用域

同一个 CSS 变量,可以在多个选择器内声明。读取的时候,优先级最高的声明生效。这与 CSS 的”层叠”(cascade)规则是一致的。

下面是一个例子。

蓝色

绿色

红色

上面代码中,三个选择器都声明了--color变量。不同元素读取这个变量的时候,会采用优先级最高的规则,因此三段文字的颜色是不一样的。

这就是说,变量的作用域就是它所在的选择器的有效范围。

CSS

body { --foo: #7F583F; } .content { --bar: #F7EFD2; }

1
2
3
4
5
6
7
body {
  --foo: #7F583F;
}
 
.content {
  --bar: #F7EFD2;
}

上面代码中,变量--foo的作用域是body选择器的生效范围,--bar的作用域是.content选择器的生效范围。

由于这个原因,全局的变量通常放在根元素:root里面,确保任何选择器都可以读取它们。

CSS

:root { --main-color: #06c; }

1
2
3
:root {
  --main-color: #06c;
}

webpack 4 更快(速度提升98%)!

我们在社区中请求大家对 webpack 4 进行构建性能测试,得出的结果非常有趣。结果很惊人,构建时间降低了 60%-98%!!这里给大家分享一下某个用户的测试结果:

图片 12

图片 13

来源: Twitter

当然这只是一部分用户的测试数据,你可以在我的推文的回复中查看他们所有的结果。

性能测试过程中也发现了一些 loader 的 bug 我们已经及时修复了!!PS: 我们还没有实现多进程,或者缓存功能(计划在v5版实现)。所以理论上我们的性能还有非常大的提升空间!!!!

构件速度是我们此次发布最主要的目标。你可以把所有的功能都添加到工具中,但是如果不能节省开发时间那你加这些功能又有什么用呢?当然以上的这些都是部分示例,我们非常欢迎大家在推特上使用 #webpack #webpack4 开头提交你们的构建时间报告。

五、响应式布局

CSS 是动态的,页面的任何变化,都会导致采用的规则变化。

利用这个特点,可以在响应式布局的media命令里面声明变量,使得不同的屏幕宽度有不同的变量值。

CSS

body { --primary: #7F583F; --secondary: #F7EFD2; } a { color: var(--primary); text-decoration-color: var(--secondary); } @media screen and (min-width: 768px) { body { --primary: #F7EFD2; --secondary: #7F583F; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
body {
  --primary: #7F583F;
  --secondary: #F7EFD2;
}
 
a {
  color: var(--primary);
  text-decoration-color: var(--secondary);
}
 
@media screen and (min-width: 768px) {
  body {
    --primary:  #F7EFD2;
    --secondary: #7F583F;
  }
}

Mode, 零配置以及默认值

我们为 webpack 新增了一个 mode 配置项。Mode 有两个值:development 或者是 production,默认值是 production。Mode 是我们为减小生产环境构建体积以及节约开发环境的构建时间提供的一种优化方案。

如果想要了解更多 mode 配置项的内容,大家可以看看我们之前的一篇文章: webpack 4: mode 和优化

另外,entryoutput 这些配置项也都有默认值了。这意味着你不需要每次都配置它们了,当然包括 mode。这可能意味着从现在开始,你的配置文件在我们做出如此巨大改变之后会变得非常小!

Legato 意味着毫无间隙地连续演奏每个节奏。

另外,我们提供零配置平台来扩展。webpack 最大的一个特色就是可扩展性。最终我们实现的零配置平台会是什么样子呢?当我们实现了 webpack presets 功能后,这意味着你可以基于零配置平台配置你自己,公司,甚至是社区的工作流配置用以继承直接使用。

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:4正式发布,变量教程

上一篇:别责怪框架,性能优化大挑战 下一篇:没有了
猜你喜欢
热门排行
精彩图文