Vue.js 3 应用开发与核心源码解析 阅读笔记

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的工作原理如下:

  1. 初始渲染:首先,将页面的初始状态转换为虚拟DOM树,并将其渲染到实际的DOM上。
  2. 更新比较:当页面状态发生变化时,会生成一个新的虚拟DOM树,并与之前的虚拟DOM树进行比较。
  3. 差异计算:比较过程中会找出两个虚拟DOM树之间的差异,即需要更新的部分。
  4. 更新应用:将差异应用到实际的DOM上,只更新需要变化的部分,而不是整个页面。
  5. 页面重绘:最后,浏览器会根据更新后的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来格式化时间展示和单击回调方法等。

2.4.2 案例完整代码

2.5 小结与练习

第三章 Vue组件

3.1 组件生命周期

3.1.1 beforeCreate 和 created

3.1.2 beforeMount 和 mounted

3.1.3 beforeUpdate 和 updated

3.1.4 beforUnmount 和 unmounted

3.1.5 errorCaptured

3.1.6 activated和 deactivated

3.1.7 renderTracked 和 renderTriggered

3.2 组件通信

3.2.1 组件通信概述

3.2.2 父组件向子组件通信

3.2.3 子组件向父组件通信

3.2.4 父子组件的双向数据绑定与自定义v-model

3.2.5 非父子关系组件的通信

3.2.6 provided / inject

3.3 组件插槽

3.3.1 默认插槽

3.3.2 具名插槽

3.3.3 动态插槽名

3.3.4 插槽后备

3.3.5 作用域插槽

3.3.6 结构插槽props

3.4 动态组件

3.5 异步组件和<suspense>

3.6 <teleport>

3.7 Mixin

3.7.1 Mixin合并

3.7.2 全局Mixin

3.7.3 Mixin取舍

3.8 案例: Vue3 待办事项

3.8.1 功能描述

3.8.2 案例完整代码

3.9 小结和练习

第四章Vue组合式API

4.1 组合式API基础

4.2 setup 方法

4.2.1 setup方法的参数

4.2.3 setup方法组合模版使用

4.2.4 setup方法的执行时机和getCurrentlnstance方法

4.3 响应式类方法

4.3.1 ref和reactive

4.3.2 toRef和toRefs

4.3.3 其他响应式类方法

4.4 监听类方法

4.4.1 computed 方法

4.4.2 watchEffect方法

4.4.3 watch方法

4.5 生命周期类方法

4.6 mehods方法

4.7 provide/ inject

4.8 单文件组件<script setup>

4.9 案例: 组合式API待办事项

4.9.1 功能描述

4.9.2 案例完整代码

4.10 小结与练习

第五章VUE动画

5.1 从一个简单的动画开始

5.2 transition组件实现过渡效果

5.3 transition组件实现动画效果

5.4 transition组件实现过渡和动画

5.5 transition组件的钩子函数

5.6 多个元素或组件的过渡 / 动画效果

5.7 列表数据的过渡效果

5.8 案例: 魔幻的事项列表

5.8.1 功能描述

5.8.2 案例完整代码

5.9 小结与练习

第六章 VUE状态管理

6.1 什么是“状态管理模式”

6.2 Vuex概述

6.3 state

6.4 getters

6.5 mutation

6.6 action

6.7 modules

6.8 Vuex插件

6.9 在组合式API中使用Vuex

6.10Vues使用的场合

6.11 PINia介绍

6.12 案例: 事项列表的数据通信

6.13 小结与练习

第七章 Vue路由管理

7.1 什么是单页应用

7.2 Vue Router概述

7.3 动态路由

7.3.1 动态路由匹配

7.3.2 相应路由变化

7.4 导航守卫

7.4.1 全局前置守卫

7.4.2 全局解析守卫

7.4.3 全局后置钩子

7.4.4 组件内的守卫

7.4.5 路由配置守卫

7.5 嵌套路由

7.6 命名视图

7.7 命名路由

7.8 编程式导航

7.9 路由组件传参

7.10 路由重定向、别名即元信息

7.10.1 路由重定向

7.10.2 路由别名

7.10.3 路由元数据

7.11 Vue Router的路由模式

7.12 滚动行为

7.13 Keep-alive

7.13.1 keep-alive缓存状态

7.13.2 利用元数据Meta控制keep-alive

7.14 路由懒加载

7.15 在组合式API中使用Vue Router

7.16 案例:Vue Router路由代办事项

7.17 小结与练习

第八章 Vue Cli 工具

8.1 Vue Cli 概述

8.2 Vue Cli 的安装和使用

8.3 Vue Cli 自定义配置

8.4 案例 Vue Cli创建待办事项

8.5 小结与练习

第九章 Vite 工具

9.1 Vite概述

9.2 Vite的安装和使用

9.3 Vite自定义配置

9.4 Vite与Vue Cli

9.5 案例 Vite创建待办事项

9.6 小结与练习

第十章 Vue 服务端渲染

10.1 服务端渲染概述

10.2 Vue服务端渲染改造

10.3 编写通用的代码

10.4 预渲染

10.5 Nuxt.js 介绍

10.6 案例 服务端渲染待办事项

10.7小结与练习

第十一章 Vue 核心源码解析

11.1 源码目录结构解析

11.1.1 下载并情动Vue 3 源码

11.1.2 目录模块

11.1.3 构建版本

11.2 面试高频响应式原理

11.2.1 Proxy API

11.2.2 Proxy和响应式对象reactive

11.2.3 ref()方法运行原理

11.3 大名鼎鼎的虚拟DOM

11.3.1 什么是虚拟DOM

11.3.2 Vue 3 虚拟DOM 

11.3.3 获取<template>的内容

11.3.4 生成AST

11.3.5 生成render方法字符串

11.3.6 得到最终的Vnode对象

11.4 双向绑定的前世今生

11.4.1 响应式触发

11.4.2 生成新的VNode

11.4.3 虚拟DOM的diff过程

11.4.4 完成真实DOM的修改

11.5<keep-alive>的魔法

11.5.1 LRU算法

11.5.2 缓存VNode对象

11.6 小结与练习

第十二章 实战项目 豆瓣电影评分系统

12.1 开发环境准备 

12.2 项目功能逻辑

12.3 首页开发

12.4 登录页开发

12.5 详情页开发

12.6 发表页开发

12.7 搜索页开发

12.8 路由配置

12.9 服务端渲染改造

12.10 小结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/584772.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

毅四捕Go设计模式笔记——命令模式

命令模式&#xff08;Command Pattern&#xff09; 为了解决什么问题&#xff1f; 命令模式的目的是将请求发起者和请求执行者解耦&#xff0c;使得请求的发起者不需要知道具体的执行者是谁&#xff0c;也不需要知道执行的具体过程&#xff0c;只需要发送请求即可。 通过使用…

Apache Flume

文章目录 关于 Apache Flume数据流模型EventAgentSourceChannelSink 关于 Apache Flume 官网&#xff1a;https://flume.apache.orgFlume User Guide : https://flume.apache.org/releases/content/1.11.0/FlumeUserGuide.htmlFlume Developer Guide : https://flume.apache.o…

pytorch-解决过拟合之regularization

目录 1.解决过拟合的方法2. regularization2. regularization分类3. pytorch L2 regularization4. 自实现L1 regularization5. 完整代码 1.解决过拟合的方法 更多的数据降低模型复杂度 regularizationDropout数据处理早停止 2. regularization 以二分类的cross entropy为例&…

EasyRecovery数据恢复软件2025永久免费电脑版下载

EasyRecovery数据恢复软件是一款业界知名的数据恢复工具&#xff0c;它凭借强大的恢复能力和广泛的数据兼容性&#xff0c;帮助用户从各种存储设备中恢复丢失或删除的数据。以下是关于EasyRecovery数据恢复软件的详细介绍。 EasyRecovery绿色破解下载网盘链接: https://pan.ba…

基于FPGA的数字信号处理(3)--什么是浮点数?

科学计数法 你可能不了解「浮点数」&#xff0c;但你一定了解「科学记数法」。 10进制科学记数法把一个数表示成a与10的n次幂相乘的形式&#xff08;1≤|a|<10&#xff0c;a不为分数形式&#xff0c;n为整数&#xff09;&#xff0c;例如&#xff1a; 19970000000000 1.9…

前端业务开发中使用原生js和elementui两种方式实现头像裁切上传的功能

日常业务开发中&#xff0c;无论是后台管理系统还是前台界面&#xff0c;都会遇到图片裁剪的业务需求&#xff0c;选择合适的尺寸或者图片的关键部分&#xff0c;满足我们的功能需求&#xff01;&#xff01; 效果预览 效果一&#xff1a; 效果二: 实现过程 1.原生js实现方…

在Linux操作系统中的文件系统及挂载介绍

磁盘存储数据的最小单位是数据块。 数据块只是一个概念&#xff0c;而不能查看&#xff0c;默认4kb是一个数据块。 块设备文件存储数据时是随机的数据块&#xff0c;而不是相邻的数据块。 无论一个数据块是否被占满&#xff0c;当一个数据块存储数据时&#xff0c;这个数据块…

哪个牌子的骨传导耳机好用?盘点五款高热度爆款骨传导耳机推荐!

近年来&#xff0c;骨传导耳机在潮流的推动下销量节节攀升&#xff0c;逐渐成为运动爱好者和音乐迷们的必备装备。但热度增长的同时也带来了一些品质上的忧患&#xff0c;目前市面上的部分产品&#xff0c;存在佩戴不舒适、音质不佳等问题&#xff0c;甚至可能对听力造成潜在损…

hdfs balancer -policy

hdfs balancer -policy当前有两种&#xff0c;datanode&#xff08;默认&#xff09;&#xff1a;如果每个数据节点是平衡的&#xff0c;则集群是平衡的。blockpool&#xff1a;如果每个datanode中的每个块池都是平衡的&#xff0c;则集群是平衡的。 代码区别&#xff1a;计算…

字段选择器

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列、spring教程等&#xff0c;大家有兴趣的可以看一看 &#x1f4d9;Jav…

Linux中ssh登录协议

目录 一.ssh基础 1.ssh协议介绍 2.ssh协议的优点 3.ssh文件位置 二.ssh原理 1.公钥传输原理&#xff08;首次连接&#xff09; 2.ssh加密通讯原理 &#xff08;1&#xff09;对称加密 &#xff08;2&#xff09;非对称加密 3.远程登录 三.服务端的配置 常用的配置项…

JENKINS 安装,学习运维从这里开始

Download and deployJenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their softwarehttps://www.jenkins.io/download/首先点击上面。下载Jenkins 为了学习&#xff0c;从windows开始&#x…

mysql面试题九(SQL优化)

目录 1.一条 SQL 是如何执行的 2.索引失效的几种情况 3.EXPLAIN 4.Where 子句如何优化 5.超大分页或深度分页如何处理 6.大表查询如何优化 7.分库分表 基本概念 分库分表方法 水平拆分 垂直拆分 分库分表后的注意事项 1.一条 SQL 是如何执行的 在MySQL中&#xff0…

Linux下软硬链接和动静态库制作详解

目录 前言 软硬链接 概念 软链接的创建 硬链接的创建 软硬链接的本质区别 理解软链接 理解硬链接 小结 动静态库 概念 动静态库的制作 静态库的制作 动态库的制作 前言 本文涉及到inode和地址空间等相关概念&#xff0c;不知道的小伙伴可以先阅读以下两篇文章…

vue 设置输入框只能输入数字且只能输入小数点后两位,并且不能输入减号

<el-input v-model.trim"sb.price" placeholder"现价" class"input_w3" oninput"valuevalue.replace(/[^0-9.]/g,).replace(/\.{2,}/g,.).replace(/^(\-)*(\d)\.(\d\d).*$/,$1$2.$3)"/> 嘎嘎简单、、、、、、、、、

RAPTOR:索引树状 RAG,使用树结构来捕捉文本的高级和低级细节

RAPTOR&#xff1a;索引树状 RAG&#xff0c;使用树结构来捕捉文本的高级和低级细节 提出背景使用树结构来捕捉文本的高级和低级细节递归摘要RAPTOR 递归树结构的构建 树遍历或压缩树检索 语义关联性检索对比 RAG、知识图谱树遍历检索和压缩树检索 提出背景 论文&#xff1…

西门子PCU50.3数控面板维修6FC5220-0AA31-2AA0

西门子数控面板维修&#xff0c;西门子工控机触摸屏维修6FC5247-0AA00-0AA3 西门子数控机床维修包括&#xff1a;840C/CE、840Di/DSL、840Di SL、802C S、802D SL、810D/DE、820D SL、S120数控电路板、数控伺服驱动模块、控制模块修、电源模块&#xff0c;西门子数控机床控制面…

SQL Sever无法连接服务器

SQL Sever无法连接服务器&#xff0c;报错证书链是由不受信任的颁发机构颁发的 解决方法&#xff1a;不用ssl方式连接 1、点击弹框中按钮“选项” 2、连接安全加密选择可选 3、不勾选“信任服务器证书” 4、点击“连接”&#xff0c;可连接成功

国内各种免费AI聊天机器人(ChatGPT)推荐(上)

作者主页&#xff1a;点击&#xff01; 国内免费AI推荐专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月27日11点25分 欢迎来到AI聊天机器人推荐系列的第一篇文章&#xff01; 在这个系列中&#xff0c;我将引领您探索国内各种AI聊天机器人的精彩世界。 从…

西瓜书学习——决策树形状、熵和决策树的本质

文章目录 决策树形状监督学习算法分类与回归 熵信息熵香农熵 (Shannon Entropy) - H(X)联合熵 (Joint Entropy) - H(X, Y)条件熵 (Conditional Entropy) - H(Y|X)互信息 (Mutual Information) - I(X; Y)相对熵 (Relative Entropy) / KL散度 (Kullback-Leibler Divergence) - DK…