前端学习总结

目录

JavaScript

浏览器执行JS

JS的组成

JS是什么语言

JS八进制和十六进制

null/undefined

isNaN()

前置自增/后置自增

==/===

区别

用哪个

逻辑与

Switch

Array

JS作用域

全局作用域/局部作用域

作用域链

JS预解析

JS执行机制

事件循环

JS对象创建

new关键字执行过程

内置对象/浏览器对象

数组常用方法

基本包装类型

字符串

字符串常用方法

值类型/引用类型

prototype

原型链查找规则

闭包

call/apply/bind

call

理解

应用场景

apply

理解

应用场景

bind

继承

浅拷贝/深拷贝

事件对象/事件源/事件类型

innerText/innerHTML

this

js修改Style

element.属性/element.getAttribute(‘属性’)

事件冒泡/事件捕获

Load/DOMContentLoaded

setTimeout/setInterval

Promise

是什么

为什么用

pending/fulfilled/rejected

resolve/reject

then/catch

then

catch

all

嵌套简写

async/await

防抖/节流

为什么要防抖节流

防抖

节流

应用场景

SessinStorage/LocalStorage

立即执行函数

箭头函数中的this

理解

示意图

forEach中的this指向

理解

修正this指向

Vue2

渐进式

响应式

MVVM

理解

示意图

单向绑定

双向绑定

响应式

原理

动态添加对象属性,Vue无法渲染

生命周期

理解

示意图

$nextTick

理解

原理

示意图

$foreUpdate()

应用场景

示例

编译过程

变量作用域

虚拟Dom

mustache语法

let/const

常用属性

data为什么是一个函数

computed

理解

computed没有触发更新

watch

常用指令

v-on

v-for

v-model

v-if/v-show

区别

应用场景

v-if和v-for为什么不建议一起使用

原因

解决方案

事件

wheel

理解

鼠标滑轮垂直滚动

sync

理解

示意图

组件

组件化

组件化思想

组件化思想的应用

组件如何使用

父子组件通信

子组件修改props

子组件避免修改props

解决方案

使用本地数据进行修改

通过事件通知父组件

使用计算属性

使用watch监听props的变化

子组件动态绑定样式

通过props传递样式

通过计算属性传递样式

兄弟组件通信

组件混入

组件扩展

slot

编译作用域

keep-alive

深度选择器

是什么

怎么用

CLI

路由

前端路由

$router

hash/history

路由懒加载

router-view

Vuex

Vue命令

...(扩展运算符)

npm报错

Edge浏览器调试

VSCode配置Edge调试

Vue3

优势

Vite

生命周期

响应式原理

Vue2.0的响应式

实现原理

存在问题

Vue3.0的响应式

通信方式

props

自定义事件

原生DOM事件

自定义事件

全局事件总线

v-model

useAttrs

ref/$parent

provide/inject

pinia

slot

默认插槽

具体名称插槽

作用域插槽

setup

是什么

注意点

ref/reactive

定义数据角度对比

原理角度对比

使用角度对比

customRef

toRef/toRefs

computed

watch/watchEffect

watch

watchEffect

shallowReactive/shallowRef

readonly/shallowReadonly

toRaw/markRaw

provide/inject

响应式数据的判断

Fragment

Teleport

Suspense

JavaScript

浏览器执行JS

  1. 渲染引擎:解析HTML与CSS,俗称内核。
  2. JS引擎:JS解释器,读取网页中的js代码,对其处理后运行。
  3. 浏览器本身并不会执行JS代码,通过内置JS引擎来执行JS代码,逐行解析。

JS的组成

  1. ECMAScript:javaScript语法,ECMAScript规定了JS的编程语法和基础核心知识。
  2. DOM:页面文档对象模型,通过DOM接口对页面上的各种元素进行操作
  3. BOM:浏览器对象模型,与浏览器窗口进行互动的对象结构,通过BOM可以操作浏览器窗口。

JS是什么语言

JS是一种弱类型或者说动态语言,这意味着不用提前声明变量的类型,类型会被自动确定。

JS八进制和十六进制

在JS中八进制前面加0,十六进制前面加0x

null/undefined

  1. null表示空的对象(该处的对象现在为空),空的值(该处的值现在为空),转为数值时为0。
  2. undefined表示未定义,没有赋值,转为数值时为NaN。

isNaN()

如果是数字返回false,如果不是数字返回true。

前置自增/后置自增

前置自增:先加1,后返回原值。

后置自增:先返回原值,后加1。

==/===

区别

  1. ==:类型自动转换并比较两个值是否相等。
  2. ===:不进行类型自动转换,比较两个值的类型和值是否完全相同。

用哪个

  1. ===不进行类型自动转换,因此更加严格和安全,建议使用。
  2. 明确知道两个值的类型,需要进行类型转换后再比较,使用==。

逻辑与

表达式1&&表达式2:

  1. 如果第一个表达式的值为真,则返回表达式2。
  2. 如果第一个表达式的值为假,则返回表达式1。
  3. 逻辑与的优先级要高于逻辑或。

Switch

变量和case里面的值必须是全等。

Array

可以把一组相关的数据一起存放。

JS作用域

就是代码名字在某个范围内起作用和效果,目的是为了提高程序的可靠性更重要的是减少命名冲突。

全局作用域/局部作用域

  1. 全局作用域:整个script标签或者是一个单独的js文件。
  2. 局部作用域:在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用。
  3. 全局变量:在全局作用域下的变量,或者在函数内部没有声明的变量也属于全局变量。
  4. 局部变量:在局部作用域下的变量,或者在函数内部的变量就是局部变量。
  5. 全局变量只有浏览器关闭的时候才会销毁,比较占资源。
  6. 局部变量当我们程序执行完毕的就会销毁,比较节约内存资源。
  7. Js中没有块级作用域,在es6的时候新增块级作用域。

作用域链

内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值。就近原则。

JS预解析

  1. js引擎会把js里面所有的var和function提升到当前作用域的最前面,然后按照代码书写的顺序从上 往下执行。
  2. JS预解析分为变量预解析(变量提升)和函数预解析(函数提升)。
  3. 变量提升就是把所有变量声明提升到当前作用域最前面,不提升赋值操作。
  4. 函数提升就是把所有函数声明提升到当前作用域的最前面,不调用函数。
  5. 函数表达式调用必须写在函数表达式的下面。
  6. 预解析过程:先提升变量,然后提升函数,然后变量赋值,然后调用函数,函数内部也是先提升变量 然后输出。

JS执行机制

  1. 同步任务:同步任务都在主线程上执行,形成一个执行栈。
  2. 异步任务:JS的异步是通过回调函数实现的。
    1. 普通事件:click,resize等。
    2. 资源加载:load,error等。
    3. 定时器:setInterval,setTimeout等。
  3. 执行顺序:
    1. 先执行执行栈中的同步任务
    2. 异步任务(回调函数)放入任务队列中。
    3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

事件循环

同步任务进入主线程,异步任务进入任务队列。主线程内的任务执行完毕,会从任务队列读取对应的任务,推入主线程执行,上述过程的不断重复就是事件循环。

JS对象创建

一组无序的线性属性和方法的集合,字符串,数值,数组,函数都是对象。

  1. 字面量创建对象:{}。
  2. new Object()创建对象。
  3. 构造函数创建对象:把对象里面的一些相同的属性和方法抽象出来封装到函数里面。
  4. ES6中通过Class和constructor创建对象。
  5. 我们利用构造函数创建对象的过程也称为对象的实例化

new关键字执行过程

  1. new构造函数可以在内存中创建一个空对象。
  2. this就会指向刚才创建的空对象。
  3. 执行构造函数里面的代码给这个空对象添加属性和方法。
  4. 返回这个对象。

内置对象/浏览器对象

内置对象:Math,Date,Array,String,Number,Boolean,Object,Error,Global,Function,RegExp。

浏览器对象:Window,Navigator,Screen,History,Location。

数组常用方法

  1. slice:截取原数组的一部分,返回一个新数组,原数组不变。
  2. splice:删除原数组的一部分,并且可以在删除的位置添加新的数组成员,返回被删除的元素 数组,原数组会改变。
  3. push,pop,unshift,shift,concat,filter,map,forEache,join,sort,reverse。

基本包装类型

就是把简单数据类型包装成了复杂数据类型。

字符串

  1. 字符串具有不可变性,看上去是可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
  2. 字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。

字符串常用方法

charAt,charCodeAt,str[index],concat,substr,slice,substring,replace,trim,trimStart,trimEnd,startWith,endWith。

值类型/引用类型

  1. 简单数据类型/基本数据类型,在存储变量中存储的是值本身,也叫值类型。String,number,boolean,undefined,null。null返回的是一个空的对象(object),如果有个变量我们打算存储对象,但是没想好就可以赋值null。
  2. 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此也叫做引用数据类型,通过   new关键字创建的对象(系统对象,自定义对象),如Object,Array,Date等。
  3. 简单数据类型是存放在栈里面,栈里面直接开辟一个空间存放的是值。
  4. 复杂数据类型首先在栈里面存放地址,十六进制表示,然后这个地址指向堆里面的数据。

prototype

prototype:每一个构造函数都有一个prototype属性,prototype就是一个对象,这个对象的所有属性和方法都会被构造函数所拥有。可以把不变的方法直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法。prototype的所有属性和方法,都能被实例对象共享,可以用来做对象继承或者用来扩展内置对象。

原型链查找规则

  1. 访问对象的属性方法时,先找这个对象自身。
  2. 如果没有就找它的原型(也就是_proto_指向的prototype原型对象)。
  3. 如果还没有就找原型对象的原型(Object的原型对象)。
  4. 依次类推一直找到Objetct为止(null)。
  5. _proto_对象原型意义在于为对象成员查找机制提供一个方向,一条路线。

闭包

一个作用域可以访问另外一个函数内部的局部变量,可以用作延伸变量的作用范围。

call/apply/bind

call

理解

call用来指定函数内部的this指向。

应用场景

调用对象的原生方法。

apply

理解

apply用来指定函数内部的this指向,接收数组作为函数执行时的参数。

应用场景
  1. 找出数组最大元素。
  2. 将数组的空元素变为undefined。
  3. 转换类似数组的对象。

bind

bind用于将函数内部的this绑定到某个对象,然后返回一个新函数。

继承

  1. 使用原型链继承。
  2. ES6中使用class和extends。

浅拷贝/深拷贝

浅拷贝:只拷贝一层,深层次对象只拷贝引用,Object.assign(target,...sources)

深拷贝:拷贝多层,每一级别的数据都会拷贝,需要判断数据类型用到递归。

事件对象/事件源/事件类型

  1. 事件对象:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event。比如:键盘按键状态,鼠标的位置,鼠标按钮。
  2. 事件源:事件被触发的对象,例如按钮。
  3. 事件类型:如何触发,什么事件,比如鼠标点击(onclick)还是鼠标经过,还是键盘按下。
  4. 事件处理程序:通过一个函数赋值的方式完成。

innerText/innerHTML

innerText不识别html标签,去除空格和换行

innerHTML识别html标签,保留空格和换行

this

this指向的是事件函数的调用者。

js修改Style

js修改style样式操作,产生的是行内样式,CSS权重比较高。

element.属性/element.getAttribute(‘属性’)

  1. element.属性:获取内置属性值(元素本身自带的属性)。
  2. element.getAttribute(‘属性’):主要获得自定义的属性(标准)和我们程序员自定义的属性。

事件冒泡/事件捕获

  1. 事件冒泡:事件开始由最具体的元素接受,然后逐级向上传播到DOM最顶层节点。
  2. 事件捕获:由DOM最顶层节点开始,逐级向下传播到最具体的元素接受。
  3. e.target:点击了哪个元素,就返回哪个元素的。
  4. this:哪个元素绑定了这个点击事件,那么就返回谁。
  5. e.stopPropagation():阻止冒泡。

Load/DOMContentLoaded

Load:等页面内容全部加载完毕,包含页面dom元素,图片,flash,css等等。

DOMContentLoaded:是DOM加载完毕,不包含图片,flash,css等就可以执行,加载速度比load更快一些。

setTimeout/setInterval

setTimeout():在定时器到期后执行调用函数。

setInterval():每隔一段时间,就去调用一次回调函数。

Promise

是什么

Promis是一种用于处理异步操作的对象,代表一个尚未完成但是最终会完成或失败的操作,并且允许你在其完成或失败之后继续执行代码,类似于C#中的Task。

为什么用

  1. JavaScript执行的时候,一次只能执行一个任务,会阻塞其它任务,这个缺陷导致JavaScript的所有网络操作,浏览器事件都必须是异步执行,异步执行可以使用回调函数执行。
  2. 常见的异步模式有定时器,接口调用,事件函数。
  3. ajax可能有多个网络请求是关联的,先执行第一个请求返回结果后,第一个返回结果作为第二个请求 的参数,调用第二个网路请求。如果业务复杂,网路请求太多时,回调也很多,会容易出现回调地狱。
  4. Promise专门解决异步的回调地狱问题。

pending/fulfilled/rejected

  1. pending:进行中,表示Promise还在执行阶段,没有执行完成。
  2. fulfilled:成功状态,表示Promise成功执行完成。
  3. rejected:拒绝状态,表示Promise执行被拒绝,也是失败。

resolve/reject

  1. resolve():把Promise的状态从进行中pending变为成功状态fulfilled。
  2. reject():把Promise的状态从进行中pending变为拒绝状态rejected。

then/catch

then

执行resolve时,Promise状态变为fulfilled,会执行then方法,then方法接受的参数也是一个函数,函数中携带一个参数,该参数是resolve(res)返回的数据。

catch

执行reject时,Promise 状态从pending变为rejected,会执行catch方法,catch方法接收的也是一个函数,函数中携带一个参数,该参数是reject(err)返回的数据。

all

Promise.all()方法,提供了并行执行异步操作的能力,并且在所有异步操作完成之后,统一返回所有结果。

嵌套简写

  1. Promise和resolve()简写,直接return。
  2. Promise和reject()简写,直接throw。

async/await

  1. async/await是用于处理异步操作的语法糖。
  2. async用于定义一个函数是异步的,当函数被标记为async时,它将返回一个Promise对象,无论实际返回值什么。async函数内部可以使用await关键字来暂停函数的执行,直到一个Promise完成并返回 结果。
  3. await关键字只能在async函数内部使用,它用于等待一个Promise对象完成,并且暂停async函数的执行,直到Promise对象状态变为resolved(已完成)或rejected(已失败)。

防抖/节流

为什么要防抖节流

限制JS代码频发执行。

防抖

  1. 单位时间内触发多次,最后一次生效。
  2. 做法:每次触发函数清除原来的定时器,重新开始计时。

节流

  1. 单位时间内,只触发一次。
  2. 做法:触发函数时判断是否到达了指定时间,如果到达了则执行,否则不执行。
  3. 时间戳法:
  4. 定时器法:
应用场景
  1. 防抖:搜索的时候会出现搜索提示,即通过input事件发送请求数据,这是一个很频繁的请求,防止用户在输入过程中发送请求,在停顿或停止的时候请求一下数据。
  2. 节流:鼠标不断触发某事件时,如点击,只在单位时间内触发一次。

SessinStorage/LocalStorage

本地存储特性:

  1. 数据存储在用户浏览器中。
  2. 设置,读取方便,甚至页面刷新不丢失数据。
  3. 容量较大,sessionStorage约5M,localStorage约20M。
  4. 只能存储字符串,可以将对象JSON.stringify()编码后存储。

window.sessionStorage:

  1. 生命周期为关闭浏览器窗口。
  2. 在同一个窗口(页面)下数据可以共享。
  3. 以键值对的形式存储使用。
  4. 存储数据:sessionStorage.SetItem(key,value)。
  5. 获取数据:sessionStorage.getItem(key)。
  6. 删除数据:sessionStorage.removeItem(key)。
  7. 删除所有数据:sessionStorage.clear()。
  8. 应用场景:敏感账号一次性登录。

window.localStorage:

  1. 生命周期为永久,除非手动删除,否则关闭页面也会存在。
  2. 可以多窗口(页面)共享(同一浏览器可以共享)。
  3. 以键值对的形式存储使用。
  4. 存储数据:localStorage.setItem(key,value)。
  5. 获取数据:localStorage.getItem(key)。
  6. 删除数据:localStorage.removeItem(key)。
  7. 删除所有数据:localStorage.clear()。
  8. 应用场景:长期登录,长期保存在本地的数据。

立即执行函数

立即执行函数最大的作用就是创建了一个独立的作用域。里面所有的变量都是局部变量,不会有命名冲突。

箭头函数中的this

理解
  1. 普通函数的this在全局作用域中指向全局对象,在对象方法中指向调用该方法的对象。
  2. 箭头函数没有自己的this,它会从最近的非箭头的父级作用域中继承this。
  3. 箭头函数的this在其定义时就确定了,无法通过call,apply,bind来改变。

示意图

forEach中的this指向

理解

foreEach中的this,在严格模式下,指向undefined。在非严格模式下,指向全局对象。

修正this指向

  1. 使用箭头函数。
  2. 使用bind绑定。
  3. 保存this到变量。
  4. forEach第二个参数绑定this。

Vue2

渐进式

可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验。

响应式

当数据发生改变的时候,界面会自动发生一些响应。

MVVM

理解
  1. ViewModel帮助Model和View通信,实现数据双向绑定。
  2. Data Bing:数据绑定,将Model的改变实时反应到View中。
  3. DOM Listener:Dom监听,DOM发生事件,可以监听到并改变对应的Data。
示意图

单向绑定

  1. 单向绑定是指把Model绑定到View上面,当更新Model的时候View就会自动更新。
  2. 插值形式{{}}和v-bind,都是单向绑定的体现形式。

双向绑定

  1. 双向绑定是指把Model绑定到View的同时也把View绑定到Model上面,使Model和View能够相互更新。
  2. v-model就是双向绑定的体现形式。

响应式

原理

动态添加对象属性,Vue无法渲染

  1. Vue只能追踪已经被初始化为响应式的数据属性,在创建Vue实例时,数据对象的属性必须要在data选项中进行初始化。
  2. 如果想动态添加属性并使其能够被Vue追踪和渲染出结果,可以使用Vue.set或者this.$set方法。

生命周期

理解
  1. 事物从诞生到消亡的整个过程。当Vue初始化的时候,执行到某一步的时候会对你自己定义的函数执行一个回调。
  2. Create:html模板渲染之前,这时候获取不到dom元素,通常初始化某些属性值,然后再渲染试图,视图渲染前前先获取下数据(ajax请求)。
  3. Mounted:html模板渲染之后,这时候可以获取到dom元素,通常是初始化页面完成之后,再对html的dom节点进行一些操作。视图渲染后初始化echarts实例。
示意图

$nextTick

理解
  1. Vue实现响应式并不是数据发生变化之后dom立即变化,而是按照一定的策略进行dom的更新。
  2. 当你想在改变dom元素的数据之后基于新的dom做点什么,那么对新dom的一系列js操作都需要放到$nextTick()的回调函数中。
  3. $nextTick()表示当数据更新了,并且在dom中渲染完成之后,自动执行该函数。
  4. 在created()进行dom操作一定要放在$nextTick()的回调函数中,因为在created()执行的时候dom其实并没有进行任何的渲染,此时进行dom操作无异于徒劳,所以此处一定要将dom操作的js代码放到$nextTick()的回调函数中,与之对应的就是mounted(),在mounted()执行的时候所有的dom挂载已经完成。
原理
  1. Vue是异步执行dom更新,一旦观察到数据变化,就会开启一个队列,然后把在同一个事件循环当中的watcher推送到这个队列。
  2. 如果watcher被触发多次,那么只会被推送到队列一次,这种缓冲行为可以有效的去掉重复数据造成的不必要计算和dom操作,而在下一个事件循环时,Vue会清空队列,并进行必要的dom更新。
  3. 为了在数据变化之后等待Vue完成dom更新,可以在数据变化之后立即使用Vue.nextTick(callback),这样回调函数在dom更新完成之后就会被调用。
示意图

$foreUpdate()

应用场景

如果直接添加或者修改data中的对象或者数组时,页面是不识别的,这个时候可以考虑使用$foreUpdate()。

示例

编译过程

  1. 初始化工作。
  2. 执行beforeCreated函数。
  3. 初始化data数据。
  4. 执行created函数。
  5. 判断是否传了el选项。
  6. 如果没传,等到vm主动调用$mount()再继续执行。
  7. 如果传了el,再判断是否传template模板选项。
  8. 如果没有传template,将el对应容器的所有内容,当成template。
  9. 将template通过render函数编译成虚拟DOM树。

变量作用域

变量在什么范围内是可用的。var是没有块级作用域。

虚拟Dom

在Vue中,当数据发生变化时,Vue会生成一个新的虚拟DOM并将其与之前的虚拟DOM进行比较。然后Vue会计算出需要进行的最小化的DOM操作,并将这些操作批量应用到真实的DOM上。这样就避免了频繁地直接操作真实DOM,提高了性能。

mustache语法

{{}},插值操作。

let/const

let:变量需要改变。let具有块级作用域。

const:变量不需要改变。

  1. const修改的标识符为常量,不可以再次赋值。
  2. const修饰的标识符必须赋值。
  3. 当我们修饰的标识符不会被再次赋值时,使用const来保证数据的安全性。
  4. 优先使用const,只有需要改变某一个标识符的时候才使用let。

常用属性

data为什么是一个函数

  1. 如果data是一个对象,那么所有实例将会共享相同的数据对象,这就会导致当一个实例的状态发生变化时,其它实例也会受到影响。
  2. data是函数,能确保每个实例都返回一个独立的数据对象,互不影响。每个实例都会调用该函数来获取独立的数据对象,从而保持各自的状态独立性。

computed

理解

计算属性,支持缓存,不支持异步,只有依赖数据发生变化,才会重新进行计算。

computed没有触发更新
  1. 在Vue中,如果直接修改数组中元素的属性而不改变数组本身,会导致computed属性没有正确地触 发更新。这是因为Vue默认只对整个数组地变化进行响应式处理。
  2. 如果需要在修改数组中元素地属性时触发computed属性更新,可以使用Vue.set方法或者使用扩展运算符创建新的数组来触发响应式更新。

watch

不支持缓存,支持异步操作,数据变化时执行异步或开销较大的操作,一般可以监听变量,数组,计算属性。

常用指令

v-on

v-for

1. 官方推荐在使用v-for时,给对应的元素或组件添加上一个Key属性为了更好的复用。

2. 使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

3. key的作用主要是为了高效的更新虚拟DOM。

v-model

v-model用于实现表单元素和数据的双向绑定,可以同时绑定输入框的值和数据对象中的属性,从视图到数据的变化会自动同步到数据对象,反之亦然。

v-if/v-show

区别
  1. v-if只有在表达式为真时才会渲染对应的元素,当表达式为假时,元素不会被渲染到DOM中。
  2. v-show不管表达式的值是真还是假,元素始终会被渲染到DOM中,只是通过设置CSS的display属性来控制是否显示。
应用场景

v-if适合那些很少发生切换的场景,v-show适合需要频繁切换显示/隐藏状态的场景。

v-if和v-for为什么不建议一起使用

原因

v-for比v-if具有更高的优先级,每次遍历重新渲染时都会对每个循环项的条件进行判断。

解决方案
  1. 使用元素包裹,将v-if和v-for放到不同的元素上面进行包裹。
  2. 使用计算属性,对数据进行过滤,然后只使用v-for渲染已经过滤的数据。

事件

wheel

理解
  1. wheel是一个DOM事件,它代表了鼠标滑轮滚动的事件。
  2. 在Vue中,可以通过在模板中使用@wheel来监听这个事件,然后在对应的方法中处理滚轮的滚动逻辑,比如垂直滚动条的滚动,放大缩小等操作。
鼠标滑轮垂直滚动

sync

理解
  1. .sync表示对prop进行”双向绑定”。
  2. Vue推荐在子组件中使用update:myPropName的方式向父组件传值。
  3. 在父组件中通过.sync修饰符,可以将@update删除,并且能直接修改父组件中变量的值。
示意图

组件

组件化

  1. 将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了。
  2. 我们将一个完整的页面拆分成很多个组件。每个组件都用于实现页面的一个功能块。而每一个组件又可以进行细分。

组件化思想

  1. 它提供了一种抽象,让我们可以开发出一个独立可复用的小组件来构造我们的应用。
  2. 任何的应用都会被抽象成一颗组件树。

组件化思想的应用

尽可能的将页面拆分成一个个小的,可复用的组件。

组件如何使用

  1. 组件的使用分成三个步骤:1.创建组件构造器 2.注册组件 3.使用组件。
  2. Vue.extend():创建的是一个组件构造器。通常在创建组件构造器时,传入template代表我们自定义组件的模板。该模板就是在使用到组件的地方,要显示的HTML代码。
  3. Vue.component():将组件构造器注册为一个组件,并且给它起一个组件的标签名称。需要 传递两个参数:1.注册组件的标签名 2.组件构造器。
  4. Vue组件内部是不能访问Vue实例里面的数据的。
  5. Vue组件的数据存放在组件对象的data属性里面,这个data属性必须是一个函数,而且这个函数返回一个对象,对象内部保存着数据。如果data属性不是一个函数Vue直接就报错,Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象,组件在多次使用后会相互影响。

父子组件通信

  1. 父组件通过props向子组件传递数据。
  2. 子组件通过自定义事件向父组件发送消息。
  3. 父组件访问子组件:使用$children或者$refs。
  4. 子组件访问父组件:$parent。

子组件修改props

子组件避免修改props

Vue中,子组件应该尽量避免修改props属性值,因为props被设计为单向数据流,即父组件传递数据给子组件使用,不应该由子组件直接修改。这是为了保证数据流的清晰和可预测性。

解决方案
使用本地数据进行修改

可以将props的值赋给子组件中的变量,然后在子组件中修改本地变量而不影响父组件的props。

通过事件通知父组件

当子组件需要修改props的值时,可以触发自定义事件,让父组件处理相应的更新操作。

使用计算属性

在子组件内部使用计算属性对props的值进行加工处理,以便返回一个经过处理的新值。

使用watch监听props的变化

可以使用watch来监听props的变化,一旦变化就执行相应操作。

子组件动态绑定样式

通过props传递样式

通过计算属性传递样式

兄弟组件通信

EventBus

组件混入

  1. 全局混入:Vue.mixin()({}),全局混入只能定义Vue组件生命周期的属性或方法,定义其它属性或方法不生效。
  2. 组件混入:把功能注入到指定的组件,先把通用功能提取出来,然后再注入到需要的组件上。

组件扩展

extends,把两个组件的合并,组成新组件。

slot

  1. 插槽是让我们原来的设备具有更多的扩展性。把相同的东西进行封装,不同的东西使用插槽。父组件替换插槽的标签,但是内容由子组件来提供。
  2. 组件的插槽:
    1. 组件的插槽也是为了让我们封装的组件更加具有扩展性。
    2. 让使用者可以决定组件内部的一些内容到底展示什么。

编译作用域

父组件模板的所有东西都会在父级作用域内编译,子组件模板的所有东西都会在子级作用域内编译。父组件替换插槽的标签,但是内容由子组件来提供。

keep-alive

Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

深度选择器

是什么
  1. 当style标签有scoped属性时,它的CSS只作用于当前组件中的元素,父组件的样式不会渗透到子组 件。
  2. 在父组件scoped中根据子组件内部元素的类名修改子组件的样式,深度选择器可以使样式渗透到子组件。
怎么用
  1. ::v-deep:Vue3.0单文件规范中,会有警告。
  2. >>>:Sass,Less预处理器无法正确解析。
  3. /deep/:Vue3.0中,安装项目时选择了dart-sass,这个不支持/deep/和>>>。
  4. :deep():推荐写法。

CLI

命令行界面,俗称脚手架。

路由

前端路由

先通过js获取全部后端资源,然后通过前端路由,根据不同的url抽取全部资源里面的js代码渲染不同的页面。

$router

  1. $router:路由实例,使用$router.push方法导航到不同的URL。
  2. $route:处于活跃状态的路由对象,可以获取当前浏览器URL路由的参数值,比如name,path,query, params等。

hash/history

  1. hash模式:锚点,指url尾巴后的#号和后面的字符。浏览器刷新不会向服务器发送请求,hash改变会触发hashchange事件,只能改变#后面的url片段。
  2. history模式:页面定位,提供了pushState和replaceState两个方法记录路由状态,这两个方法改变URL不会引起页面刷新,浏览器刷新会向服务器发送请求。

路由懒加载

把不同路由对应的组件分割成不同的代码块,当路由被访问的时候才加载对应组件。路由懒加载的主要作用就是将路由对应的组件打包成一个个的Js代码块。只有在这个路由被访问到的时候,才加载对应的组件。

设置导航的链接来实现不同的HTML内容切换,会被渲染为a标签。我们点击a标签时可能会重载页面,router-link会被vue监听,跳转链接时不会刷新界面。

  1. :to相当于a标签的href属性
  2. replace:页面切换时不会留下历史记录
  3. tag:被渲染成相应的标签
  4. active-calss:设置激活链接时class属性,当前页面及所有与当前页面地址匹配的链接都会被添加class属性
  5. append:当前(相对)路径前添加基路径。

router-view

  1. 一个页面里面可以切换着展现不同的组件页面,单页面中与router-link配合,渲染router-link映射过来的组件。
  2. 直接包在keep-alive里面,所有路径匹配到的视图组件都会被缓存。

Vuex

  1. 存储需要多页面共享的状态,全局单例对象,集中式存储管理。
  2. state:单一状态树,就是把所有的数据都放在一起。
  3. getters:可以当作是store的计算属性,可以访问store中的所有state,并且可以被多个模块重用。
  4. mutations:状态更新,不支持异步操作。
  5. action:代替mutations支持异步操作。

Vue命令

npm run dev:开发环境,在本地node中运行了一个前端服务器。

npm run build:将前端资源以及js源码打包并压缩,打包成一个新的静态的资源文件夹,放在Web(Tomcat/Ngnix)容器中即可运行。

...(扩展运算符)

...用于将一个可迭代的对象(比如数组,字符串等)展开为多个参数或者元素,属于浅拷贝。

npm报错

  1. npm config set proxy null
  2. npm config set https-proxy null
  3. npm config set registry https://registry.npm.taobao.org

Edge浏览器调试

  1. F8:暂停脚本执行。
  2. F10:跳过下一个函数调用。
  3. F11:进入下一个函数调用。
  4. Shift+F11:跳出当前函数。
  5. F9:单步调试。
  6. Ctrl+F8:停用断点。

VSCode配置Edge调试

Vue3

优势

  1. 打包大小减少41%,打包快。
  2. 初次渲染快55%,更新渲染快133%。
  3. 内存减少54%,占用内存少。
  4. 使用Proxy代替defineProperty实现响应式。
  5. 重写虚拟DOM的实现。
  6. 更好的支持TypeScript。
  7. 在Vue2.0中,使用传统的Options API,新增或者修改一个需求,就需要分别在data,methods,computed 里面进行修改。而在Vue3.0中可以利用Composition API可以更加有序的将代码,函数组织在一起。

Vite

  1. 开发环境中,无需打包操作,可快速的冷启动。
  2. 轻量快速的热重载。
  3. 真正的按需编译,不再等待整个应用编译完成。

生命周期

Vue3.0中,将beforeDestroy改名为beforeUnmount,destroyed改名为unmounted。

响应式原理

Vue2.0的响应式

实现原理
  1. 对象类型通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)。
  2. 数组类型通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。
存在问题
  1. 新增属性,删除属性,界面不会更新,可以通过this.$set,Vue.set来解决。
  2. 直接通过下标修改数组,界面不会自动更新。

Vue3.0的响应式

  1. 通过Proxy(代理),拦截对象中任意属性的变化,包括属性值的读写,添加,删除等。
  2. 通过Reflect(反射),对源对象的属性进行操作。

通信方式

props

Vue3.0中可以通过defineProps获取父组件传递的数据,并且在组件内部不需要引入defineProps方法就可以直接使用,props是只读的,不能修改。

自定义事件

原生DOM事件
  1. 原生DOM事件可以让用户与网页进行交互,比如click,change等。
  2. Vue2.0中组件标签需要通过native修饰符才能变为原生DOM事件。
  3. Vue3.0中,原生DOM事件不管是在标签,自定义标签,还是在组件标签上,它都是原生DOM事件。
自定义事件
  1. 自定义事件可以实现子组件给父组件传递数据。
  2. Vue3.0中,使用defineEmits方法传递一个数组,数组元素即为将来组件需要触发的自定义事件类型,此方法执行会返回一个$emit方法用于触发自定义事件。
  3. 在事件回调内部调用$emit方法去触发自定义事件,第一个参数为触发事件的类型。第二个,第三个等 等的参数为传递给父组件的数据。
  4. 在子组件中,defineEmits方法会将父组件的原生DOM事件变为自定义事件。

全局事件总线

  1. 全局事件总线可以实现任意组件通信,在Vue2.0中可以根据VM与VC的关系推出全局事件总线。
  2. Vue3.0中没有Vue的构造函数,也就没有Vue.prototype,并且组合式API写法没有this,那么在Vue3.0 中想实现全局事件总线的功能就有点不现实。
  3. 在Vue3.0中想使用全局事件总线的功能,可以使用mitt插件。

v-model

1.  v-model可以用来收集表单数据,进行数据的双向绑定。

2.  还可以实现父子组件的数据同步,相当于给子组件传递一个props(modelValue)和绑定一个自定 义事件 update:modelValue,来实现父子组件的数据同步。

3.  Vue3.0中一个组件可以通过使用多个v-model,实现父子组件多个数据的同步。

useAttrs

  1. Vue3.0中可以利用useAttrs方法获取组件的属性和事件,事件包含原生DOM事件或者自定义事件,类 似于Vue2.0中的$attrs属性和$listeners方法。
  2. 如果在子组件中用defineProps方法接受了某一个属性,那么useAttrs方法返回的对象身上就没有相应的属性和属性值。

ref/$parent

  1. ref可以获取元素的DOM或者获取子组件实例的VC。
  2. 既然可以在父组件内部通过ref获取子组件的实例VC,那么子组件内部的方法和响应式的数据父组件 都可以使用。
  3. Vue3.0中,组件内部的数据对外是“关闭的”,外部不能访问。
  4. 如果想让父组件获取子组件的数据或者方法,子组件需要通过defineExpose对外进行暴露。
  5. $parent可以获取某一个组件的父组件实例VC,因此可以使用父组件内部的数据和方法。
  6. 当然,父组件的数据和方法也需要通过defineExpose对外进行暴露。

provide/inject

在Vue3.0中,可以利用provide和inject实现祖先和后代组件间的通信。

pinia

pinia也是集中式管理的状态容器,类似于Vuex。

slot

默认插槽

具体名称插槽

具体名称插槽就是在组件内部留多个指定名字的插槽。

作用域插槽

作用域插槽可以理解为,子组件的数据由父组件提供,但是子组件内部决定不了自身结构和外观样式。

setup

是什么

组件中所用到的数据,方法等等,都需要配置在setup中。

注意点

  1. 尽量不要与Vue2.0配置混用。
    1. Vue2.0配置(data,methods,computed...)中可以访问到setup中的属性,方法。
    2. 但在setup中不能访问Vue2.0配置。
    3. 如果有重名,setup优先。
  2. setup不能是一个async函数,因为返回值不再是return的对象,而是Promise,后期也可以返 回一个Promise实例,但是需要Suspense和异步组件的配合。
  3. setup在beforeCreate之前执行一次,这个时候的this是undefined。

ref/reactive

定义数据角度对比

  1. ref用来定义基本类型数据,也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象。
  2. reactive用来定义对象(或数组)类型数据。

原理角度对比

  1. ref通过Object.defineProperty()的get和set来实现响应式(数据劫持)。
  2. reactive通过Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据。

使用角度对比

  1. ref定义的数据,操作数据时需要.value,读取数据时模板中直接读取不需要.value。
  2. reactive定义的数据,操作数据与读取数据都不需要.value。

customRef

customRef用来创建一个自定义的ref,并且对其依赖项跟踪和更新触发进行显示控制。

toRef/toRefs

  1. toRef将响应式对象中的某个属性单独提供给外部使用。
  2. toRefs和toRef的功能一致,但是可以批量创建多个ref对象。

computed

watch/watchEffect

watch

  1. 监视reactive定义的响应式数据时,oldValue无法正确获取,强制开启了深度监视(deep配置失效)。
  2. 监视reactive定义的响应式数据中某个属性时,deep配置有效。

watchEffect

  1. watch既要指明监听的属性,也要指明监听的回调。
  2. watchEffect不用指明监听哪个属性,监视的回调中用到哪个属性,那就监听哪个属性。
  3. watchEffect类似computed,但是computed注重的是计算出来的值(回调函数的返回值),所以必须要写返回值,而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

shallowReactive/shallowRef

  1. ShallowReactive只处理对象最外层属性的响应式。
  2. shallowRef只处理基本数据类型的响应式,不进行对象的响应式处理。

readonly/shallowReadonly

  1. readonly让一个响应式的数据变为只读的(深只读)。
  2. shallowReadonly让一个响应式的数据变为只读的(浅只读)。

toRaw/markRaw

  1. toRaw将一个由reactive生成的响应式对象转为普通对象,用于读取响应式对象对应的普通对象, 对这个普通对象的所有操作,不会引起页面的更新。
  2. markRaw用于标记一个对象,使该对象永远不会再成为响应式对象。
    1. 有些值不应该被设置为响应式的,例如复杂的第三方类库。
    2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

provide/inject

  1. provide和inject用来实现祖先和后代组件间的通信。
  2. 父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据。

响应式数据的判断

  1. isRef用来检查一个值是否为一个ref对象。
  2. isReactive用来检查一个对象是否由reactive创建的响应式代理。
  3. isReadonly用来检查一个对象是否由readonly创建的只读代理。
  4. isProxy用来检查一个对象是否由reactive或者readonly方法创建的代理。

Fragment

  1. 在Vue2.0中,组件必须有一个根标签。
  2. 在Vue3.0中,组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中,减少标签层级,减少内存占用。

Teleport

Teleport能够将我们的组件内html结构移动到指定位置的技术。

Suspense

Suspense在等待异步组件时渲染一些额外的内容,让应用有更好的用户体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子丶鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值