https://www.dedao.cn/ebook/reader?id=V5R16yPmaYOMqGRAv82jkX4KDe175w7xRQ0rbx6pNgznl9VZPLJQyEBodb89mqoO
2022年出的书,针对Vue的版本是3.2.28,当前的版本是 3.4.21。
本书的一大特色是对Vue 3.x的核心源码(响应式原理、双向绑定实现、虚拟DOM、<keep-alive>原理和实现)进行了分析和讲解,这不仅有利于读者掌握Vue.js的设计思想,也能提升读者对Vue.js框架的熟练度,同时Vue.js源码知识也是近年来前端面试经常被问到的内容,学习和掌握这些内容是非常必要的。选择这本书的原因是有核心源码解析部分,这个会对深入了解会有帮助吧。
第一章 Vue概述
1.1 MVC 和MVVM模式
MVVM让开发真更加专注于页面视图,从视图出发来编写业务逻辑。
1.2 Vue.js 简介
1.2.1 Vue的由来
解决Angular过于庞大功能复杂上手难度高的问题。
1.2.2 Vue 前端工程化和Webpack
Webpack的主要功能是将前端工程所需要的静态资源文件打包成一个或者若干个js和CSS文件。
1.3 Vue 的 安装和导入
1.3.1 CND 方式导入
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
1.3.2 npm导入
npm install vue
1.3.3 Vue Cli 和 Vite导入
1.4 Vue3 的新功能
更快,更小,更易于维护
组合式API,新增内置组件,服务端渲染,vite
1.5 ES 6 语言基础
1.5.1 变量声明
1 let, var 和 const
使用let/ const来声明变量
2 箭头函数
let f = v =>v 等同于 var f = function (v) {return v}
let f = () => 5 等同于 var f = function() (return 5}
let f = (num1, num2) => num1 +num2 等同于 var f=function(num1, num2) {return num1+num2}
=> 后面跟随函数的返回值
3,对象属性和方法的简写 ES6 允许在大括号中直接写入变量和函数,作为对象的属性和方法。
4,对象解构
可以使用解构从数组和对象中提取值并赋给变量
1.5.2 模块化
1,ES6模块化概述
类似于python的import相似功能。JavaScript程序员自己制定了一些模块加载方案,主要有CommonJS和AMD两种。前者用于Node.js服务器,后者用于浏览器。
2, import和export
ES 6的到来,终于原生支持了模块化功能,即import和export。
1.5.3 Promis和async/await
1 Promise Promise是一种适用于异步操作的机制,比传统的回调函数解决方案更合理和更强大。
2, async/await
async/await是两个关键字,主要用于解决异步问题,其中async关键字代表后面的函数中有异步操作,await关键字表示等待一个异步方法执行完成。这两个关键字需要结合使用。
1.6 实践
实现如图的效果:显示内容随着输入内容变化(双向绑定)
html文档的理解:
1,2 是需要再index.html目录下需要有的文件。
3,4,5 通过变量msg进行信息同步
6,7,8 通过变量名 id= "app" 来进行信息同步。
1.7 小结与练习
第二章 Vue基础
2.1 Vue 实例和组件
2.1.1 创建Vue实例
这个例子中,createApp方法创建一个Vue使用实例。该实例通过调用mount方法,和页面上的DOM渲染进行挂载。mount的参数(#apt)传递id选择器,挂载之后这个Id对应的DOM就被Vue实例接管。
mount方法, Vue中的mount方法是将Vue实例与实际网页DOM相结合的关键步骤。它负责将Vue应用从纯Javascript对象转化为用户可见的网页界面,并建立起数据与界面之间的相应关系。
id选择器和class选择器:是CSS中两种基本且重要的选择器,用于HTML文档中定位并相应样式到特定的DOM元素。 id选择器以井号(#)开头,唯一性,高特异性,语义化,Javascript交互,class选择器用点号(.)开头, 可复用性 。
Vue中id选择器和class选择器的使用与传统HTML和CSS并没有本质区别,用于CSS样式应用和可能得JavaScript交互。由于Vue的特性,call选择器在Vue项目中扮演着重要的角色。而id选择器在Vue中使用相对较少,主要集中于DOM定位,路由锚点或极少数需要极高样式优先级的场景。
createApp方法传递的参数是根组件(也可以叫作根实例)的配置,返回的对象叫作Vue应用实例,当应用实例调用mount方法后返回的对象叫作根组件实例,一个Vue应用由若干个实例组成,准确地说是由一个根实例和若干个子实例(也叫子组件)组成。如果把一个Vue应用看作一棵大树,那么称根节点为Vue根实例,子节点为Vue子组件。
2.1.2 用component() 方法创建组件
23-26行使用上一步返回的Vue实例app调用component()方法新建一个组件。该方法的以一个参数标记这个组件的名字,第二个参数是一个对象,这里的data必须是一个函数function,这个函数返回一个对象。template定义了一个模板,表示这个组件将会使用这部分HTML代码作为其内容。
15-16行,<button-component>表示用了一个自定义标签来使用组件,其内容保持和组件名一样,这是Vue中特有的使用组件的写法。可以多次使用,以达到组件复用的效果。
2.1.3 Vue组件、根组件、实例的区别
在一般情况下,我们使用createApp创建的叫作应用(根)实例,然后调用mount方法得到的叫作根组件,而使用app.component()方法创建的叫作子组件,组件也可以叫作组件实例,概念上它们的区别并不大。
Vue中的组件是相互嵌套的,可以看作是一个树结构,就是组件树。
2.1.4 全局组件和局部组件
2.1.3代码中直接使用app.component()创建的组件为全局组件,全局组件无须特意指定挂载到哪个实例上,可以在需要时直接在组件中使用,,全局组件必须在根应用实例挂载前定义,即需要再app.mount("#apt")之前定义。全局组件可以在任意的Vue组件中使用。局部组件表示指定它被某个组件所引用。
下面的例子为创建局部组件,代码
结果:
为了组件复用,可以将组件单独抽离出来,代码,结果如下:
2.1.5 组件方法和事件的交互操作
例子2.1.7 定义和调用方法的展示。单击“Hello inner”后显示弹窗。
在模板中通过设置@click="clickCallback"表示为<h2>绑定了一个click事件,回调方法是clickCallback,当单击发生时,会自动从methods中寻找clickCallback这个方法,并且触发它。
可以设置另一个方法,同时在clickCallback中使用this.xxx()去调用,如示例代码2-1-8所示。单击Hello inner,两个弹出窗口。
例 2.1.9 使用方法进行DOM交互操作
单击“click0”,可以实现数值++的操作。
2.1.6 单文件组件
将组件的模板代码被抽离到一起,使用<template>标签包裹;组件的脚本代码被抽离到一起,使用<script>标签包裹;组件的样式代码被抽离到一起,使用<style>标签包裹。这种方式为单文件组件。这使得组件UI样式和交互操作的代码可以写在一个文件内,方便了维护和管理。
正因为Vue.js有了单文件组件,才能将其和构建工具(Webpack等)结合起来,使得Vue.js项目不单单是简单的静态资源查看,而是可以集成更多文件预处理功能,这些功能改变了传统的前端开发模式,更能体现出前端工程化的特性,目前大部分Vue.js项目都会采用单文件组件。
2.2 Vue模版语法
模板语法是一种用于生成动态内容的语法规则。它通常用于在网页开发中,将数据和静态模板结合起来,生成最终的网页内容。《数据和展示方式联系到一起》
2.2.1 插值表达式
用{{}}来完成插值。
1.文本插值
{{}},可以使用v-oncel指令,使得数据改变时,插值处的内容不会改变。
例1-6中的练习,增加v-once后,mssg的值将停止变化。
Vue指令:在Vue中给DOM元素添加v-***形式的属性的写法叫作指令
2,原始HTML插值
插入的值会按照文本来解释,如果插入的是含有HTML代码的字符串,需要使用v-html指令。
这个命令存在危险,对于用户输入的内容不能使用这个指令,很容易导致XSS攻击。
3,属性插值
插值语法不能作用在HTML的属性上,遇到这种情况应该使用v-bind指令。
4, JavaScript表达式插值
2.2.2 指令
Vue指令:在Vue中给DOM元素添加v-***形式的属性的写法叫作指令
1, v-bind
v-bind是Vue.js框架中的一个指令,用于将数据绑定到HTML元素的属性上。通过v-bind指令,我们可以动态地将Vue实例中的数据绑定到HTML元素的属性上,实现数据的响应式更新。
v-bind的语法格式为:v-bind:属性名=“表达式”,其中属性名是要绑定的HTML属性,表达式是Vue实例中的数据或计算属性。
例如,我们可以使用v-bind将Vue实例中的一个变量绑定到HTML元素的class属性上:
<div v-bind:class="className"></div>
在上述代码中,className是Vue实例中的一个变量,通过v-bind:class指令将其绑定到div元素的class属性上。当className的值发生变化时,div元素的class属性也会相应地更新。
v-bind的简写用法是使用冒号(:)代替v-bind指令。通过简写,我们可以更加简洁地绑定数据到HTML元素的属性上。使用简写后的写法是:
<div :class="className"></div>
这样就可以将组件的className属性绑定到div元素的class属性上了。
2, v-if, v-else, v-else-if
实例:未登录,已注册显示请登录。已经登录显示欢迎登录,未注册显示请注册。
3, v-show
如下例,点击按钮字符串交替出现消失。,v-show的元素会始终被渲染并保存在DOM中,它只是被隐藏,显示和隐藏只是简单地切换CSS的display属性。
一般来说,v-if切换开销更高,而v-show的初始渲染开销更高。因此,如果需要非常频繁地切换,使用v-show更好;如果在运行时条件很少改变,则使用v-if更好。
4, v-for
示例 2-2-11 v-for指令 (遍历数组)
示例2-2-12 v-for 指令参数
v-for 指令遍历对象 2-2-13
v-for 指令遍历对象的参数 2-2-14
v-for 指令 有key属性。 由于Vue编程逻辑的问题,建议/需要再v-for定义key属性(有一些类似于索引的逻辑)。
当Vue更新使用了v-for渲染的元素列表时,它会默认使用“就地更新”的策略。如果数据项的顺序被改变了,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染到用户界面上。
Vue会尽可能地对组件进行高度复用,所以增加key可以标识组件的唯一性,目的是为了更好地区别各个组件,key更深层的意义是为了高效地更新虚拟DOM。
这里提到了虚拟DOM的概念:
虚拟DOM(Virtual DOM)是一种用于提Web应用性能的技术。它是通过在内存中创建一个轻量级的、实际DOM结构对应的JavaScript对象树来表示页面的结构和状态。虚拟DOM可以在页面更新时进行比较和计算,然后将变化的部分更新到实际的DOM上,从而减少了直接操作实际DOM的次数,提高了页面渲染的效率。
虚拟DOM的工作原理如下:
- 初始渲染:首先,将页面的初始状态转换为虚拟DOM树,并将其渲染到实际的DOM上。
- 更新比较:当页面状态发生变化时,会生成一个新的虚拟DOM树,并与之前的虚拟DOM树进行比较。
- 差异计算:比较过程中会找出两个虚拟DOM树之间的差异,即需要更新的部分。
- 更新应用:将差异应用到实际的DOM上,只更新需要变化的部分,而不是整个页面。
- 页面重绘:最后,浏览器会根据更新后的DOM结构重新绘制页面。
通过使用虚拟DOM,可以减少对实际DOM的直接操作次数,从而提高页面渲染的性能和响应速度。同时,虚拟DOM也提供了一种方便的方式来管理页面状态和更新,使得开发者可以更加专注于业务逻辑的实现。
v-for 和v-if不推荐在同一个DOM元素上使用。建议将逻辑在外面的指令写在一个单独的DOM元素上(空元素如template)。
5, v-on
之前已经用过v-on指令,它主要用来为DOM元素绑定事件。v-on的冒号后面可以跟一个参数,用来表示触发事件的名称,v-on的值可以是一个方法的名字或一个内联语句。v-on简写用“@”来代替。示例2-2-16
v-on指令传递参数,示例如下
v-on指令用在普通元素上时,只能监听原生DOM事件,用在自定义DOM元素组件上时,也可以监听子组件触发的自定义事件。 《有示例,不具体,后续会讲到》
在使用v-on监听原生DOM事件时,可以添加一些修饰符并有选择性地执行一些方法或者程序逻辑. 示例为prevent修饰符的作用。其他包括,.stop / .once / .capture 等。
6, v-model
与select,input等进行数据双向绑定
V-model结合 v-for
7, v-memo
v-memo是Vue 3中引入的指令,它的作用是在列表渲染时,跳过新的虚拟DOM的创建过程,提升性能。v-memo的引入也使得在大量列表渲染方面,Vue 3离成为最快的主流前端框架更近了一步。
v-memo指令主要结合v-for一起使用,而且必须作用在同一个元素上,如示例代码2-2-23所示。
本示例中,v-memo是否使用并看不出区别的,v-memo在处理大量数据时才有效果。
8,指令的动态参数
在使用v-bind或者v-on指令时,冒号后面的字符串被称为指令的参数,代码如下:
<a v-bind:href="url">...</a>
这里href是参数,告知v-bind指令将该元素的href属性与表达式url的值绑定。
<a v-on:click="doSomething">...</a>
在这里click是参数,告知v-on指令绑定哪种事件。
把用方括号括起来的JavaScript表达式作为一个v-bind或v-on指令的参数,这种参数被称为动态参数。
v-bind指令的动态参数代码如下:
<a v-bind:[attributeName]="url"> ... </a>
v-on指令的动态参数代码如下:
<button v-on:[event]="doThis"></button>
2.3 Vue的data属性、方法、计算属性和监听器
data属性、方法属性methods等,这些都是进行组件配置的重要内容。
2.3.1 data属性
Vue 3中,data属性是一个函数,Vue在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后Vue会通过响应性系统将其包裹起来,并以$data的形式存储在组件实例中。
2.3.2 方法
方法除了可以通过v-on使用之外,还可以通过插值表达式{{}}来使用。示例2-3-2
方法可以传参数
2.3.3 计算属性
计算属性是一种在面向对象编程中常见的概念,它允许我们通过定义一些特殊的方法来模拟属性的行为。计算属性的值并不是直接存储在对象中,而是根据其他属性或者对象状态的计算结果得到的。
在许多编程语言中,计算属性通常由两个方法组成:一个用于获取属性值的方法(通常称为getter),和一个用于设置属性值的方法(通常称为setter)。通过这两个方法,我们可以在获取和设置属性值时执行一些额外的逻辑。
计算属性的一个常见应用场景是对属性进行验证或者转换。例如,假设我们有一个名为"age"的属性,我们可以定义一个getter方法来确保"age"的值始终大于等于0,或者定义一个setter方法来将输入的字符串转换为整数类型。
另外,计算属性还可以用于实现依赖关系。例如,假设我们有一个名为"fullName"的计算属性,它依赖于"firstName"和"lastName"两个属性。当"firstName"或者"lastName"发生变化时,"fullName"会自动更新。
总结一下,计算属性是一种通过方法来模拟属性行为的概念,它可以用于验证、转换数据,以及实现属性之间的依赖关系。
计算属性可以完成类似方法的操作,如示例 2-3-4。计算属性的使用方式如同属性值。
2.3.4 计算属性和方法
· 计算属性:只要依赖的数据没发生改变,就可以直接返回缓存中的数据,而不需要每次都重复执行数据操作。
· 方法:只要页面更新用户界面,就会发生重新渲染,methods调用对应的方法,执行该函数,无论是不是它所依赖的。
计算属性之所以叫作“计算”属性,是因为它是固定属性data的对应,同时多了一些对数据的计算和处理操作。。一般情况下,同一个属性名,设置了计算属性就无须设置固定属性。反之,设置了固定属性就无须设置计算属性。
计算属性是一种在面向对象编程中常见的概念,它允许我们通过定义一些特殊的方法来模拟属性的行为。计算属性的值并不是直接存储在对象中,而是根据其他属性或者对象状态的计算结果得到的。
在许多编程语言中,计算属性通常由两个方法组成:一个用于获取属性值的方法(通常称为getter),和一个用于设置属性值的方法(通常称为setter)。通过这两个方法,我们可以在获取和设置属性值时执行一些额外的逻辑。
计算属性的一个常见应用场景是对属性进行验证或者转换。例如,假设我们有一个名为"age"的属性,我们可以定义一个getter方法来确保"age"的值始终大于等于0,或者定义一个setter方法来将输入的字符串转换为整数类型。
另外,计算属性还可以用于实现依赖关系。例如,假设我们有一个名为"fullName"的计算属性,它依赖于"firstName"和"lastName"两个属性。当"firstName"或者"lastName"发生变化时,"fullName"会自动更新。
总结一下,计算属性是一种通过方法来模拟属性行为的概念,它可以用于验证、转换数据,以及实现属性之间的依赖关系。
对于计算属性来说,上面定义的personInfo所对应的函数其实只是一个getter方法,每一个计算属性都包含一个getter方法和一个setter方法,上面的两个示例都是计算属性的默认用法,只调用了getter方法来读取。
在需要时,也可以提供一个setter方法,当手动修改计算属性的值时,就会触发setter方法,执行一些自定义的操作,如示例代码2-3-5所示。
1, 程序正常运行get函数,
2,修改计算属性的值,会启动Set函数
3,Set 函数运行
4,get 函数运行
5,get 函数运行结果(内容已经被Set函数修改。)
计算属性也可以传递参数,如示例 2-3-6.形式与方法传参一致,
2.3.5 监听器
监听器可以实现与计算属性set方法的功能。即监听属性值的变化,如示例2-3-7
1,修改属性值,2,执行watch的语句 3,语句执行结果,4,显示值同时变化
使用watch时有一个特点,就是当值第一次绑定时,不会执行监听函数,只有当值发生改变才会执行。如果需要在最初绑定值的时候也执行函数,则需要用到immediate属性。如2-3-8
watch方法还有deep属性,用来监听复杂对象的变化,或者监听数组的pop和push方法。如例2-3-9。 使用push方法在deep属性为false的情况下,并不会执行相关的代码。
2.3.6 监听器和计算属性
,对于计算属性computed和监听属性watch,它们在什么场合使用,以及使用时需要注意哪些地方,应当遵循以下原则:
· 当只需要监听一个定义在data中的属性是否变化时,需要在watch中设置一个同样的属性key值,然后在watch对应的function方法中去执行响应逻辑,而不需要在computed中另外定义一个值,然后让这个值依赖于在data中定义的这个属性,这样反倒绕了一圈,代码逻辑结构并不清晰。
· 如果需要监听一个属性的改变,并且在改变的回调方法中有一些异步的操作或者数据量比较大的操作,这时应当使用监听属性watch。而对于简单的同步操作,使用计算属性computed更加合适。
下面的两个例子实现相同的功能:监听 first name和last name的变化,变更full name的网页显示
代码分别如下:
2.4 案例 Vue 3 留言板
2.4.1 功能描述
业务目标:该项目主要由一个输入框和评论列表组成,在输入框内输入文字,单击“评论”按钮或者按回车键可以将评论内容渲染到页面中。评论主要由头像、内容、评论日期构成。
实现方案:
借助@keyup、@click指令完成用户交互事件的监听,利用v-for指令来渲染评论列表,借助计算属性computed实时获取最新的评论时间,使用methods来格式化时间展示和单击回调方法等。