HTML
一、行内元素与块级元素
区别
行内元素
- 与其他行内元素并排
- 不能设置宽高,默认的宽度就是文字的宽度
块级元素
- 霸占一行,不能与其他任何元素并列。
- 能接受宽高,如果不设置宽度,那么宽度将默认变为父级的100%。
分类
在HTML的角度来讲,标签分为:
- 文本级标签:p , span , a , b , i , u , em
- 容器级标签:div , h系列 , li , dt ,dd
p:里面只能放文字和图片和表单元素,p里面不能放h和ul,也不能放p。
从CSS的角度讲,CSS的分类和上面的很像,就p不一样:- 行内元素:除了p之外,所有的文本级标签,都是行内元素。p是个文本级标签,但是是个块级元素。
- 块级元素:所有的容器级标签,都是块级元素,以及p标签。
相互转换
块级元素(比如div)----> 行内元素
- display:inline;
行内元素(比如span)----> 块级元素
- display:block;
CSS
一、Flex布局
- display: flex; 将对象作为弹性伸缩盒展示,用于块级元素
- display: inline-flex; 将对象作为弹性伸缩盒展示,用于行内元素
六大属性
- flex-direction
指定Flex主轴的方向,继而决定 Flex子项在Flex容器中的位置
值 | 描述 |
---|---|
row | 默认值,表示水平方向从左到右排列,此时水平方向轴线为主轴 |
row-reverse | 与row相反 |
column | 表示垂直方向从上到下排列,此时垂直方向轴线为主轴 |
column-reverse | 与column相反 |
- flex-wrap
用于指定 Flex 子项是否换行
值 | 描述 |
---|---|
nowrap | 默认值,表示不换行,Flex子项可能会溢出 |
wrap | 表示换行,溢出的Flex子项会被放到下一行 |
wrap-reverse | 表示反方向换行 |
- flex-flow
复合属性,是 flex-direction 和 flex-wrap 的简写属性,是用于指定Flex子项的排列方式
- justify-content
用于指定主轴(水平方向)上Flex子项的对齐方式
值 | 描述 |
---|---|
flex-start | 默认值,表示与行的起始位置对齐 |
flex-end | 表示与行的结束位置对齐 |
center | 表示与行中间对齐 |
space-between | 表示两端对齐,中间间距相等 |
space-around | 表示间距相等,中间间距是两端间距的 2 倍 |
- align-items
用于指定侧轴(垂直方向)上Flex子项的对齐方式
值 | 描述 |
---|---|
stretch | 默认值,当Flex子项未设置高度或者高度值为auto时,stretch起作用,将Flex子项高度设置为行高度。在只有一行的情况下,行的高度为容器的高度,即Flex子项高度为容器的高度 |
flex-start | 表示与侧轴开始位置对齐 |
flex-end | 表示与侧轴的结束位置对齐 |
center | 表示与侧轴中间对其 |
baseline | 表示基线对齐,当行内轴与侧轴在同一线上。所有Flex子项的基线在同一线上时,效果等同于flex-start |
- align-content
该属性只作用于多行的情况下,用于多行的对齐方式,在只有一行的Flex容器上无效
值 | 描述 |
---|---|
stretch | 默认值,当Flex子项未设置高度或者高度值为auto时,stretch起作用,将Flex子项高度设置为行高度。 |
flex-start | 表示各行与侧轴开始位置对齐,第一行紧靠侧轴开始边界,之后的每一行都紧靠前面一行 |
flex-end | 表示各行与侧轴的结束位置对齐,最后一行紧靠侧轴结束边界,之后的每一行都紧靠前面一行 |
center | 表示各行与侧轴中间对其 |
space-between | 表示两端对齐,中间间距相等。要注意特殊情况,当剩余空间为负数时,效果等同于 flex-start |
space-around | 表示各行之间间距相等,中间间距是两端间距的2倍。要注意特殊情况,当剩余空间为负数时,效果等同于 center |
二、关于Scss和Less
Sass (Syntactically Awesome Stylesheets)是一种动态样式语言,Sass语法属于缩排语法,比css比多出好些功能(如变量、嵌套、运算,混入(Mixin)、继承、颜色处理,函数等),更容易阅读。
Sass 3 -> Scss
Less也是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量,继承,运算, 函数. Less 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可在服务端运行 (借助 Node.js)。
Scss和Less的区别
- 编译环境不一样
Sass的安装需要Ruby环境,是在服务端处理的,而Less是需要引入less.js来处理Less代码输出css到浏览器
- 变量符不一样
Less是@,而Scss是$,而且变量的作用域也不一样
- 输出设置不一样
Less没有输出设置,Sass提供4中输出选项:nested, compact, compressed 和 expanded
- Sass支持条件语句,可以使用if{}else{},for{}循环等等。而Less不支持
JS
一、js基本数据类型
- 五种基本数据类型(number,string,boolean,undefined,null)
- 一种复杂数据类型(object)。
- 三大引用类型(object,array,function)
二、HTTP状态码
常见状态码
- 200 - 请求成功
- 301 - 资源(网页等)被永久转移到其它URL
- 404 - 请求的资源(网页等)不存在
- 500 - 内部服务器错误
分类 | 描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
三、跨域问题
受浏览器同源策略的限制,本域的js不能操作其他域的页面对象(比如DOM)
解决跨域问题
- 使用JSONP跨域
原理:通过script标签引入的js不收同源策略的限制,而XmlHttpRequest 对象受到同源策略的影响,可以加载跨域服务器上的脚本,用 JSONP 获取的不是 JSON 数据,而是可以直接运行的 JavaScript 语句。
jsonp包含两个参数:回调函数和数据。
不能直接将 JSON 格式的 data 直接传给回调函数
方法
1、使用 jQuery 集成的 $.ajax 实现 JSONP 跨域调用
2、使用 《script》标签原生实现 JSONP
JSONP不足:
只能使用 GET 方法发起请求,不安全,这是由于 script 标签自身的限制决定的。
不能很好的发现错误,并进行处理。与 Ajax 对比,由于不是通过 XmlHttpRequest 进行传输,所以不能注册 success、 error 等事件监听函数。
- 使用 CORS 实现跨域调用
原理:CORS的思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 请求
四、Axios
- Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库
- react/vue 官方都推荐使用 axios 发 ajax 请求
axios 特点
- 基于 promise 的异步 ajax 请求库,支持promise所有的API
- 浏览器端 / node 端都可以使用,浏览器中创建XMLHttpRequests
- 支持请求/响应拦截器
- 支持请求取消
- 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
- 批量发送多个请求
- 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
axios相比原生ajax的优点
ajax的缺点
- 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
- 基于原生的XHR开发,XHR本身的架构不清晰。
- JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
- 不符合关注分离(Separation of Concerns)的原则
- 配置和调用方式非常混乱,而且基于事件的异步模型不友好。
五、箭头函数和普通函数
六、原型与原型链
原型:每个函数都有 prototype 属性,该属性指向原型对象;使⽤原型对象的好处是所有对象实例共享它所包含的属性和⽅法。
原型链:主要解决了继承的问题;每个对象都拥有⼀个原型对象,通过__proto__ 指针指向其原型对象,并从中继承⽅法和属性,同时原型对象也可能拥有原型,这样⼀层⼀层,最终指向 null。
_proto_
:隐式原型
Prototype
:显式原型
二者绝对相等
七、ES6新特性
八、事件循环
JavaScript是一门单线程的语言。意味着同一时间内只能做一件事,就会存在阻塞现象,实现单线程非阻塞的方法就是事件循环。
- 同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行。
- 异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等。异步任务还可以细分为微任务与宏任务。不同的任务源会被分配到不同的Task队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)。在ES6规范中,microtask称为jobs,macrotask称为task。
- 常见的宏任务:整体代码,setTimeout,setInterval,setImmediate,I/O操作,postMessage、MessageChannel,UI rendering/UI事件。
- 常见的微任务:new Promise().then,MutaionObserver(前端的回溯),Object.observe(已废弃;Proxy 对象替代),process.nextTick(Node.js)。
九、事件捕获和冒泡
- 事件
当一个HTML元素产生一个事件时,该事件会在元素节点与根节点之间的路径传播,路径所经过的节点都会收到该事件,这个传播的过程叫做DOM事件流
- 捕获
事件捕获会从 document 开始触发一级一级往下传递,依次触发,直到真正事件目标为止
- 冒泡
事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到 document 为止
闭包
函数(定义的位置)和它周围状态的引用捆绑
- 实例1(函数作为返回值)
function test(){
const a = 1;
return function(){
console.log("a" , a);
}
}
const a = 2;
const fn = test();
fn();// a , 1
// 在函数 定义 的位置的上一级寻找变量,而不是在函数执行的位置去寻找
- 实例2(函数作为参数)
function test(fn){
const a = 1;
fn();
}
const a = 2;
function fn(){
console.log("a" , a);
}
test(fn);// a , 2
// 在函数 定义 的位置的上一级寻找变量,而不是在函数执行的位置去寻找
Vue相关
一、v-for为什么要加key
1.可以简单的这样理解:加了key(一定要具有唯一性) id的checkbox跟内容进行了一个关联。是我们想达到的效果
2.没有key。vscode编辑器会报红下划线
3.可以这样简单地理解,无:key属性时,状态默认绑定的是位置;有:key属性时,状态根据key的属性值绑定到了相应的数组元素。
4.之所以要加上key是因为vue源码是内部数据驱动,通过改变数据进而达到改变视图的效果,加上key这样算法上容易定位到对应的元素,避免去遍历dom造成的性能的消耗
二、Vue组件间通信
- 父子关系的组件数据传递选择 props 与 $emit进行传递,也可选择ref
- 兄弟关系的组件数据传递可选择 $ bus,其次可以选择$parent进行传递
- 祖先与后代组件数据传递可选择attrs与listeners或者 Provide与 Inject
- 复杂关系的组件数据传递可以通过Vuex存放共享的变量
Vuex
Vuex 实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State的变化,渲染到视图上。
Vuex与SessionStorage:这个讲讲自己用的就行
三、Vue双向绑定的原理
- v-model是Vue中双向绑定的体现
- v-model实现双向绑定主要应用到了两个方法:v-bind:value、v-on:input
四、vue-router钩子函数
- 全局钩子
beforeEach 和 aftrEach
beforeEach函数有三个参数:
to:router即将进入的路由对象
from:当前导航即将离开的路由
next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
afterEach函数不用传next()函数
- 单个路由里面的钩子
beforeEnter 和 beforeLeave
主要用于写某个指定路由跳转时需要执行的逻辑
- 组件路由钩子
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
这几个钩子都是写在组件里面也可以传三个参数(to,from,next)
五、Vue响应式布局
- App.vue 中使用 body.getBoundingClientRect().width 判断视窗大小
mounted() {
const { body } = document;
console.log(body.getBoundingClientRect().width);
if (body.getBoundingClientRect().width < 993) {
store.dispatch("app/toggleDevice", "mobile");
store.commit("get_device", "mobile");
} else {
store.dispatch("app/toggleDevice", "desktop");
store.commit("get_device", "desktop");
}
window.addEventListener("unload", this.saveState);
},
methods: {
saveState() {
sessionStorage.setItem("state", JSON.stringify(this.$store.state));
},
},
六、Vue创建项目
vue-cli
- 1、npm安装
- 2、安装vue-cli
- 3、vue init webpack ”项目名称“
- 进入项目:cd 项目名,安装依赖
npm install
- npm run dev,启动项目
@vue/cli
- vue create 项目名
- 也可以通过 vue ui 命令以图形化界面创建和管理项目
vue ui
七、前端组件化
Component,中文称为组件,或者构件。使用非常比较广泛,它的核心意义在于复用,相对模块,对于依赖性有更高的要求。
- 页面上的每个独立的可视/可交互区域视为一个组件;
- 每个组件对应一个工程目录,组件所需的各种资源都在这个目录下就近维护;
- 由于组件具有独立性,因此组件与组件之间可以 自由组合;
- 页面只不过是组件的容器,负责组合组件形成功能完整的界面;
- 当不需要某个组件,或者想要替换组件时,可以整个目录删除/替换。
实现
- 在template属性中定义组件的HTML结构
- props属性定义了组件可以接受的外部参数的数组,如果传入外部参数,则可以直接当做数据属性来使用
- 组件的实例化可以通过标签来实现
八、Vue生命周期
-
vue实例有⼀个完整的⽣命周期,从节点开始创建、载入、更新、销毁⼀系列过程,⽣命周期的钩⼦就是在某个阶段给⼀些做处理的机会
-
⽣命周期总共分为8个阶段创建前/后、载⼊前/后、更新前/后、销毁前/后。
前端安全相关
九、uni-app
标签转换
- div 改成 view
- span、font 改成 text
- a 改成 navigator
- img 改成 image
- select 改成 picker
- iframe 改成 web-view
webpack
一、webpack原理
webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖的文件,使用loaders来处理它们,最后打包成一个或多个浏览器可识别的js文件(bundle.js),通过代码分割成单元片段并按需加载。
二、核心概念
Entry
入口起点(entry point)指示 webpack 应该使用哪个模,来作为构建其内部依赖图的开始。
进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
每个依赖项随即被处理,最后输出到称之为 bundles 的文件中。
Output
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。
Module
模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk
代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
Loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。
loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
Plugin
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
三、什么是bundle,什么是chunk,什么是module
bundle: 是由webpack打包出来的文件
chunk: 是指webpack在进行模块依赖分析的时候,代码分割出来的代码块
module: 是开发中的单个模块
四、webpack的构建流程
初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数。
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译。
确定入口:根据配置中的 entry 找出所有的入口文件。
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
完成模块编译:在经过第 4 步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系。
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。
输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
五、模块热更新
模块热更新是webpack的一个功能,它可以使得代码修改之后,不用刷新浏览器就可以更新。在应用过程中替换添加删出模块,无需重新加载整个页面,是高级版的自动刷新浏览器。
只更新变更内容,以节省宝贵的开发时间。调整样式更加快速,几乎相当于在浏览器中更改样式
六、webpack实现模块化
es6 module是js语言原生的模块化方案,但是由于浏览器的兼容问题,需要webpack对我们写好的模块代码进行处理,可以让浏览器识别我们写的模块代码。
因为浏览器端是没有commonJS规范相关的module,exports,require变量,而且该规范是同步加载模块的,所以浏览器端不适用commonJs规范类型的模块化。
webpack通过模拟module,exports,require变量,将我们的模块代码打包成一个文件,浏览器一次性将所有资源加载到内存中,变向实现了浏览器端的模块化。
(function(modules) { // modules就是我们的模块代码集合,格式类似于{ 'module1': module1对应的模块代码包装函数 }
function require(name) { // webpack模拟的require变量
const module = { exports: {} }; // webpack模拟的module,exports变量
// require的作用就是在执行的时候将事先定义好的module,exports,require变量传入当前模块对应的包装函数并且运行。
modules[name].call(module, module, module.exports, require);
return module.exports; // module.exports变量被传入包装函数运行之后赋值。
};
require('入口文件');
})(
// 参数就是模块代码被包装之后的集合
{
'模块代码1路径': function(module, exports, require) {
// 代码主体
},
'模块代码2路径': function(module, exports, require) {
// 代码主体
}, }
)