一、sass插件的安装:gulp-sass-china
1.安装插件
npm install gulp-sass-china
2.引入插件模块
let sass = require("gulp-sass-china");
3.定义指令
gulp.task("sass",()=>{
return gulp.src("sass/*.scss")
.pipe(sass().on("error",sass.logError))
.pipe(gulp.dest("css"))
.pipe(connect.reload());
})
4.监听文件更改
gulp.task("watch",()=>{
gulp.watch("sass/*.scss",["sass"])
})
gulp-sass-china文档参考:
https://www.npmjs.com/package/gulp-sass-china
二、sass介绍
sass是一种高效css编译模式,目前这种高效的css编译方式有两种:sass/less
sass基于ruby语言,特点是没有大括号,换行需要用缩进表示,非常难受
后来sass开发了两种后缀名文件:一种后缀名为sass,不使用大括号和分号
另一种就是我们这里使用的scss文件,这种和我们平时写的css文件格式差不多,使用大括号和分号
本节课所有sass文件都指后缀名为scss的文件。在此也建议使用后缀名为scss的文件,以避免sass后缀名的严格格式要求报错。
sass是需要编译的,sass不能直接用于页面。它可以极大地提高编程效率(对于使用熟练的人来说)。
sass想要应用在项目中需要编译成css文件。这里使用gulp插件进行编译(gulp-sass-china)
三、sass语法
变量
必须以$开头, 后面加上!default那就代表这个是当前变量的默认值。
$font-size:16px;
div{
font-size: $font-size;
}
复杂变量的使用
KaTeX parse error: Expected 'EOF', got '#' at position 11: linkColor:#̲b6b6b6 #ddd!def…linkColor,1);
&:hover{
color:nth($linkColor,2);
}
}
nth()方法,第一个参数为复杂变量,第二个参数为复杂变量的第几个值,从1开始数
一般我们都将变量当做属性值来使用,但是也有极特殊情况下我们会将变量当做class里的类来使用。
这时候,我们必须以#{$name}的方式来使用变量名;
$name:top !default;
.class-#{$name}{
border-#{name}:1px solid #b6b6b6;
}
多值变量:map 和 list(复杂变量)
多值变量代表的是多维数据的存储方式,换句话说,list相当于js中的数组map相当于js中的对象。 list数据一般用空格分割, 但是也可以用 逗号 或者小括号分割多个值。
list:
$list:(20px 40px)(30px 20px)(40px 30px);//相当于多维数组,其他格式同理;
$list:20px 30px 40px 50px 60px;
$list:20px,30px,40px,50px,60px;
使用:对于list的使用,可以使用 nth($list,num)去调用;
当然我们还可以去使用其他方式;
length($list) 返回list的长度
nth($list, $n) 返回索引的项目
set-nth($list, $n, $value) 设置list中第n个的值
join($list1, $list2, [$separator]) 将两个列表链接在一起
append($list1, $val, [$separator]) 追加一个值到列表最后
zip($lists…) 将几个列表组合成多维列表
index($list, $value) 返回一个列表中值的位置
$list:(top 20px 30px) (left 40px 50px) (right 60px 70px);
@each $name,$width,$height in $list{
.box-#{$name}{
width:$width;
height:$height;
}
}
map:
map的数据是以键值对形式出现的,期中value可以是list。格式为
$map:(key1:value1, key2:value2, key3:value3)。
最常用的取值方法就是用map-get($map,$key) 进行取值
关于map还有很多函数:
map-get($map, $key) 返回key值;
map-merge($map1, $map2) 合并两个$map;
map-remove($map, $keys…) 删除某个value并返回value值;
map-keys($map) 以list形式返回所有$map 的key;
map-values($map) 以list形式返回所有$map中的value;
map-has-key($map, $key) 查看当前的$map是否有这个key
keywords($args) 返回一个关键字
$headers:(h1:20px,h2:30px,h3:40px);
@each $key, $value in $headers{
#{$key}{
font-size: $value;
}
}
这里的each用法那和我们js中的for-in用法基本一致,只不过写法不同。
$key 相当于for-in中的变量,$value 相当于for-in中的obj[i];
嵌套
sass可以进行选择器的嵌套,表示层级关
选择器嵌套:
ul{
li{
list-style: none;
color:nth($linkColor,1);
}
}
属性嵌套:
.class{
border:{
style:solid;
left:none;
right:1px;
color:#b6b6b6;
}
}
@at-root(不推荐使用)
跳出当前选择器嵌套。
.class{
color:f10;
.child{
width:100px;
}
}
.class2{
@at-root .child{
color:#b6b6b6;
}
}
@at-root (without: …) 和 @at-root (with: …)
默认@at-root只会跳出选择器嵌套,而不能跳出@media或@support
如果要跳出这两种,则需使用@at-root (without: media),@at-root (without: support)。
这个语法的关键词有四个:
all(表示所有)
rule(表示常规css)
media(表示media)
support(表示support,因为@support目前还无法广泛使用,所以对其忽略)。
我们默认的@at-root其实就是@at-root (without:rule)。
@media screen and (max-width:641px){
.parent{
color:#b6b6b6;
@at-root .child{
width:100px;
}
}
}
在这里.child只会跳出.parent 和.parent类作为同级,而不会跳出@media 那么我们如何让他跳出@media那?
@media screen and (max-width:641px){
.parent{
color:#b6b6b6;
@at-root (without:media) {
.child{
width:100px;
}
}
}
}
这种编译模式会将我们的css编译成
@media screen and (max-width: 641px) {
.parent {
color: #b6b6b6;
}
}
.parent .child {
width: 100px;
}
也就是说,这时候我们的 .child 带着他的父级跳出了media嵌套。
@media screen and (max-width:641px){
.parent{
color:#b6b6b6;
@at-root (without:all) {
.child{
width:100px;
}
}
}
}
和刚才的执行结果有稍微的一点差异,变成了这个样子;
@media screen and (max-width: 641px) {
.parent {
color: #b6b6b6;
}
}
.child {
width: 100px;
}
注意:这次的跳出是不带父级的。
小技巧:@at-root 其实有很多的组合配合,和 &配合可以改变css的从属关系;
.parent{
@at-root .child &{
color:#b6b6b6;
}
}
@mixin
mixin(混合)
sass中使用@mixin声明混合,可以传递参数,参数名以$符号开始,多个参数以逗号分开,也可以给参数设置默认值。声明的@mixin通过@include来调用。
sass中可用mixin定义一些代码片段,且可传参数,方便日后根据需求调用。从此处理css3的前缀兼容轻松便捷。
无参数 mixin
@mixin marginCenter{
margin-left:auto;
margin-right:auto;
}
.cont{
@include marginCenter;
}
有参数 mixin
1)必须传参数的应用
@mixin transform($type){
-webkit-transform: $type;
-moz-transform: $type;
-ms-transform: $type;
-o-transform: $type;
transform: $type;
}
.box{
@include transform(scale(1.2))
}
2)设置默认情况的mixin(当你不传入参数直接使用的话那会调用默认值)
@mixin opacity($opacity:50){
opacity: $opacity/100;
filter:alpha(opacity=$opacity)
}
.box{
@include opacity()
}
多个参数 mixin
调用时可直接传入值,如@include传入参数的个数小于@mixin定义参数的个数,则按照顺序表示,后面不足的使用默认值,如不足的没有默认值则报错。除此之外还可以选择性的传入参数,使用参数名与值同时传入。
@mixin line($border:1px border #ccc, KaTeX parse error: Expected '}', got 'EOF' at end of input: … border-bottom:border;
padding-top:
p
a
d
d
i
n
g
;
p
a
d
d
i
n
g
−
b
o
t
t
o
m
:
padding; padding-bottom:
padding;padding−bottom:padding;
}
.list ul{
@include line(1px solid #ccc);
}
.list p{
@include line($padding:15px);
}
多组值参数mixin
一个参数可以有多组值,如box-shadow、transition等,那么需要在参数后加三个点表示,如
s
h
a
d
o
w
.
.
.
@
m
i
x
i
n
b
o
x
−
s
h
a
d
o
w
(
shadow... @mixin box-shadow(
shadow...@mixinbox−shadow(shadow…) {
-webkit-box-shadow:
s
h
a
d
o
w
;
b
o
x
−
s
h
a
d
o
w
:
shadow; box-shadow:
shadow;box−shadow:shadow;
}
.box{
border:1px solid #ccc;
@include box-shadow(0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3));
}
扩展/继承
sass可通过@extend来实现代码组合声明,使代码更加优越简洁。
.active{
border:1px solid #b6b6b6;
padding:10px;
color: #333;
}
.success{
@extend .active;
width:100px;
}
运算
sass可进行简单的加减乘除运算等,当我们拿到一张需要转换成百分比或rem布局的设计稿,这时候我们有福了
.container{
width: 100%;
}
//百分比
.aside{
width:(600px/960px)*100%;
}
//rem
.article{
width:(300px/960px)*1rem;
}
函数
sass定义了很多函数可供使用,当然你也可以自己定义函数,以@fuction开始。
实际项目中我们使用最多的应该是颜色函数,而颜色函数中又以lighten减淡和darken加深为最,其调用方法为lighten(
c
o
l
o
r
,
color,
color,amount)和darken(
c
o
l
o
r
,
color,
color,amount),它们的第一个参数都是颜色值,第二个参数都是百分比。
$baseFontSize:10px;
$gray:#ccc;
@function pxToRem($px){
@return ($px/$baseFontSize)*1rem;
}
body{
font-size:$baseFontSize;
color:lighten($gray,10%);
}
.test{
font-size:pxToRem(16px);
color:darken($gray,10%);
}
这个和我们JS中的函数那非常的相似,可以和我们js中的函数一样使用。
同时注意,这里的返回值几乎是必须的所以请在每个函数结束时,使用@return去返回需要的返回值。
拓展部分:
@if判断
@if可一个条件单独使用,也可以和@else结合多条件使用
$lte7: true;
$type: monster;
.ib{
display:inline-block;
@if $lte7 {
*display:inline;
*zoom:1;
}
}
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
三目判断
语法为:if($condition, $if_true, $if_false) 。三个参数分别表示:条件,条件为真的值,条件为假的值。
if(true, 1px, 2px) => 1px
if(false, 1px, 2px) => 2px
for循环***
for循环有两种形式,分别为:@for $var from through 和@for v a r f r o m < s t a r t > t o < e n d > 。 var from <start> to <end>。 varfrom<start>to<end>。i表示变量,start表示起始值,end表示结束值,这两个的区别是关键字through表示包括end这个数,而to则不包括end这个数。
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
@each循环
语法为:@each v a r i n < l i s t o r m a p > 。 其 中 var in <list or map>。其中 varin<listormap>。其中var表示变量,而list和map表示list类型数据和map类型数据。
$animal-list: puma, sea-slug, egret, salamander;
@each $animal in KaTeX parse error: Expected '}', got '#' at position 18: …imal-list { .#̲{animal}-icon {
background-image: url(’/images/#{$animal}.png’);
}
}
sass中如导入其他sass文件,最后编译为一个css文件,优于纯css的@import
@import “reset”;
==========================================
一、什么是模块化
是一种项目的构架模式, 这种构架模式让JS代码重用性变得非常高,让项目构架的一些复杂问题全部得以解决。 例如,多个script标签不会再出现了,我们只要用一个script标签进行引入就可以了。
为了减少系统耦合度,提高内聚,减少资源依赖
便于维护,功能复用性更强
解决独立作用域、依赖管理、api暴露、按需加载与执行、安全合并等问题
二、模块化规范
模块化有三个规范,AMD规范和CMD规范,当然还有针对于ndoejs后台的commonJS规范
AMD 异步模块定义=>主要负责前端的模块化实现=>require.js
依赖前置 => 如果你有,我就加载
CMD 需求加载,创始人是玉伯,=> seajs
CommonJs => NodeJs规范 => 用来写后台的
这些规范目标一致都是为项目实现模块化,期中有遵循AMD规范的 require.js 和遵循CMD规范的sea.js。
先说这两种规范的不同:
1.首先对于依赖:
AMD提前执行(不管有没有用,先加载过来) //特点 : 前期消耗网络资源大, 但是后期运行效率高.
CMD需求执行(有用我再去加载) //特点:整个自选消耗曲线比较平缓。
2. CMD 推崇依赖就近,AMD 推崇依赖前置。
3. AMD 的 API 默认是一个当多个用。比如,require 分全局 require 和局部 require,都叫 require。
http://www.ruanyifeng.com/blog/2012/11/require_js.html?bsh_bid=230697246
三、AMD模块化
定义模块defined():(module.js)
defined(["otherModule"],function(){
...
...
return {};
})
加载模块require():(main.js)
require(["module"],function(moduleObj){
//模块加载完成后执行
...
})
四、ES6模块化
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
ES6模块的使用:
使用export规定模块的对外接口,使用import用于输入其他模块提供的功能
定义模块export语法:(module.js文件)
export var a = 10;
var b = 20;
export {b};
var c = "admin"
export {c as name};
||
export {a,b,c};
export {a as num1, b as num2, c as name};
export default {num1:a, num2:b, name:c}
加载模块import语法:(main.js文件)
import {a} from "./module.js";
import {b} from "./module.js";
import {c} from "./module.js";
import {a,b,c} from "./module.js";
import {num1,num2,num3} from "./module.js”;
||
import {num1 as n1, num2 as n2, num3 as n3} from "./module.js";
import obj from "./module.js";
注意:1.export和import关键字,只能存在于顶层作用域内,不能存在局部或块级作用域
2.在ES6的模块化中,所有语法自动处在严格模式下
3.export是声明关键字,声明一个对外接口
4.export声明的接口必须和模块内部的变量建立一一对应的关系
5.export声明的接口与对应的值是动态绑定,即可以拿到模块内部实时修改的值
5.export和import时,都可以使用as关键字,重命名接口
6.使用default关键字,设置默认接口,一个模块中只允许出现一次default
7.import在使用接口时,必须将接口放在花括号内,除非export暴露接口时使用了default关键字
8.import加载的接口是只读的,不允许被修改,如果接口是对象,可以修改属性
9.import具有提升效果
10.由于import是静态执行,所以不能使用表达式和变量
11.当import后没有接收接口,会执行整个模块文件
12.可以使用通配符*加载整个模块的接口(需要配合as使用),返回一个模块对象
13.ES6的模块化不是对象,而是通过export输出对应的代码,再通过import输入
14.import加载模块的输入接口是静态加载,指定接口的情况下,只加载接口部分