学习文档
一、sass
*1.1 sass*
Sass (英文全称:Syntactically Awesome Stylesheets) 是一个最初由 Hampton Catlin 设计并由 Natalie Weizenbaum 开发的层叠样式表语言。
Sass 是一个 CSS 预处理器。
Sass 是 CSS 扩展语言,可以帮助我们减少 CSS 重复的代码,节省开发时间。
Sass 完全兼容所有版本的 CSS。
Sass 扩展了 CSS3,增加了规则、变量、混入、选择器、继承、内置函数等等特性。
Sass 生成良好格式化的 CSS 代码,易于组织和维护。
Sass 文件后缀为 .scss。
*1.2 sass的优势*
CSS 本身语法不够强大,导致重复编写一些代码,无法实现复用,而且在代码也不方便维护。
Sass 引入合理的样式复用机制,增加了规则、变量、混入、选择器、继承、内置函数等等特性。
*1.3 sass变量*
$min-width:1226px; //容器安全区域宽度
// 常规字体大小设置
$fontA: 80px; //产品站大标题
$fontB: 38px; //产品站标题
$fontC: 28px; //导航标题
$fontD: 26px; //产品站副标题
$fontE: 24px;
$fontF: 22px;
$fontG: 20px; //用在较为重要的文字、操作按钮
$fontH: 18px; //用于大多数文字
$fontI: 16px; //用于辅助性文字
$fontJ: 14px; //用于一般文字
$fontK: 12px; //系统默认大小
// 常规配色设置
$colorA: #1685a9 !default; //用于需要突出和强调的文字、按钮和icon
$colorB: #333333 !default; //用于较为重要的文字信息、内页标题等
$colorC: #666666 !default; //用于普通段落信息 引导词
$colorD: #999999 !default; //用于辅助、次要的文字信息、普通按钮的描边
$colorE: #cccccc !default; //用于特别弱的文字
$colorF: #d7d7d7 !default; //用于列表分割线、标签秒变
$colorG: #ffffff !default; //用于导航栏文字、按钮文字、白色背景
$colorH: #e5e5e5 !default; //用于上下模块分割线
$colorI: #000000 !default; //纯黑色背景,用于遮罩层
$colorJ: #F5F5F5 !default; //弹框标题背景色
$colorK: #FFFAF7 !default; //订单标题背景色
变量可以重复使用,适用于颜色、字体大小统一管理,需要修改时只需把定义的变量改变即可
*1.4 sass嵌套*
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
以上代码对应的css代码为:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
减少了重复代码的编写,嵌套结构一目了然
*1.5 sass @mixin 与 @include*
mixin.scss:
@mixin flex($hov:space-between,$col:center) {
display: flex;
justify-content: $hov;
align-items: $col;
}
定义了一个可重复使用的样式,通过传入的变量改变样式,未传入变量使用默认值
app.scss:
@import "../assets/scss/mixin.scss";
.ads-box {
@include flex();
margin-top: 14px;
margin-bottom: 31px;
a {
width: 296px;
height: 167px;
}
}
@import+文件地址,然后在需要使用的样式内@include导入即可
二、ES6代码语法规范
*2.1 ES6*
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,在 2015 年 6 月正式发布。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。日常场合,这两个词是可以互换的。
*2.2 babel转码器*
Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在老版本的浏览器执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持。
*2.3 let和const*
let命令
ES6 新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined
。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。let
不允许在相同作用域内,重复声明同一个变量。
const命令
const
声明一个只读的常量。一旦声明,常量的值就不能改变,这意味着,const
一旦声明变量,就必须立即初始化,不能留到以后赋值。
对于复合类型的数据只能保证所指向的那个地址不变,地址内的数据结构和数据完全不能控制。
在我们开发的时候,可能认为应该默认使用 let 而不是 var,这种情况下,对于需要写保护的变量要使用 const。
然而另一种做法日益普及:默认使用 const,只有当确实需要改变变量的值的时候才使用 let。这是因为大部分的变量的值在初始化后不应再改变,而预料之外的变量的修改是很多 bug 的源头。
暂时性死区
let
和const
命令并不是阻止了变量的提升,而是通过暂时性死区改变。只要块级作用域内存在let
、const
命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
对于ES6更多内容可以访问阮一峰老师的ES6入门教程
三、node.js和MongoDB
*3.1 node.js*
简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
*3.2 koa*
koa是基于node.js平台的下一代web开发框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,快速而愉快地编写服务端应用程序。
import koa from 'koa' //导入koa
import Router from 'koa-router' //导入koa-router路由中间件
import cors from '@koa/cors' //导入@koa/cors后端解决跨域问题
import koaBody from 'koa-body' //导入koa-body支持post方法和文件上传
import json from 'koa-json' //导入koa-json 参数转为json
let app = new koa()
let router = new Router()
router.get('/',async (ctx) => {
ctx.body = '首页' //返回值为字符串‘首页’
})
app.use(koaBody({multipart: true}))
app.use(cors())
app.use(json({pretty: false, param: 'pretty' }))
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000) //服务启动端口为3000
因为import 和异步async/await属于ES6语法,所以需要babel-node才能运行,配置方法-babel-node
*3.3 MongoDB*
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
*3.4 mongoose*
Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具,Mongoose为模型提供了一种直接的,基于scheme结构去定义你的数据模型。它内置数据验证, 查询构建,业务逻辑钩子等,开箱即用。
Schema
: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力,每个schema
都会映射到一个MongoDBcollection
,并定义这个collection
里的文档的构成。Model
: 由Schema
发布生成的模型,具有抽象属性和行为的数据库操作对,基本文档数据的父类,通过集成Schema定义的基本方法和属性得到相关的内容。Entity
: 由Model
创建的实体,他的操作也会影响数据库
DBHelper.JS
import mongoose from 'mongoose'
const DB_url = 'mongodb://localhost:27017/dbUser'
mongoose.connect(DB_url,{
useNewUrlParser:true,
useUnifiedTopology:true
}) //mongoose与数据库建立连接
mongoose.connection.on('connected',()=>{
console.log('连接成功')
})
export default mongoose //将mongoose暴露出去可供别的js使用
user.js
import mongoose from '../config/DBHelper'
const Schema = mongoose.Schema //创建schema
const userSchema = new Schema({
'username':{ type: String },
'password': { type: String }
})
const userModel = mongoose.model('User', userSchema) //创建一个model,通过这个可以操作数据库
export default userModel
*3.5 koa与mongoose结合使用*
import koa from 'koa' //导入koa
import Router from 'koa-router' //导入koa-router路由中间件
import cors from '@koa/cors' //导入@koa/cors后端解决跨域问题
import koaBody from 'koa-body' //导入koa-body支持post方法和文件上传
import json from 'koa-json' //导入koa-json 参数转为json
import user from '../model/user.js' //导入user.js
let app = new koa()
let router = new Router()
router.get('/',async (ctx) => {
ctx.body = '首页' //返回值为字符串‘首页’
})
router.get('/login',async (ctx) => {
const req = ctx.request.query //获取前端传来的参数
const body =await user.find({username:req.username}) //此时body为user集合内的username为前端参数传来的username相同的数据
if(body.length!=0 && body[0].password == req.password){ //如果body内有数据并且password相同返回200,不相同返回400
ctx.body = {
code: 200,
msg: 'success'
}
}else{
ctx.body = {
code:400,
msg:'failed'
}
}
})
app.use(koaBody({multipart: true}))
app.use(cors())
app.use(json({pretty: false, param: 'pretty' }))
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000) //服务启动端口为3000
四、前端工程化
前端工程化是使用软件工程的技术和方法来进行前端的开发流程、技术、工具、经验等规范化、标准化,其主要目的为了提高效率和降低成本,即提高开发过程中的开发效率,减少不必要的重复工作时间。前端工程化就是为了让前端开发能够“自成体系”,主要应该从模块化、组件化、规范化、自动化四个方面思考
*4.1 模块化*
简单来说,模块化就是将一个大文件拆分成相互依赖的小文件,再进行统一的拼装和加载
js的模块化
历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require
、Python 的import
,甚至就连 CSS 都有@import
,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
在 ES6 之前,社区制定了一些模块加载方案,最主要的有CommonJS
和 AMD
两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS
和 AMD
规范,成为浏览器和服务器通用的模块解决方案。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS
和AMD
模块,都只能在运行时确定这些东西。比如,CommonJS
模块就是对象,输入时必须查找对象属性。
可以使用Webpack
+ Babel
将所有模块打包成一个文件同步加载,也可以搭乘多个chunk异步加载
css的模块化
虽然SASS、LESS、Stylus等预处理器实现了CSS的文件拆分,但没有解决CSS模块化的一个重要问题:选择器的全局污染问题。
按道理,一个模块化的文件应该要隐藏内部作用域,只暴露少量接口给使用者。而按照目前预处理器的方式,导入一个CSS模块后,已存在的样式有被覆盖的风险。虽然重写样式是CSS的一个优势,但这并不利于多人协作。
为了避免全局选择器的冲突,需要制定CSS命名风格,但是,
与其费尽心思地告诉别人要遵守某种规则,以规避某种痛苦,倒不如从工具层面就消灭这种痛苦。
从工具层面,社区又创造出Shadow DOM、CSS in JS和CSS Modules三种解决方案。
- Shadow DOM是WebComponents的标准。它能解决全局污染问题,但目前很多浏览器不兼容,对我们来说还很久远;
- CSS in JS是彻底抛弃CSS,使用JS或JSON来写样式。这种方法很激进,不能利用现有的CSS技术,而且处理伪类等问题比较困难;
- CSS Modules仍然使用CSS,只是让JS来管理依赖。它能够最大化地结合CSS生态和JS模块化能力,目前来看是最好的解决方案。Vue的scoped style也算是一种。
*4.2 组件化*
从UI拆分下来的每个包含模板(HTML)+样式(CSS)+逻辑(JS)功能完备的结构单元,我们称之为组件。
组件化≠模块化。模块化只是在文件层面上,对代码或资源的拆分;而组件化是在设计层面上,对UI(用户界面)的拆分。
页面上所有的东西都是组件。页面是个大型组件,可以拆成若干个中型组件,然后中型组件还可以再拆,拆成若干个小型组件,小型组件也可以再拆,直到拆成DOM元素为止。DOM元素可以看成是浏览器自身的组件,作为组件的基本单元。
目前市面上的组件化框架很多,主要的有Vue、React、Angular。Vue文档中的对比其他框架一文已经讲得很详细了。
*4.3 规范化*
规范化其实是工程化中很重要的一个部分,项目初期规范制定的好坏会直接影响到后期的开发质量。
比如:
目录结构的制定,传统的开发概念一般是按照文件类型划分的,所以传统前端项目会有这样的目录结构:
-
js:放js文件
-
css:放css文件
-
images:放图片文件
-
html:放html文件
这样确实很直接,但是这样的开发概念划分将给项目带来较高的维护成本,并为项目臃肿埋下了工程隐患,理由是:如果项目中的一个功能有了问题,维护的时候要在js目录下找到对应的逻辑修改,再到css目录下找到对应的样式文件修改一下,如果图片不对,还要再跑到images目录下找对应的开发资源。
images下的文件不知道哪些图片在用,哪些已经废弃了,谁也不敢删除,文件越来越多。
ps: 除非你的团队只有1-2个人,你的项目只有很少的代码量,而且不用关心性能和未来的维护问题,否则,以文件为依据设计的开发概念是应该被抛弃的。可以为这个开发体系确定了3个开发资源概念:
模块化资源:js模块、css模块或组件
页面资源:网站html或后端模板页面,引用模块化框架,加载模块
非模块化资源:并不是所有的开发资源都是模块化的,比如提供模块化框架的js本身就不能是一个模块化的js文件。严格上讲,页面也属于一种非模块化的静态资源。
ps: 开发概念越简单越好,有组件或模块(widget),页面(page),测试数据(test),非模块化静态资源(static)。有的团队在模块之中又划分出api模块和ui模块(组件)两种概念
还有编码规范、文档规范、组件管理等
*4.4 自动化*
任何简单机械的重复的劳动应该交给机器去完成,在前端有很多自动化的工具,比如:webpack
、Grunt
、Gulp
脚手架
百度百科对于”脚手架“的定义为:是为了保证各施工过程顺利进行而搭建的工作平台
所谓脚手架其实就是帮助我们快速搭建项目的工具,通常只需要跑一个命令就可以帮助我们生成一个项目,让用户不需要再思考项目的目录结构,单元测试,所需要的依赖等繁琐的事情。通过脚手架,由“程序员手写代码”时代跨越到了“程序员指挥机器自动生成代码”时代。