分为两种:W3C标准盒模型和IE怪异盒模型
WC3: width + height
IE: width + height+padding+border
content-box(默认):宽度和高度之外绘制内边距和边框
border-box:宽度和高度之内绘制设定元素的边框及内边距
行元素:span、strong、input、a、b、i、em、img等
块元素:div、h1~h6、hr、ul、p、li、table
行内块元素:img、input、td
1.zoom:可以改变页面上元素的尺寸,属于真实尺寸
测试10px
测试12px
-webkit-transform:scale()只对可以定义宽高的元素生效,如果是行内元素的话,应该先转为行内块元素。
测试10px
测试12px
1.语义化标签
2.增强型表单包括属性以及元素
3.新增视频
4.Canvas 图形
5.地理定位
6.拖放API
7.SVG绘图
animation // 动画
transition // 动画过度
text-shadow // 文字阴影
box-shadow // 盒子阴影
border-radius // 圆角
border-image // 图片边框
color: rgba(0,0,0,0.1) // 透明度设置
background-clip // 背景绘制
flex //布局
// 媒体查询
// 多列布局
header 头部
nav 导航栏
section 区块
main 主要区域
article 主要内容
aside 侧边栏
footer 底部
px: px是显示器屏幕分辨率而言的尺寸单位
rpx:是微信小程序独有的、解决屏幕自适应的尺寸单位
em: 相对于父元素的字体尺寸
rem: 相对于根元素的字体大小
vh\vw: 相对于视口的高度和宽度。1vh = 1/100 的浏览窗口高度,1vw = 1/100 的浏览器窗口宽度
标签选择器、类选择器、层级选择器(后代选择器)、id选择器、组选择器、伪类选择器
!important >内联 > ID选择器 > 类选择器 > 标签选择器
1、父元素使用overflow:hidden、auto
2、使用伪元素清除浮动
常用的伪元素:
span::before { // 内容前面插入新内容
content:'';
}
span::after{ // 内容之后插入新内容
content:'';
}
1、伪类本质上是为了弥补常规CSS选择器的不足,以便获取到更多信息
2、伪元素本质上是创建了一个有内容的虚拟容器
3、CSS3中伪类和伪元素的语法不同
伪类 :link :hover 单冒号
伪元素 ::before ::after 双冒号
4、可以同时使用多个伪类,而只能同时使用一个伪元素
5、其中伪类和伪元素的根本区别在于:它们是否创造了新的元素,这个新创造的元素就叫 "伪元素"
6、伪元素/伪对象:不存在在DOM文档中,是虚拟的元素,是创建新元素。
这个新元素(伪元素)是某个元素的子元素,这个子元素虽然在逻辑上存在,但却并不实际存在于文档树中
7、伪类:存在dom文档中标签,在伪类时改变样式
8、因为伪类是类似于添加类所以可以是多个,而伪元素在一个选择器中只能出现一次,并且只能出现在末尾
第一种:使用flex
第二种:使用绝对定位
.left,
.right {
width: 200px;
height: 200px;
background-color: #ccc;
position: absolute;
}
.left {
left: 0;
}
.right {
right: 0;
}
.center {
height: 200px;
margin: 0 200px;
background-color: burlywood;
}
transfrom:scale(0.5)
普通三角形
div {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
右上角角标的三角形
div {
width: 0;
height: 0;
border-top: 100px solid red;
border-left: 100px solid transparent;
}
/* 第一种 */
div{
width: 200px;
height: 200px;
background-color: bisque;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
/* 第二种 */
div{
width: 200px;
height: 200px;
background-color: bisque;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
/* 第三种 */
div {
width: 200px;
height: 200px;
background-color: bisque;
position: absolute;
top: 50%;
left: 50%;
margin: -100px 0 0 -100px;
}
基础数据类型:Undefined、Null、Boolean、Number、String、Symbol【ES6】、Bigint【ES10】
复杂数据类型(三大引用类型):Object、Array、Function 【Arrar和Function都属于Object类型】
Symbol
函数的返回值是不相等的同:判断一个变量是否为空, 或者是什么类型的
异:
typeof返回值是一个字符串, number, boolean, string, function, object, undefined
typeof缺点:null的值object,无法分辨是null还是object
instanceof返回值是boolean,只能识别object,function,Array
(1)变量声明
(2)解构赋值
(3)模板字符串(template string)
(4)ES6 提供了新的语法规则来定义函数 —— 箭头函数
(5)数据结构Set
(6)数据结构 Map
(7)for...of 循环
(8)Promise对象
(9)async/await
axios 是由 promise 封装的一个 http 的库,可以用于在浏览器和Node.js中对HTTP请求进行简单的封装,支持拦截器、并发请求等功能,适用于各种类型的HTTP请求,例如GET、POST等。
promise是一个对象,用于获取异步操作的数据
优点:避免回调地狱
简介的api,操作更加容易
容易理解,便于维护
容易操作相互依赖的异步请求
缺点:一旦执行,没办法取消
如果不设置回调函数,内部的错误,没办法抛到外部
不知道当前的状态
promise有三个状态:正在请求,成功,失败
async 和await两种语法 ,可以让异步代码像同步代码一样
async函数
async函数的返回值为promise对象
promise对象的结果由async函数执行的返回值决定
await表达式
await必须写在async函数中
await右侧的表达式一般为promise对象
await返回的是promise成功的值
await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
只能去重简单数据类型,不能引用数据类型
原因:存储机制不同,基本数据类型是存储在栈中,引用数据类型存储在堆中,指向它们的具体内容,每个具体对象就有一个具体的地址指向它,所以去重不了。null也属于对象,但是没有地址可以指向,存的就是null,所以就被去重掉了。
const arr = [1, 2, 3, 4, 5, 5, 5, 5, 5]
console.log(... new Set(arr)) //1,2,3,4,5
注意:map的key只能用基础数据类型,不能用引用数据类型,否则返回的值是undefined
一、创建
let map = new Map([[1, 2, 3], [4, 5], ['name', 'zs']])
console.log(map); // Map(3) {1 => 2, 4 => 5, 'name' => 'zs'}
console.log(typeof map); // object
二、用法
1.set()方法
// 1.set() 给实例设置一对键值对,返回map实例,有两个参数,第一个key,第二个value
map.set(5, 6) // Map(4) {1 => 2, 4 => 5, 'name' => 'zs', 5 => 6}
map.set([1], [2]) // Map(5) {1 => 2, 4 => 5, 'name' => 'zs', 5 => 6, Array(1) => Array(1)}
map.set(function () { }, [2]) // Map(6) {1 => 2, 4 => 5, 'name' => 'zs', 5 => 6, Array(1) => Array(1), …}
console.log(map); // Map(6) {1 => 2, 4 => 5, 'name' => 'zs', 5 => 6, Array(1) => Array(1), …}
2.get()方法
// 2.get() 获取指定键名的键值,返回键值
console.log(map.get([1])); // undefined
console.log(map.get(5)); // 6
3.delete()方法
// 3.delete() 删除指定键值对,成功返回true,失败返回false
console.log(map); // Map(6) {1 => 2, 4 => 5, 'name' => 'zs', 5 => 6, Array(1) => Array(1), …}
map.delete(5)
console.log(map); // Map(5) {1 => 2, 4 => 5, 'name' => 'zs', Array(1) => Array(1), ƒ => Array(1)}
4.clear()方法
// 4.clear() 清空Map中所有的键值对
map.clear()
console.log(map); // Map(0) {size: 0}
5.has()方法
// 5.has() 判断Map中是否包含对应的键,返回布尔类型的值
console.log(map.has([1, 2, 3])); // false
console.log(map.has('name', 'zs')); // true
6.entries()方法
// 6.entries() 返回实例的键值对遍历器
for (let [key, value] of map.entries()) {
console.log(key); // 1 4 name [1] ƒ () { }
console.log(value); // 2 5 zs [2] [2]
}
7.keys()方法 values()方法
// 7.keys() values()
/*
keys( )方法:返回实例所有键名的遍历器。
values( ) 方法:返回实例所有键值的遍历器。
*/
for (let x of map.keys()) {
console.log(x); // 1 4 name [1] ƒ () { }
}
for (let y of map.values()) {
console.log(y); // 2 5 zs [2] [2]
}
8.forEach()方法
// 8.forEach() 循环遍历Map中的所有键值对
map.forEach((key, value) => {
console.log(key + ':' + value); // 2:1 5:4 zs:name 2:1 2:function () { }
})
9.size属性
// 9.size属性 获取Map中键值对的数量
console.log(map.size); // 5
添加:
arr.unshift() 从前面添加元素, 返回值是添加完后的数组的长度
arr.push() 从后面添加元素,返回值为添加完后的数组的长度
删除:
arr.shift() 从前面删除元素,只能删除一个 返回值是删除的元素
arr.pop() 从后面删除元素,只能是一个,返回值是删除的元素
arr.splice(i,n) 删除从i(索引值)开始之后的那个元素。返回值是删除的元素
arr.slice(start,end) 切去索引值start到索引值end的数组,不包含end索引的值,返回值是切出来的数组
遍历:
arr.forEach() 遍历数组,无return 即使有return,也不会返回任何值,并且会影响原来的数组
arr.map() 映射数组(遍历数组),有return 返回一个新数组 。
过滤:
arr.filter() 过滤数组,返回一个满足要求的数组
转化:
str.split() 将字符串转化为数组
排序:
arr.sort() 将数组进行排序,返回值是排好的数组,默认是按照最左边的数字进行排序,不是按照数字大小排序的
arr.reverse() 将数组反转,返回值是反转后的数组
1.splice改变原数组,slice不改变原数组。
2.splice除了可以删除之外,还可以插入。
3.splice可传入3个参数,slice接受2个参数。
isNaN();
注意:isNaN(undefined)也是return true,所以,外层要先判断不是undefined
var a = NaN
if(a !== undefined ){
console.log(isNaN(a));
}
优点:
缺点:
更新完data数据后,需要及时渲染视图层
1创建.构造函数也是一个普通函数,创建方式和普通函数一样,但是构造函数习惯上首字母大写
2.调用:普通函数直接调用,构造函数要用关键字new来调用
3.this:构造函数内部的this指向实例,普通函数内部的this指向调用函数的对象(如果没有对象调用,默认为window)
4.return:构造函数默认的返回值是创建的对象(也就是实例),普通函数的返回值由return语句决定
5.构造函数内部会创建一个新对象,就是实例,普通函数不会创建新对象
6.构造函数的函数名与类名相同
1.直接输入this指向window(全局)
function fun(){
console.log(this); //window
}
fun()
function fun1(){
'use strict'
console.log(this); //undefined
}
fun1()
2.作为方法被调用,谁调用方法,this就指向谁
let obj = {
name:'lxy',
fun(){
console.log(this); //指向obj
}
}
obj.fun()
3.元素绑定事件,this指向DOM对象
测试10px
4. 构造函数
如果构造函数返回一个基本类型的值 则返回结果没有变化
如果返回一个对象 则结果就是你返回的对象
// 构造函数:名称规范用大驼峰模式
// new关键字做了什么?
// new会创建对象,将构造函数(Dog)的this指向创建出来的对象--->dog
function Dog(){
this.name = "lxy",
this.fun = function(){
console.log(this); //dog
}
}
let dog = new Dog()
dog.fun()
console.log(Dog.prototype == dog.__proto__); //将空对象的原型,指向构造函数的原型
5.箭头函数,this指向它的父级
防抖(debounce):事件被触发后,延迟n秒后再执行事件,如果在这n秒内事件被再次触发,则重新计时
防抖的概念:如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。
防抖的应用场景:
用户在输入框连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减少请求次数,节约请求资源.
例子:点击了按钮,需要两秒触发,还没两秒又点击了按钮,则需要又等两秒才能触发(重新计时)
Document
节流阀的概念:
高铁的卫生间是否被占用,由红绿灯控制,假设一个每个人上洗手间要五分钟,则五分钟之内别人不可以使用,上一个使用完毕之后,将红灯设置为绿灯,表示下一个人可以使用了.下一个人在使用洗手间时需要先判断控制灯是否为绿色,来知晓洗手间是否可用.
节流策略的应用场景:
例子:
点击了按钮,触发时间需要两秒,无论中途点击了多少次都不会再触发,也不会重新计算触发时间;只能等两秒后,再重新被触发
Document
防抖:如果事件被频繁触发,防抖保证只能有一次触发生效,前面N多次触发都会被忽略.
节流:如果时间被频繁触发,节流能减少事件触发的频率,因此,节流是有选择性的执行一部分事件.
总结:函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。
总结:三次握手是建立连接,四次挥手是关闭连接
握手
挥手
服务端发送完syn/ack之后就建立连接,为了防止已失效的请求报文,突然又传到服务器引起错误
单线程 :只有一个线程,只能做一件事
js里面有可视的DOM,如果是多线程的话,这个线程正在删除DOM节点,另一个线程在编辑DOM节点,导致浏览器不知道听谁的
宏任务:script(整体代码)、setTimeout、setInterval、setlmmediate、l/O/UI rendering
微任务:promise、Object.observe、MutationObserver
优先级:process.nextTick > promise.then>setTimeout>setlmmediate
回流:当render tree中的元素结构或尺寸发生改变,浏览器重新渲染的过程叫做回流
比如:
重绘:当页面元素的样式发生改变,不影响文档流中的位置,这个过程叫做重绘
总结:回流一定会引起重绘,重绘不一定会引起回流
DOM:document,获取元素得文档对象类型,可以设置标签的属性,跟浏览器没有关系
BOM:browser object model,浏览器对象模型,提供浏览器窗口进行交互的对象,管理页面与页面之间的通讯,核心对象是window
常用有:location(url相关的操作)、history(历史相关的操作)、navigator(浏览器相关的信息)
一个事件触发后,会在子元素和父元素之间传播,这种传播分为三个阶段,
捕获阶段(从window对象传导到目标节点(从外到里),这个阶段不会响应任何事件),目标阶段,(在目标节点上触发),冒泡阶段(从目标节点传导回window对象(从里到外)),事件委托/事件代理就是利用事件冒泡的机制把里层需要响应的事件绑定到外层
优先级:事件捕获 > 事件冒泡
内存泄漏是指一块被分配的内存既不能使用又不能回收,直到浏览器进程结束
垃圾回收机制是为了防止内存泄漏,寻找没用的变量,释放它所指向的内存
有两种方式: 标记清除、引用计数
标记清除:大部分浏览器使用这个方法,当变量进入执行环境时,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,再度标记,进行删除。
引用计数:这种方式常常会引起内存泄露,主要存在于低版本浏览器。跟踪某一个变量的使用次数,当变量赋值给另一个变量的时,引用次数加;如果该变量又赋值另一个变量,引用次数减1,当引用次数为0时,进行删除
事件代理(Event Delegation),又称之为事件委托。“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
浏览器缓存就是把一个已经请求过的web资源(如html页面,图片,JS,数据)拷贝一份放在浏览器中。缓存会根据进来的请求保存输入内容的副本。当下一个请求到来的时候,如果是相同的URL,浏览器会根据缓存机制决定是直接使用副本响应访问请求还是向源服务器再次发起请求。
(1)减少网络带宽消耗
(2)减少网络延迟
(3)减少服务器压力
概念:面向对象是一种编程思想
特点:1. 封装,属性和方法定义在对象里面。
2.继承,子对象可以使用父对象的属性和方法
3.多态,分别有两种形式。
重载:同一方法名,根据传入的参数不同,而执行不同操作
重写:子对象重新定义一个新的属性或方法覆盖父对象中继承的属性或方法。
Map 跟 forEach区别
相同点:
1) 都是循环遍历数组中的每一项。
2) 每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组)。
3)只能遍历数组。
不同点
1) map()返回新数组,有返回值
2)forEach()在原数组修改,没有返回值
1.减少http请求
2.减少DOM的操作
3.使用浏览器缓存
4.压缩css和js文件
5.css放在页面的最上面,js放在页面的最下面
6.使用CDN
7.避免重定向
8.避免图片 src 为空
'=='值相等即可(判断之前会做类型转换)
'==='类型和值都要相等
var变量提升
let,const都是块级作用域,var是函数作用域
const只能赋值一次,不能重新赋值,声明必须赋值
同一作用域下let和const不能声明同名变量,而var可以
转换为Boolean
类型的值时,都会转换为false
Undefined
类型的值会返回undefined
.而Null
类型的值返回为object
undefined
会转换为NaN
,无法参与计算,而null
会转换为0
,箭头函数
1、匿名函数,this指向的是父级,也就是谁创建它,this就指向谁
2、不能进行函数提升
3、不能new
4、不能改变this指向
普通函数this,谁调用,this就指向谁
谈谈你对原型的理解?
每当定义一个对象(函数也是对象),对象中都会有一些预定义属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象,使用原型对象的好处是,所有对象实例共享它的属性和方法
什么是原型链?原型链解决的是什么问题?
1)原型链解决的主要是继承问题
2)每个对象拥有一个原型对象,通过 proto 指针指向其原型对象,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向 null(Object.proptotype.__proto__指向的是null)。这种关系被称为原型链(prototype chain),通过原型链一个对象可以拥有定义在其他对象中的属性和方法
prototype 和 proto 区别是什么?
1)prototype是构造函数的属性
2)__proto__
是每个实例都有的属性,可以访问 [[prototype]] 属性
3)实例的__proto__
与其构造函数的prototype指向的是同一个对象
存储大小:Cookies不能超过4k, sessionStorage、localstorage,可以达到5m甚 至更大
存储时间:cookies设置有效时间
sessionStorage浏览器关闭,自动清除
localstorage除非删除,否则一直存在
相同:
修改this指向
不同:
1.执行方法:call和apply是同步,bind是异步
2.传参不同
3. 修改this: call、apply是临时的修改一次,也就是call和apply方法的那一次;当再次调用原函数的时候,它的指向还是原来的指向, bind是永久修改函数this指向
4. call和apply可以调用函数,bind返回值是一个函数
概念:函数嵌套函数
作用:内部函数可以访问外部函数的参数和变量
变量保存在内存中
缺点:使用不当,会导致内存泄漏
解决:在退出函数之前,将不适用的变量全部删除
// 第一种
var arr = [1,2,1,2,1]
arr = [...new Set(arr)]
// 第二种
var arr = [1,2,1,2,1]
var arr1 = arr.map((item,index) => {
if(arr1.indexOf(item) < 0){
arr1.push(item)
}
})
// 第三种
var arr = [1,2,4,3,1,1,2,2,21]
var arr1 = arr.filter((item,index,arr) => {
return arr.indexOf(item) === index
})
let arr = [
{
key: "1",
name: "林青霞",
},
{
key: "2",
name: "张三丰",
},
{
key: "1",
name: "段誉",
},
];
let obj = {};
let arr1 = arr.reduce(function (preValue, item) {
obj[item.key] ? "" : (obj[item.key] = true && preValue.push(item));
return preValue;
}, []);
同步和异步
同步: 只有前一个任务执行完毕,才能执行下一个任务
异步:不会阻塞下面代码执行,前一个任务还没执行完毕,下一个任务依然执行
比如:定时器(setTimeout、setInterval) 、ajax的异步请求、promise
浅拷贝:
var obj1 = {
name:'zangsan',
age: 18
}
var obj2 = Object.assign(obj1);
var obj1 = {
name:'zangsan',
age: 18
}
var obj2 = {...obj1};
深拷贝
1、JSON对象来实现深拷贝【缺点:函数无法拷贝,会显示undefined】
let str = {}
let obj = JSON.parse(JSON.stringify(str))
2.递归
function deepClone(obj){
015 objClone = Array.isArray(obj) ? [] : {};
if(obj && typeof obj=== "object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
var obj1 = {
name:'zangsan',
age: 18,
hobby:{
motion: new Array('篮球','足球')
}
}
var obj2 = deepClone(obj1);
console.log(obj1, obj2);
Vue的优点
MVC:
框架:Angular
Model:数据层(data),负责保存应用数据,与后端数据进行同步
View:视图层,负责视图展示,将Model的数据渲染出来
Controller:控制器,负责业务逻辑,根据用户行为对Model数据进行修改
MVC的思想:Controller里面把Model的数据赋值给View。
MVC的特点:实现关注点分离,即应用程序中的数据模型与业务和展示逻辑解耦。就是将模型和视图之间实现代码分离,松散耦合,使之成为一个更容易开发、维护和测试的客户端应用程序。
MVC的优点:
MVC的缺点:
MVVM:
框架:vue
Model:数据层
View:视图层
ViewModel:数据模型,视图和数据之间的转换
MVVM的特点: 在MVVM的框架下,视图和模型是不能直接通信的,它们通过ViewModal来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信。
MVVM的优点:
vue-cli、vuex、vue-router、axios
概念:自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用
添加自定义指令的两种方式:
什么是 vue 生命周期?有什么作用?
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做 生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。
创建前后---挂载前后---更新前后---销毁前后
beforeCreate:在实例部分(事件/⽣命周期)初始化完成之后调⽤。
created:在完成外部的注⼊/双向的绑定等的初始化之后调⽤。
beforeMount:在页⾯渲染之前执⾏。
mounted:dom 元素在挂载到页⾯之后执⾏。
beforeUpdate:数据改变,还没重新渲染之前执⾏。
updated:渲染数据完成之后执⾏。
执⾏销毁需要调⽤:vm.$destroy()
beforeDestroy:实例销毁之前执⾏。
destroyed:实例销毁之后执⾏。
组件生命周期:
actived:创建
deactived:销毁
vue获取数据在一般在哪个周期函数
渲染的过程
子组件更新过程
父组件更新过程
销毁过程
created(创建后):HTML没有渲染出来,不能直接操作dom节点;
mounted(挂载后):HTML已渲染,可以直接操作dom节点。
scoped
给dom元素加ref=‘refname’,然后通过this.$refs.refname进行获取dom元素
可以,比如 v-on=“onclick,onbure”
Vue2:v-for的优先级是高于v-if的,如果作用在同一元素上,输出的渲染函数中可以看除会先执行循环再判断条件,哪怕只渲染列表中一小部分元素,也得在每次重渲染的时候遍历整个列表,这会造成性能的浪费
Vue3:v-if的优先级时高于v-for的,因此v-if执行时要调用的变量可能还不存在,会导致报错。
方法1:
通过父组件媒介,从组件1传给父组件,再从父组件传给组件2
方法2:
组件1
//发送方
methods: {
submit() {
this.$bus.$emit("name", this.value);
},
},
组件2
//接收方
mounted() {
this.$bus.$on("name", (value) => {
this.value = value;
});
},
组件缓存,用于那些频繁切换的页面,减少因页面频繁切换;组件不断的创建和销毁导致损耗性能的情况;
更小:vue2对象编程,vue3是函数式编程,更利于代码的压缩
底层功能:渲染方式,数据监听,双向绑定,生命周期
数据双向绑定:vue2 用es5的发布订阅模式实现(defineProperty),vue3用了es6 的 Proxy对数据代理;
vue3.0可以在安装脚手架同时提前安装好一些项目开发必备的插件,并且3.0提供了可视化创建脚手架,可以更加方便的对插件和依赖进行管理和配置
vue3还新增了一些内置组件和方法,比如vue3可以默认进行懒观察,使用Function-based API,setup函数,对与插件或对象的一个按需引入,Computed Value ,新加入了 TypeScript 以及 PWA 的支持等等…
这里着重说一下vue3的一个按需引入
Vue2.x中new出的实例对象,所有的东西都在这个vue对象上,这样其实无论你用到还是没用到,都会跑一变,这样不仅提高了性能消耗,也无疑增加了用户加载时间。
而vue3.0中可以用ES module imports按需引入,如:keep-alive内置组件、v-model指令,等等,不仅我们开发起来更加的便捷,减少了内存消耗,也同时减少了用户加载时间,优化用户体验。
v-model:双向绑定,基本上用在表单元素上;
v-bind:单向绑定,绑定数据和属性以及表达式,数据只能从data流向页面
同:都是用于元素的显示和隐藏
不同:
v-show:CSS属性(display)实现显示还是隐藏
v-if:操作dom元素,消耗更高
1.原理不同。
hash模式的实现原理是通过监听Change事件来实现的。history模式是通过调用 history.pushState方法(或者replaceState) 并且 监听popstate事件来实现的。history.pushState会追加历史记录,并更换地址栏地址信息,但是页面不会刷新,需要手动调用地址变化之后的处理函数,并在处理函数内部决定跳转逻辑;监听popstate事件是为了响应浏览器的前进后退功能。
2.表现不同。
hash模式会在地址栏中有#号,而history模式没有;同时由于history模式的实现原理用到H5的新特性,所以它对浏览器的兼容性有要求(IE >= 10)。
3.history模式特点
history模式开发的SPA项目,需要服务器端做额外的配置,否则会出现刷新白屏(链接分享失效)。原因是页面刷新时,浏览器会向服务器真的发出对这个地址的请求,而这个文件资源又不存在,所以就报404。处理方式就由后端做一个保底映射:所有的请求全部拦截到index.html上。
插槽就是子组件中的提供给父组件使用的一个占位符,用
插槽分别有三种:具名插槽、匿名插槽、作用域插槽
具名插槽:子组件在slot插槽name属性自定义名称,父组件通过slot属性填充插槽的位置
//子组件
//父组件
我是header部分
作用域插槽:子组件的属性通过slot插槽传给父组件使用
子组件:把user对象通过slot插槽传给父组件
父组件:模板字符串template中v-slot指定接收
{{user}}
vue中采用mvvm的模式,view层与model层两者进行关联,任何一方的变化都会让另外一方受到影响
vue中内部采用了发布-订阅模式。内部结合了Object.defineProperty这个ES5的新特性,对vue传入的数据进行了相应的数据拦截,为其动态添加get与set方法。当数据变化的时候,就会触发对应的set方法,当set方法触发完成的时候,内部会进一步触发watcher,当数据改变了,接着进行虚拟dom对比,执行render,后续视图更新操作完毕
key是v-for渲染列表时的节点标识,当列表发生变化,Vue就会基于key的值重新排列元素顺序,并移除key不存在的元素,提升运行效率
.stop 阻止事件冒泡
.self 仅绑定元素自身可触发
.prevent 阻止默认行为
.once 只触发一次
v-once:只会执行一次
v-show:元素隐藏,通过display属性
v-if:元素隐藏
v-for:遍历数组
v-text:渲染字符串
v-html:渲染html
v-model:数据双向绑定
computed:
watch:
data可以是函数,也可以是对象;
对象,属性存储的地址是同个位置,组件之间的data属性会相互影响;
函数,属性都在函数的作用域内,相互独立,不会影响
vue框架中状态管理。在 main.js 引入 store,注入。
新建了一个目录store.js,…export。
场景有:单页应用中,组件之间的状态。音乐播放、登陆状态、加入购物车
state
getters
mutations
actions
modules
就是放在localStorage 或者就是sessionStorage ,或者借用辅助插vuex-persistedstate
#有两种,分别是声明式和编程式
用router-link进行跳转叫声明式
用js方式进行跳转叫编程式,this.$router.push()
路由传参有两种query和params
区别:
query: 1.参数在url可以看见
2.页面刷新参数还在
3.可以使用path或name属性跳转传参
params:1.参数不可见
2.页面刷新参数不见
3.必须使用name属性跳转
router.beforeEach((to, from, next) => {}) //路由跳转之前触发
router.afterEach((to, from, next) => {}) //路由跳转之后触发
to:要导航到的目标Route对象,简单点说就是到哪里去。
form:当前离开的对象,简单点说就是从哪儿来。
next:必须调用此函数才能解决钩子
//template
我是微信小程序
我是 app
//js
// #ifndef H5
// 表示只有 h5 不使用这个 api
uni.createAnimation(OBJECT)
// #endif
//css
/* #ifdef MP-WEIXIN */
/* 只在小程序中生效 */
.header {
color:red
}
/* #endif */
pages.json 配置文件
main.js 入口文件
App.vue 主组件
pages 页面管理部分
manifest.json 应用的配置文件
package.json 配置扩展
uni.navigateTo 保留当前页面,跳转到应用内的某个页面
uni.redirectTo 关闭当前页面,跳转到应用内的某个页面
uni.reLaunch 关闭所有页面,打开到应用内的某个页面
uni.switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
uni.navigateBack 关闭当前页面,返回上一页面或多级页面
get: 1、参数可见;
2、传输数据不超过2-4k;
3、后退没有影响;
4、可缓存;
5、有历史记录
post: 1、参数不可见
2、后退重新提交
3、不可缓存;
4、没有历史记录;
5、传输数据可以无限大;
http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份
git clone '链接' 下载目录
git init 初始化
git pull 更新
git status 查看状态
git add . 提交
git push 把本地仓库推到线上
git commit -m ‘描述’提交到本地仓库