动力节点Vue3笔记——Vue核心技术

尚硅谷· vue3+ts 知识点学习整理 |14h的课程(持续更ing) 2020.9.18vue3发布本文按照,2023.10发布的公开版本3.3.4来讲解特点:性能提升打包体积减少、初次渲染更快、更新更快、内存减少源码升级用Proxy代替defineProperty实现响应式;重写虚拟DOM的实现和Tree-Shakingvue3支持TypeScript新特性CompositionAPI(组合式API):setup、ref与reactive、computed与watch内置组件。 阅读详情

动力节点Vue笔记第二章 Vue核心技术
20/100
发布文章
assdfgdfgjhtdo
未选择任何文件
new

2 Vue核心技术

2.1 事件处理

2.1.1 事件处理的核心语法

  1. 指令的语法格式:<标签 v-指令名:参数=”表达式”></标签>
  2. 事件绑定的语法格式:v-on:事件名。例如鼠标单击事件的绑定使用v-on:click。
  3. 绑定的回调函数需要在Vue实例中使用methods进行注册。methods可以配置多个回调函数,采用逗号隔开。
  4. 绑定回调函数时,如果回调函数没有参数,( )可以省略。
  5. 每一个回调函数都可以接收一个事件对象event。
  6. 如果回调函数有参数,并且还需要获取事件对象,可以使用$event进行占位。
  7. v-on:click可以简写为@click。简写的语法格式:@事件名
  8. 回调函数中的this是vm。如果回调函数是箭头函数的话,this是window对象,因为箭头函数没有自己的this,它的this是继承过来的,默认这个this是箭头函数所在的宿主对象。这个宿主对象其实就是它的父级作用域。而对象又不能构成单独的作用域,所以这个父级作用域是全局作用域,也就是window。
  9. 回调函数并没有在vm对象上,为什么通过vm可以直接调用函数呢?尝试手写Vue框架。
  10. 可以在函数中改变data中的数据,例如:this.counter++,这样会联动页面上产生动态效果。

2.1.2 事件修饰符

.stop - 调用 event.stopPropagation()。

*<div** @click="san"**>**  
3.     **<div** @click.stop="er"**>**  
4.         **<button** @click="yi"**>**{{name}}**</button>**  
5.     **</div>**  
6. **</div>**  

.prevent - 调用 event.preventDefault()。

 **<a** href="http://www.bjpowernode.com" @click.prevent="yi"**>**  
3. {{name}}  
4. **</a>** 

.capture - 添加事件侦听器时使用 capture 模式。

**<div** @click.capture="san"**>**  
3.     **<div** @click.capture="er"**>**  
4.         **<button** @click="yi"**>**{{name}}**</button>**  
5.     **</div>**  
6. **</div>**

注意:只有添加了capture修饰符的元素才会采用捕获模式。(或者说带有capture修饰符的优先触发)

.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。

 **<div** @click="san"**>**  
 1.     **<div** @click.self="er"**>**  
 2.         **<button** @click="yi"**>**{{name}}**</button>**  
 3.     **</div>**  
 4. **</div>**  

.once - 只触发一次回调。
5.

**<button** @click.once="yi"**>**  
 6.     {{name}}  
 7. **</button>** 

.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
1.无需等待,直接继续(立即)执行事件默认行为。(对wheel事件有效果)
2. .passive 和 .prevent 修饰符不能共存。

2.1.3 按键修饰符

常用的按键修饰符包括:
.enter
.tab (只能配合keydown使用)
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

<input type=”text” @keyup.page-down=”getInfo”>

可以通过全局 config.keyCodes 对象自定义按键修饰符别名

Vue.config.keyCodes.huiche = 13

2.1.4 系统修饰键

系统修饰键包括4个
.ctrl
.alt
.shift
.meta
系统修饰键在使用时应注意:

  1. 只有当系统修饰键和其他键组合使用,并且组合键释放时,才会触发keyup事件。

  2. 只要按下系统修饰键,就会触发keydown事件。

小技巧 <input type=”text” @keyup.ctrl.c=”getInfo”/>

2.2 计算属性

  1. 案例:用户输入信息,然后翻转用户输入的字符串。
  2. 插值语法可以实现,但是有三个问题
    1. 代码可读性差
    2. 代码不可复用
    3. 代码难以维护
  3. 可以使用methods方式实现,存在1个问题
    1. 效率低,即使数据没有发生变化,但每一次仍然会调用method。
  4. 使用计算属性可以解决以上问题。
  5. 什么是计算属性?

data中的是属性。用data的属性经过计算得出的全新的属性就是计算属性。

  1. 计算属性的使用
**<div** id="app"**>**  
3.     **<h1>**{{msg}}**</h1>**  
4.     输入的信息:**<input** type="text" v-model="info"**><br>**  
5.     反转的信息:{{reversedInfo}} **<br>**  
6.     反转的信息:{{reversedInfo}} **<br>**  
7.     反转的信息:{{reversedInfo}} **<br>**  
8.     反转的信息:{{reversedInfo}} **<br>**  
9. **</div>**  
10. **<script>**  
11.     const vm = new Vue({  
12.         el : '#app',  
13.         data : {  
14.             msg : '计算属性-反转字符串案例',  
15.             info : ''  
16.         },  
17.         computed : {  
18.             reversedInfo:{  
19.                 get(){  
20.                     console.log('getter被调用了');  
21.                     return this.info.split('').reverse().join('')  
22.                 },  
23.                 set(val){  
24.                     //this.reversedInfo = val // 不能这样做,这样会导致无限递归  
25.                     this.info = val.split('').reverse().join('')  
26.                 }  
27.             }  
28.         }  
29.     })  
30. **</script>**
  1. 计算属性需要使用:computed
  2. 计算属性通过vm. d a t a 是无法访问的。计算属性不能通过 v m . data 是无法访问的。计算属性不能通过vm. data是无法访问的。计算属性不能通过vm.data访问。
  3. 计算属性的getter/setter方法中的this是vm。
  4. 计算属性的getter方法的调用时机:
    1. 第一个时机:初次访问该属性。
    2. 第二个时机:计算属性所依赖的数据发生变化时。
  5. 计算属性的setter方法的调用时机:
    1. 当计算属性被修改时。(在setter方法中通常是修改属性,因为只有当属性值变化时,计算属性的值就会联动更新。注意:计算属性的值被修改并不会联动更新属性的值。)
  6. 计算属性没有真正的值,每一次都是依赖data属性计算出来的。
  7. 计算属性的getter和setter方法不能使用箭头函数,因为箭头函数的this不是vm。而是window。
  8. 计算属性的简写形式

只考虑读取,不考虑修改时,可以启用计算属性的简写形式。

computed : {  
2.     reversedInfo(){  
3.         console.log('getter被调用了');  
4.         **return** **this**.info.split('').reverse().join('')  
5.     }  
6. }  

2.3 侦听属性的变化

  1. 侦听属性的变化其实就是监视某个属性的变化。当被监视的属性一旦发生改变时,执行某段代码。
  2. 监视属性变化时需要使用watch配置项。

使用watch实现:比较数字大小的案例

**<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     数值1:**<input** type="text" v-model="number1"**><br>**  
4.     数值2:**<input** type="text" v-model="number2"**><br>**  
5.     比较大小:{{compareResult}}  
6. **</div>**  
7. **<script>**  
8.     const vm = new Vue({  
9.         el : '#app',  
10.         data : {  
11.             msg : '侦听属性的变化',  
12.             number1 : 1,  
13.             number2 : 1,  
14.             compareResult : ''  
15.         },  
16.         watch : {  
17.             number1 : {  
18.                 immediate : true,  
19.                 handler(newVal, oldVal){  
20.                     let result = newVal - this.number2  
21.                     if(result **>** 0){  
22.                         this.compareResult = newVal + '**>**' + this.number2  
23.                     }else if(result **<** **0**){  
24.                         this.compareResult = newVal + '**<**' + this.number2  
25.                     }else{  
26.                         this.compareResult = newVal + '=' + this.number2  
27.                     }  
28.                 }  
29.             },  
30.             number2 : {  
31.                 immediate : true,  
32.                 handler(newVal, oldVal){  
33.                     let result = this.number1 - newVal  
34.                     if(result **>** 0){  
35.                         this.compareResult = this.number1 + '**>**' + newVal  
36.                     }else if(result **<** **0**){  
37.                         this.compareResult = this.number1 + '**<**' + newVal  
38.                     }else{  
39.                         this.compareResult = this.number1 + '=' + newVal  
40.                     }  
41.                 }  
42.             }  
43.         }  
44.     })  
45. **</script>** 

运行效果:


  1. 如何深度监视:
    1. 监视多级结构中某个属性的变化,写法是:’a.b.c’ : {}。注意单引号哦。
    2. 监视多级结构中所有属性的变化,可以通过添加深度监视来完成:deep : true
  2. 如何后期添加监视:
    1. 调用API:vm.$watch(‘number1’, {})
  3. watch的简写:
    1. 简写的前提:当不需要配置immediate和deep时,可以简写。
    2. 如何简写?
      1. watch:{ number1(newVal,oldVal){}, number2(newVal, oldVal){} }
    3. 后期添加的监视如何简写?
      1. vm.$watch(‘number1’, function(newVal, oldVal){})
  4. computed和watch如何选择?
    1. 以上比较大小的案例可以用computed完成,并且比watch还要简单。所以要遵守一个原则:computed和watch都能够完成的,优先选择computed。
    2. 如果要开启异步任务,只能选择watch。因为computed依靠return。watch不需要依赖return。
  5. 关于函数的写法,写普通函数还是箭头函数?
    1. 不管写普通函数还是箭头函数,目标是一致的,都是为了让this和vm相等。
    2. 所有Vue管理的函数,建议写成普通函数。
    3. 所有不属于Vue管理的函数,例如setTimeout的回调函数、Promise的回调函数、AJAX的回调函数,建议使用箭头函数。

2.4 class与style绑定

数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute,我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。因此,Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。

2.4.1 class绑定

2.4.1.1 绑定字符串

适用于样式的名字不确定,需要动态指定。

. <!DOCTYPE html**>**  
2. **<html** lang="en"**>**  
3. **<head>**  
4.     **<meta** charset="UTF-8"**>**  
5.     **<title>**class绑定字符串形式**</title>**  
6.     **<script** src="../js/vue.js"**></script>**  
7.     **<style>**  
8.         .static{  
9.             border: 1px solid black;  
10.             background-color: beige;  
11.         }  
12.         .big{  
13.             width: 200px;  
14.             height: 200px;  
15.         }  
16.         .small{  
17.             width: 100px;  
18.             height: 100px;  
19.         }  
20.     **</style>**  
21. **</head>**  
22. **<body>**  
23.     **<div** id="app"**>**  
24.         **<h1>**{{msg}}**</h1>**  
25.         **<div** class="static" :class="c1"**></div>**  
26.     **</div>**  
27.     **<script>**  
28.         const vm = new Vue({  
29.             el : '#app',  
30.             data : {  
31.                 msg : 'class绑定字符串形式',  
32.                 c1 : 'small'  
33.             }  
34.         })  
35.     **</script>**  
36. **</body>**  
37. **</html>** 

运行效果:

使用vue开发者工具修改c1的small为big:

通过测试可以看到样式完成了动态的切换。

2.4.1.2 绑定数组

适用于绑定的样式名字不确定,并且个数也不确定。

 <!DOCTYPE html**>**  
2. **<html** lang="en"**>**  
3. **<head>**  
4.     **<meta** charset="UTF-8"**>**  
5.     **<title>**class绑定数组形式**</title>**  
6.     **<script** src="../js/vue.js"**></script>**  
7.     **<style>**  
8.         .static{  
9.             border: 1px solid black;  
10.         }  
11.         .active{  
12.             background-color: green;  
13.         }  
14.         .text-danger{  
15.             color: red;  
16.         }  
17.     **</style>**  
18. **</head>**  
19. **<body>**  
20.     **<div** id="app"**>**  
21.         **<h1>**{{msg}}**</h1>**  
22.         **<div** class="static" :class="['active','text-danger']"**>**数组形式**</div>**  
23.         **<br><br>**  
24.         **<div** class="static" :class="[activeClass,errorClass]"**>**数组形式**</div>**  
25.         **<br><br>**  
26.         **<div** class="static" :class="classArray"**>**数组形式**</div>**  
27.     **</div>**  
28.     **<script>**  
29.         const vm = new Vue({  
30.             el : '#app',  
31.             data : {  
32.                 msg : 'class绑定数组形式',  
33.                 activeClass : 'active',  
34.                 errorClass : 'text-danger',  
35.                 classArray : ['active', 'text-danger']  
36.             }  
37.         })  
38.     **</script>**  
39. **</body>**  
40. **</html>**  

运行效果:

使用vue开发者工具删除数组中的一个样式:

2.4.1.3 绑定对象

适用于样式名字和个数都确定,但是要动态决定用或者不用。

. <!DOCTYPE html**>**  
2. **<html** lang="en"**>**  
3. **<head>**  
4.     **<meta** charset="UTF-8"**>**  
5.     **<title>**class绑定对象形式**</title>**  
6.     **<script** src="../js/vue.js"**></script>**  
7.     **<style>**  
8.         .static{  
9.             border: 1px solid black;  
10.         }  
11.         .active{  
12.             background-color: green;  
13.         }  
14.         .text-danger{  
15.             color: red;  
16.         }  
17.     **</style>**  
18. **</head>**  
19. **<body>**  
20.     **<div** id="app"**>**  
21.         **<h1>**{{msg}}**</h1>**  
22.         **<div** class="static" :class="{active : true, 'text-danger' : true}"**>**对象形式**</div>**  
23.         **<br><br>**  
24.         **<div** class="static" :class="classObject"**>**对象形式**</div>**  
25.     **</div>**  
26.     **<script>**  
27.         const vm = new Vue({  
28.             el : '#app',  
29.             data : {  
30.                 msg : 'class绑定对象形式',  
31.                 classObject : {  
32.                     active : true,  
33.                     'text-danger' : false  
34.                 }  
35.             }  
36.         })  
37.     **</script>**  
38. **</body>**  
39. **</html>**  

运行效果:

使用vue开发者工具修改text-danger为true:

2.4.2 style绑定

2.4.2.1 绑定对象
**<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     <!-- 静态写法 -->  
4.     **<div** class="static" style="font-size: 20px;"**>**对象形式**</div><br><br>**  
5.     <!-- 动态写法1 -->  
6.     **<div** class="static" :style="{fontSize: 40 + 'px'}"**>**对象形式**</div><br><br>**  
7.     <!-- 动态写法2 -->  
8.     **<div** class="static" :style="styleObject"**>**对象形式**</div><br><br>**  
9. **</div>**  
10. **<script>**  
11.     const vm = new Vue({  
12.         el : '#app',  
13.         data : {  
14.             msg : 'style绑定对象形式',  
15.             styleObject : {  
16.                 fontSize : '40px'  
17.             }  
18.         }  
19.     })  
20. **</script>** 
2.4.2.2 绑定数组
**<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     <!-- 静态写法 -->  
4.     **<div** class="static" style="font-size: 40px; color: red;"**>**数组形式**</div><br><br>**  
5.     <!-- 动态写法1 -->  
6.     **<div** class="static" :style="[{fontSize:'40px'},{color:'red'}]"**>**数组形式**</div><br><br>**  
7.     <!-- 动态写法2 -->  
8.     **<div** class="static" :style="styleArray"**>**对象形式**</div><br><br>**  
9. **</div>**  
10. **<script>**  
11.     const vm = new Vue({  
12.         el : '#app',  
13.         data : {  
14.             msg : 'style绑定对象形式',  
15.             styleArray : [  
16.                 {fontSize:'40px'},  
17.                 {color:'red'}  
18.             ]  
19.         }  
20.     })  
21. **</script>** 

2.5 条件渲染

2.5.1 v-if

指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true时才被渲染

**<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     温度:**<input** type="number" v-model="temprature"**><br>**  
4.     天气:  
5.     **<span** v-if="temprature <= 10"**>**寒冷**</span>**  
6.     **<span** v-if="temprature > 10 && temprature <= 25"**>**凉爽**</span>**  
7.     **<span** v-if="temprature > 25"**>**炎热**</span>**  
8. **</div>**  
9. **<script>**  
10.     const vm = new Vue({  
11.         el : '#app',  
12.         data : {  
13.             msg : '条件渲染',  
14.             temprature : 10  
15.         }  
16.     })  
17. **</script>** 

运行效果:

2.5.2 v-else-if、v-else

顾名思义,v-else-if 提供的是相应于 v-if 的“else if 区块”。它可以连续多次重复使用。
一个使用 v-else-if 的元素必须紧跟在一个 v-if 或一个 v-else-if元素后面。
你也可以使用 v-else 为 v-if 添加一个“else 区块”,当然,v-else元素也是必须紧跟在一个 v-if 或一个 v-else-if元素后面。

 **<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     温度:**<input** type="number" v-model="temprature"**><br>**  
4.     天气:  
5.     **<span** v-if="temprature <= 10"**>**寒冷**</span>**  
6.     **<span** v-else-if="temprature <= 25"**>**凉爽**</span>**  
7.     **<span** v-else**>**炎热**</span>**  
8. **</div>**  
9. **<script>**  
10.     const vm = new Vue({  
11.         el : '#app',  
12.         data : {  
13.             msg : '条件渲染',  
14.             temprature : 10  
15.         }  
16.     })  
17. **</script>** 

2.5.3 与v-if

因为 v-if 是一个指令,他必须依附于某个元素。但如果我们想要切换不止一个元素呢?在这种情况下我们可以在一个 元素上使用 v-if,这只是一个不可见的包装器元素,最后渲染的结果并不会包含个 元素。v-else 和 v-else-if 也可以在 上使用。

 **<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     温度:**<input** type="number" v-model="temprature"**><br>**  
4.     天气:  
5.     **<template** v-if="temprature <= 10"**>**  
6.         **<span>**寒冷**</span>**  
7.     **</template>**  
8.     **<template** v-else-if="temprature <= 25"**>**  
9.         **<span>**凉爽**</span>**  
10.     **</template>**  
11.     **<template** v-else**>**  
12.         **<span>**炎热**</span>**  
13.     **</template>**  
14. **</div>**  
15. **<script>**  
16.     const vm = new Vue({  
17.         el : '#app',  
18.         data : {  
19.             msg : '条件渲染',  
20.             temprature : 10  
21.         }  
22.     })  
23. **</script>** 

2.5.4 v-show

另一个可以用来按条件显示一个元素的指令是 v-show。其用法基本一样:

 **<div** id="app"**>**  
2.     **<h1>**{{msg}}**</h1>**  
3.     温度:**<input** type="number" v-model="temprature"**><br>**  
4.     天气:  
5.     **<span** v-show="temprature <= 10"**>**寒冷**</span>**  
6.     **<span** v-show="temprature > 10 && temprature <= 25"**>**凉爽**</span>**  
7.     **<span** v-show="temprature > 25"**>**炎热**</span>**  
8. **</div>**  
9. **<script>**  
10.     const vm = new Vue({  
11.         el : '#app',  
12.         data : {  
13.             msg : '条件渲染',  
14.             temprature : 10  
15.         }  
16.     })  
17. **</script>**  

不同之处在于 v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性。
v-show 不支持在 元素上使用,也不能和 v-else 搭配使用。

2.5.5 v-if VS v-show

v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建
v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display属性会被切换。
总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。

2.6 列表渲染

语法格式:v-for指令。该指令用在被遍历的标签上。

  1. v-for="(element, index) in elements" :key="element.id"

或者

v-for="(element, index) of elements" :key="element.id"  

2.6.1 遍历数组、对象、字符串、指定次数

 **遍历数组**
2. **<div** id="app"**>**  
3.     **<h1>**{{msg}}**</h1>**  
4.     **<h2>**遍历数组**</h2>**  
5.     **<ul>**  
6.         **<li** v-for="(product, index) in products" :key="product.id"**>**  
7.             商品名称:{{product.name}},单价:{{product.price}}元/千克,下标:{{index}}  
8.         **</li>**  
9.     **</ul>**  
10. **</div>**  
11. **<script>**  
12.     const vm = new Vue({  
13.         el : '#app',  
14.         data : {  
15.             msg : '列表渲染',  
16.             products : [  
17.                 {id:'111',name:'西瓜',price:20},  
18.                 {id:'222',name:'苹果',price:10},  
19.                 {id:'333',name:'香蕉',price:30}  
20.             ]  
21.         }  
22.     })  
23. **</script>** 

运行效果:

  1. 遍历对象
*<div** id="app"**>**  
3.     **<h1>**{{msg}}**</h1>**  
4.     **<h2>**遍历对象**</h2>**  
5.     **<ul>**  
6.         **<li** v-for="(propertyValue, propertyName) of dog" :key="propertyName"**>**  
7.             {{propertyName}}:{{propertyValue}}  
8.         **</li>**  
9.     **</ul>**  
10. **</div>**  
11. **<script>**  
12.     const vm = new Vue({  
13.         el : '#app',  
14.         data : {  
15.             msg : '列表渲染',  
16.             dog : {  
17.                 name : '拉布拉多',  
18.                 age : 3,  
19.                 gender : '雄性'  
20.             }  
21.         }  
22.     })  
23. **</script>**

运行结果:

  1. 遍历字符串
**<div** id="app"**>**  
3.     **<h1>**{{msg}}**</h1>**  
4.     **<h2>**遍历字符串**</h2>**  
5.     **<ul>**  
6.         **<li** v-for="char,index of str" :key="index"**>**  
7.             {{index}}:{{char}}  
8.         **</li>**  
9.     **</ul>**  
10. **</div>**  
11. **<script>**  
12.     const vm = new Vue({  
13.         el : '#app',  
14.         data : {  
15.             msg : '列表渲染',  
16.             str : '动力节点'  
17.         }  
18.     })  
19. **</script>**  

运行结果:

  1. 遍历指定次数
**<div** id="app"**>**  
3.     **<h1>**{{msg}}**</h1>**  
4.     **<h2>**遍历指定次数**</h2>**  
5.     **<ul>**  
6.         **<li** v-for="number,index of 10" :key="index"**>**  
7.             下标:{{index}},数字:{{number}}  
8.         **</li>**  
9.     **</ul>**  
10. **</div>**  
11. **<script>**  
12.     const vm = new Vue({  
13.         el : '#app',  
14.         data : {  
15.             msg : '列表渲染'  
16.         }  
17.     })  
18. **</script>** 

运行结果:

2.6.2 虚拟dom和diff算法

所谓的虚拟dom就是内存当中的dom对象。vue为了提高渲染的效率,只有真正改变的dom元素才会重新渲染。

2.6.3 v-for的key的作用以及实现原理

  1. 用index作为key
<!DOCTYPE html**>**  
3. **<html** lang="en"**>**  
4. **<head>**  
5.     **<meta** charset="UTF-8"**>**  
6.     **<title>**key的原理**</title>**  
7.     **<script** src="../js/vue.js"**></script>**  
8. **</head>**  
9. **<body>**  
10.     **<div** id="app"**>**  
11.         **<h1>**{{msg}}**</h1>**  
12.         **<button** @click="addFirst"**>**在数组第一个位置添加tom**</button>**  
13.         **<button** @click="addLast"**>**在数组最后位置添加vue**</button>**  
14.         **<table>**  
15.             **<tr>**  
16.                 **<th>**序号**</th>**  
17.                 **<th>**姓名**</th>**  
18.                 **<th>**邮箱**</th>**  
19.                 **<th>**选择**</th>**  
20.             **</tr>**  
21.             **<tr** v-for="(vip,index) of vips" :key="index"**>**  
22.                 **<td>**{{index + 1}}**</td>**  
23.                 **<td>**{{vip.name}}**</td>**  
24.                 **<td>**{{vip.email}}**</td>**  
25.                 **<td><input** type="checkbox"**></td>**  
26.             **</tr>**  
27.         **</table>**  
28.     **</div>**  
29.     **<script>**  
30.         const vm = new Vue({  
31.             el : '#app',  
32.             data : {  
33.                 msg : 'key原理(虚拟dom与diff算法)',  
34.                 vips : [  
35.                     {id:'100',name:'jack',email:'jack@123.com'},  
36.                     {id:'200',name:'lucy',email:'lucy@123.com'},  
37.                     {id:'300',name:'james',email:'james@123.com'}  
38.                 ]  
39.             },  
40.             methods : {  
41.                 addFirst(){  
42.                     this.vips.unshift({id:'400',name:'tom',email:'tom@123.com'})  
43.                 },  
44.                 addLast(){  
45.                     this.vips.push({id:'500',name:'vue',email:'vue@123.com'})  
46.                 }  
47.             }  
48.         })  
49.     **</script>**  
50. **</body>**  
51. **</html>** 

运行效果:

全部选中:

添加tom:

可以看到错乱了。思考这是为什么?

  1. 用vip.id作为key

运行和测试结果正常,没有出现错乱。为什么?

  1. key的作用

key存在于虚拟dom元素中,代表该虚拟dom元素的唯一标识(身份证号)。

  1. diff算法是如何比较的?

新的虚拟dom和旧的虚拟dom比较时,先拿key进行比较:

  1. 如果key相同:则继续比较子元素:
    1. 子元素不同:直接将新的虚拟dom元素渲染到页面生成新的真实dom元素。
    2. 子元素相同:直接复用之前的真实dom。
  2. 如果key不同:直接将新的虚拟dom元素渲染到页面生成新的真实dom元素。
  3. index作为key存在两个问题
  4. 效率较低。
  5. 对数组的非末尾元素进行增删时,容易错乱。
  6. index作为key和vip.id作为key对比

当index作为key时:

当vip.id作为key时:

2.7 列表过滤

使用watch和computed分别进行实现:

 <!DOCTYPE html**>**  
2. **<html** lang="en"**>**  
3. **<head>**  
4.     **<meta** charset="UTF-8"**>**  
5.     **<title>**列表过滤**</title>**  
6.     **<script** src="../js/vue.js"**></script>**  
7.     **<style>**  
8.         table,tr,th,td{  
9.             border: 1px solid blue;  
10.         }  
11.     **</style>**  
12. **</head>**  
13. **<body>**  
14.     **<div** id="app"**>**  
15.         **<h1>**{{msg}}**</h1>**  
16.         **<input** type="text" placeholder="请输入搜索关键词" v-model="keyword"**>**  
17.         **<table>**  
18.             **<tr>**  
19.                 **<th>**序号**</th>**  
20.                 **<th>**姓名**</th>**  
21.                 **<th>**邮箱**</th>**  
22.             **</tr>**  
23.             **<tr** v-for="(vip,index) of filterVips" :key="vip.id"**>**  
24.                 **<td>**{{index+1}}**</td>**  
25.                 **<td>**{{vip.name}}**</td>**  
26.                 **<td>**{{vip.email}}**</td>**  
27.             **</tr>**  
28.         **</table>**  
29.     **</div>**  
30.     **<script>**  
31.         const vm = new Vue({  
32.             el : '#app',  
33.             data : {  
34.                 keyword : '',  
35.                 msg : '列表过滤',  
36.                 vips : [  
37.                     {id:'100',name:'jack',email:'jack@123.com'},  
38.                     {id:'200',name:'lucy',email:'lucy@123.com'},  
39.                     {id:'300',name:'james',email:'james@123.com'}  
40.                 ],  
41.                 //filterVips : []  
42.             },  
43.             /* watch : {  
44.                 keyword : {  
45.                     immediate : true,  
46.                     handler(newValue, oldValue){  
47.                         this.filterVips = this.vips.filter((v) =**>** {  
48.                             return v.name.indexOf(newValue) **>**= 0  
49.                         })  
50.                     }  
51.                 }  
52.             }, */  
53.             computed : {  
54.                 filterVips(){  
55.                     return this.vips.filter((v) =**>** {  
56.                         return v.name.indexOf(this.keyword) **>**= 0  
57.                     })  
58.                 }  
59.             }  
60.         })  
61.     **</script>**  
62. **</body>**  
63. **</html>**

2.8 列表排序

<!DOCTYPE html**>**  
2. **<html** lang="en"**>**  
3. **<head>**  
4.     **<meta** charset="UTF-8"**>**  
5.     **<meta** http-equiv="X-UA-Compatible" content="IE=edge"**>**  
6.     **<meta** name="viewport" content="width=device-width, initial-scale=1.0"**>**  
7.     **<title>**列表排序**</title>**  
8.     **<script** src="../js/vue.js"**></script>**  
9.     **<style>**  
10.         table,tr,td,th{  
11.             border:1px solid black;  
12.         }  
13.     **</style>**  
14. **</head>**  
15. **<body>**  
16.     **<div** id="app"**>**  
17.         **<h1>**{{msg}}**</h1>**  
18.         **<input** type="text" placeholder="输入关键字搜索" v-model="keyword"**><br>**  
19.         **<button** @click="type = 1"**>**按照名字升序**</button><br>**  
20.         **<button** @click="type = 2"**>**按照名字降序**</button><br>**  
21.         **<button** @click="type = 0"**>**按照名字原始顺序**</button><br>**  
22.         **<table>**  
23.             **<tr>**  
24.                 **<th>**序号**</th>**  
25.                 **<th>**姓名**</th>**  
26.                 **<th>**邮箱**</th>**  
27.                 **<th>**操作**</th>**  
28.             **</tr>**  
29.             **<tr** v-for="(vip, index) in filterVips" :key="vip.id"**>**  
30.                 **<td>**{{index+1}}**</td>**  
31.                 **<td>**{{vip.name}}**</td>**  
32.                 **<td>**{{vip.email}}**</td>**  
33.                 **<td><input** type="checkbox"**></td>**  
34.             **</tr>**  
35.         **</table>**  
36.     **</div>**  
37.     **<script>**  
38.         const vm = new Vue({  
39.             el : '#app',  
40.             data : {  
41.                 msg : '列表排序',  
42.                 vips : [  
43.                     {id:'100',name:'jack',email:'jack@123.com'},  
44.                     {id:'200',name:'lucy',email:'lucy@123.com'},  
45.                     {id:'300',name:'james',email:'james@123.com'},  
46.                     {id:'400',name:'lilei',email:'lilei@123.com'},  
47.                 ],  
48.                 keyword : '',  
49.                 type : 0  
50.             },  
51.             computed : {  
52.                 filterVips(){  
53.                     // 筛选  
54.                     let arr = this.vips.filter((vip) =**>** {  
55.                         return vip.name.indexOf(this.keyword) **>**= 0  
56.                     })   
57.                     // 根据排序类型进行排序  
58.                     if(this.type){  
59.                         arr.sort((v1, v2) =**>** {  
60.                             console.log('@')  
61.                             return this.type == 1 ? v1.name.localeCompare(v2.name) : v2.name.localeCompare(v1.name)  
62.                         })  
63.                     }  
64.                     // 返回  
65.                     return arr  
66.                 }  
67.             }  
68.         })  
69.     **</script>**  
70. **</body>**  
71. </html>

2.9 收集表单数据

 <!DOCTYPE html**>**  
2. **<html** lang="en"**>**  
3. **<head>**  
4.     **<meta** charset="UTF-8"**>**  
5.     **<title>**收集表单数据**</title>**  
6.     **<script** src="../js/vue.js"**></script>**  
7. **</head>**  
8. **<body>**  
9.     **<div** id="app"**>**  
10.         **<h1>**{{msg}}**</h1>**  
11.         **<form** @submit.prevent="send"**>**  
12.             **<label** for="username"**>**用户名:**</label>**  
13.             **<input** id="username" type="text" v-model.trim="user.username"**><br><br>**  
14.             密码:**<input** type="password" v-model="user.password"**><br><br>**  
15.             年龄:**<input** type="number" v-model.number="user.age"**><br><br>**  
16.             性别:  
17.                 男**<input** type="radio" name="gender" v-model="user.gender" value="1"**>**  
18.                 女**<input** type="radio" name="gender" v-model="user.gender" value="0"**><br><br>**  
19.             爱好:  
20.                 运动**<input** type="checkbox" name="interest" value="sport" v-model="user.interest"**>**  
21.                 旅游**<input** type="checkbox" name="interest" value="travel" v-model="user.interest"**>**  
22.                 唱歌**<input** type="checkbox" name="interest" value="sing" v-model="user.interest"**><br><br>**  
23.             学历:  
24.                 **<select** v-model="user.grade"**>**  
25.                     **<option** value=""**>**请选择学历**</option>**  
26.                     **<option** value="zk"**>**专科**</option>**  
27.                     **<option** value="bk"**>**本科**</option>**  
28.                     **<option** value="ss"**>**硕士**</option>**  
29.                 **</select><br><br>**  
30.             简介:**<textarea** cols="30" rows="10" v-model.lazy="user.introduce"**></textarea><br><br>**  
31.             **<input** type="checkbox" v-model="user.isAgree"**>**阅读并接受协议**<br><br>**  
32.             **<button>**注册**</button>**  
33.         **</form>**  
34.     **</div>**  
35.     **<script>**  
36.         const vm = new Vue({  
37.             el : '#app',  
38.             data : {  
39.                 msg : '收集表单数据',  
40.                 user : {  
41.                     username : '',  
42.                     password : '',  
43.                     age : '',  
44.                     gender : '0',  
45.                     interest : ['sport'],  
46.                     grade : 'ss',  
47.                     introduce : '',  
48.                     isAgree : ''  
49.                 }  
50.             },  
51.             methods : {  
52.                 send(){  
53.                     console.log(JSON.stringify(this.user))  
54.                 }  
55.             }  
56.         })  
57.     **</script>**  
58. **</body>**  
59. **</html>** 

页面展示效果:

运行结果:

2.10 过滤器

过滤器filters适用于简单的逻辑处理,例如:对一些数据进行格式化显示。他的功能完全可以使用methods,computed来实现。过滤器可以进行全局配置,也可以进行局部配置:

  1. 全局配置:在构建任何Vue实例之前使用Vue.filter(‘过滤器名称’, callback)进行配置。
  2. 局部配置:在构建Vue实例的配置项中使用filters进行局部配置。

过滤器可以用在两个地方:插值语法和v-bind指令中。
多个过滤器可以串联:{{msg | filterA | filterB | filterC}}
过滤器也可以接收额外的参数,但过滤器的第一个参数永远接收的都是前一个过滤器的返回值。

2.11 Vue的其它指令

2.11.1 v-text

将内容填充到标签体当中,并且是以覆盖的形式填充,而且填充的内容中即使存在HTML标签也只是会当做一个普通的字符串处理,不会解析。功能等同于原生JS中的innerText。

2.11.2 v-html

将内容填充到标签体当中,并且是以覆盖的形式填充,而且将填充的内容当做HTML代码解析。功能等同于原生JS中的innerHTML。
v-html不要用到用户提交的内容上。可能会导致XSS攻击。XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript。
例如:用户在留言中恶意植入以下信息:

其他用户上当了:如果点击了以上的留言,就会将cookie发送给恶意的服务器。

2.11.3 v-cloak

v-cloak配置css样式来解决胡子的闪现问题。
v-cloak指令使用在标签当中,当Vue实例接管之后会删除这个指令。
这是一段CSS样式:当前页面中所有带有v-cloak属性的标签都隐藏起来。
[v-cloak] {
display : none;
}

2.11.4 v-once

初次接触指令的时候已经学过了。只渲染一次。之后将被视为静态内容。

2.11.5 v-pre

使用该指令可以提高编译速度。带有该指令的标签将不会被编译。可以在没有Vue语法规则的标签中使用可以提高效率。不要将它用在带有指令语法以及插值语法的标签中。

2.12 vue的自定义指令

函数式:
directives : {
‘text-reverse’ : function(element, binding){
// element 是真实dom对象(可以通过 element instanceof HTMLElement 判断)
// binding 是绑定的对象
element.innerText = binding.value.split(‘’).reverse().join(‘’)
}
}

函数调用时机:
第一时机:模板初次解析时(元素与指令初次绑定)。
第二时机:模板重新解析时。
对象式:可以使用对象式完成更加细致的功能。
directives : {
‘bind-parent’ : {
// 元素与指令初次绑定时自动调用。
bind(element, binding){},
// 元素已经被插入页面后自动调用。
inserted(element, binding){},
// 模板重新解析时被自动调用。
update(element, binding){}
}
}
自定义指令的函数中的this是window。
以上是局部指令,全局指令怎么定义:
对象式:
Vue.directive(‘bind-parent’, {
bind(element, binding){},
inserted(element, binding){},
update(element, binding){}
})
函数式:
Vue.directive(‘text-reverse’, function(element, binding){})

2.13 响应式与数据劫持

  1. 什么是响应式?

修改data后,页面自动改变/刷新。这就是响应式。就像我们在使用excel的时候,修改一个单元格中的数据,其它单元格的数据会联动更新,这也是响应式。

  1. Vue的响应式是如何实现的?

数据劫持:Vue底层使用了Object.defineProperty,配置了setter方法,当去修改属性值时setter方法则被自动调用,setter方法中不仅修改了属性值,而且还做了其他的事情,例如:重新渲染页面。setter方法就像半路劫持一样,所以称为数据劫持。

  1. Vue会给data中所有的属性,以及属性中的属性,都会添加响应式。
  2. 后期添加的属性,不会有响应式,怎么处理?
  3. Vue.set(目标对象, ‘属性名’, 值)
  4. vm.$set(目标对象, ‘属性名’, 值)
  5. Vue没有给数组下标0,1,2,3…添加响应式,怎么处理?
  6. 调用Vue提供的7个API:

push()
pop()
reverse()
splice()
shift()
unshift()
sort()
或者使用:
Vue.set(数组对象, ‘index’, 值)
vm.$set(数组对象, ‘index’, 值)

2.14 Vue的生命周期

2.14.1 什么是生命周期

所谓的生命周期是指:一个事物从出生到最终的死亡,整个经历的过程叫做生命周期。
例如人的生命周期:

  1. 出生:打疫苗
  2. 3岁了:上幼儿园
  3. 6岁了:上小学
  4. 12岁了:上初中
  5. …
  6. 55岁了:退休
  7. …
  8. 临终:遗嘱
  9. 死亡:火化

可以看到,在这个生命线上有很多不同的时间节点,在不同的时间节点上去做不同的事儿。

Vue的生命周期指的是:vm对象从创建到最终销毁的整个过程。

  1. 虚拟DOM在内存中就绪时:去调用一个a函数
  2. 虚拟DOM转换成真实DOM渲染到页面时:去调用一个b函数
  3. Vue的data发生改变时:去调用一个c函数
  4. …
  5. Vue实例被销毁时:去调用一个x函数

在生命线上的函数叫做钩子函数,这些函数是不需要程序员手动调用的,由Vue自动调用,程序员只需要按照自己的需求写上,到了那个时间点自动就会执行。

2.14.2 掌握Vue的生命周期有什么用

研究Vue的生命周期主要是研究:在不同的时刻Vue做了哪些不同的事儿。
例如:在vm被销毁之前,我需要将绑定到元素上的自定义事件全部解绑,那么这个解绑的代码就需要找一个地方写一下,写到哪里呢?你可以写到beforeDestroy()这个函数中,这个函数会被Vue自动调用,而且是在vm对象销毁前被自动调用。像这种在不同时刻被自动调用的函数称为钩子函数。每一个钩子函数都有对应的调用时间节点。
换句话说,研究Vue的生命周期主要研究的核心是:在哪个时刻调用了哪个钩子函数。

2.14.3 Vue生命周期的4个阶段8个钩子

Vue的生命周期可以被划分为4个阶段:初始阶段、挂载阶段、更新阶段、销毁阶段。
每个阶段会调用两个钩子函数。两个钩子函数名的特点:beforeXxx()、xxxed()。
8个生命周期钩子函数分别是:

  1. 初始阶段
    1. beforeCreate() 创建前
    2. created() 创建后
  2. 挂载阶段
    1. beforeMount() 挂载前
    2. mounted() 挂载后
  3. 更新阶段
    1. beforeUpdate() 更新前
    2. updated() 更新后
  4. 销毁阶段
    1. beforeDestroy() 销毁前
    2. destroyed() 销毁后

8个钩子函数写在哪里?直接写在Vue构造函数的options对象当中。
Vue官方的生命周期图:

翻译后的生命周期图:

2.14.4 初始阶段做了什么事儿

做了这么几件事:

  1. 创建Vue实例vm(此时Vue实例已经完成了创建,这是生命的起点)
  2. 初始化事件对象和生命周期(接产大夫正在给他洗澡)
  3. 调用beforeCreate()钩子函数(此时还无法通过vm去访问data对象的属性)
  4. 初始化数据代理和数据监测
  5. 调用created()钩子函数(此时数据代理和数据监测创建完毕,已经可以通过vm访问data对象的属性)
  6. 编译模板语句生成虚拟DOM(此时虚拟DOM已经生成,但页面上还没有渲染)

该阶段适合做什么?
beforeCreate:可以在此时加一些loading效果。
created:结束loading效果。也可以在此时发送一些网络请求,获取数据。也可以在这里添加定时器。

2.14.5 挂载阶段做了什么事儿

做了这么几件事:

  1. 调用beforeMount()钩子函数(此时页面还未渲染,真实DOM还未生成)
  2. 给vm追加 e l 属性,用它来代替” e l ”, el属性,用它来代替”el”, el属性,用它来代替”el”,el代表了真实的DOM元素(此时真实DOM生成,页面渲染完成)
  3. 调用mounted()钩子函数

该阶段适合做什么?
mounted:可以操作页面的DOM元素了。

2.14.6 更新阶段做了什么事儿

做了这么几件事:

  1. data发生变化(这是该阶段开始的标志)
  2. 调用beforeUpdate()钩子函数(此时只是内存中的数据发生变化,页面还未更新)
  3. 虚拟DOM重新渲染和修补
  4. 调用updated()钩子函数(此时页面已更新)

该阶段适合做什么?
beforeUpdate:适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
updated:页面更新后,如果想对数据做统一处理,可以在这里完成。

2.14.7 销毁阶段做了什么事儿

做了这么几件事:

  1. vm.$destroy()方法被调用(这是该阶段开始的标志)
  2. 调用beforeDestroy()钩子函数(此时Vue实例还在。虽然vm上的监视器、vm上的子组件、vm上的自定义事件监听器还在,但是它们都已经不能用了。此时修改data也不会重新渲染页面了)
  3. 卸载子组件和监视器、解绑自定义事件监听器
  4. 调用destroyed()钩子函数(虽然destroyed翻译为已销毁,但此时Vue实例还在,空间并没有释放,只不过马上要释放了,这里的已销毁指的是vm对象上所有的东西都已经解绑完成了)

该阶段适合做什么?
beforeDestroy:适合做销毁前的准备工作,和人临终前写遗嘱类似。例如:可以在这里清除定时器。

动力节点Vue3笔记——第二章Vue核心技术 函数式:// element 是真实dom对象(可以通过 element instanceof HTMLElement 判断)// binding 是绑定的对象函数调用时机:第一时机:模板初次解析时(元素与指令初次绑定)。第二时机:模板重新解析时。对象式:可以使用对象式完成更加细致的功能。// 元素与指令初次绑定时自动调用。// 元素已经被插入页面后自动调用。// 模板重新解析时被自动调用。自定义指令的函数中的this是window。 阅读详情

相关推荐

动力节点老杜Vue3视频笔记——Vue程序初体验

可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的,对我们编写Vue程序起不到太大的作用,更何况现在说了一些特点之后,我们也没有办法彻底理解它,因此我们可以先学会用,使用一段时间之后,回头来熟悉一下Vue框架以及它的特点。以上程序执行原理:Vue编译器对template进行编译,遇到胡子{{}}时从data中取数据,然后将取到的数据插到对应的位置。第二:虽然是直接写到HTML代码当中的,但以上程序中第3~6行已经不是HTML代码了,它是具有Vue语法特色的模板语句。

A_coding的博客 458

Vue3全家桶新版.md

作用: 对多个组件重复的功能进行提取封装使用Vue3的组合API封装的可复用的功能函数自定义hook的作用类似于vue2中的mixin技术自定义Hook的优势: 很清楚复用功能代码的来源, 更清楚易懂用来实现子组件向父组件通信EventTest.vue组件<template>--区别原生事件与自定义事件原生事件原生标签上绑定 / 组件标签上绑定加.native事件名是特定的一些。

讨口子 879

动力节点老杜Vue视频笔记——第二章 Vue核心技术

动力节点Vue笔记第二章 Vue核心技术 20/100 发布文章 assdfgdfgjhtdo 未选择任何文件 new.stop - 调用 event.stopPropagation()。 .prevent - 调用 event.preventDefault()。 .capture - 添加事件侦听器时使用 capture 模式。 注意:只有添加了capture修饰符的元素才会采用捕获模式。(或者说带有capture修饰符的优先触发).self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。 .on

A_coding的博客 819

Vue3的md笔记

把setup的组合式API进行封装,实现代码复用。–创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。–不指明监视哪个属性。监视的回调中用到哪个属性就监视哪个属性。–在异步组件加载完成之前,展示一些占位符内容,避免页面空白。学习vue3过程中的一些笔记,记录自己对知识点的理解。–将组件html结构移动到指定位置。–能让代码易读和易写。–将对象中的属性单独提供给外部使用。–一个函数,是vue3新的配置项。–定义一个对象类型的响应式数据。–浅响应式,针对对象。–是vuex的替代品。

Y27896的博客 442

动力节点|Vue3实用教程,一套搞定前端框架Vue2+3

•024.Vue数据代理时对属性名的要求.avi.baiduyun.uploading。•026.手写Vue框架数据代理的实现.avi.baiduyun.uploading。•034.关于事件回调函数中的this.avi.baiduyun.uploading。•028.Vue框架源代码解读.avi.baiduyun.uploading。•022.数据代理机制的实现.avi.baiduyun.uploading。•032.Vue的事件绑定.avi.baiduyun.uploading。

java_yydsyyds的博客 459

动力节点Vue笔记第七章vue3

绑定事件触发事件将组合式API拿出来,封装成一个函数,在需要复用的位置,使用这个hook函数。一般创建一个hooks目录,在hooks目录当中放hook函数。代码复用。

Java_Leo12的博客 364

Vue3 核心技术

Vue基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。

qq_51271926的博客 578

动力节点老杜Vue框架教程【一】Vue程序初体验

Vue.js是一个渐进式 MVVM 框架,目前被广泛使用,也成为前端中最火爆的框架Vue可以按照实际需要逐步进阶使用更多特性,也是前端的必备技能动力节点老杜的Vue2+3全家桶教程已经上线咯!学习地址:https://www.bilibili.com/video/BV17h41137i4/视频将从Vue2开始讲解,一步一个案例,知识点由浅入深,然后很自然的过度到Vue3版本。每一个Vue的知识点讲解的非常通透,不但举例告诉你怎么用,还会告诉你底层实现原理。

2301_76637473的博客 301

Web前端学习笔记18:Vue_常用指令_常用特性

文章目录day01Vue 是什么?使用Vue将helloworld 渲染到页面上指令v-cloakv-textv-htmlv-pre**v-once**双向数据绑定v-modelmvvmv-onv-on事件函数中传入参数事件修饰符按键修饰符自定义按键修饰符别名v-bind绑定对象绑定class绑定对象和绑定数组 的区别绑定style分支结构v-if 使用场景v-show 和 v-if的区别循环结构v-for案例选项卡1、 HTML 结构2、 提供的数据3、 把数据渲染到页面4、 给每一个tab栏添加事件,

JasonYangQ的博客 9445

手把手教你用Matlab解析Zygo .dat文件:从二进制数据到面形图(附完整流程)

本文详细介绍了如何使用Matlab解析Zygo干涉仪生成的.dat文件,从二进制数据读取到面形图可视化的完整流程。通过实例代码演示了文件结构解析、数据矩阵读取、高阶Zernike拟合等关键技术,帮助工程师和研究人员高效处理光学检测数据,提升分析精度和工作效率。

weixin_30731305的博客 449

优化Cartographer重定位速度:从子图筛选到参数调优的完整思路

本文详细介绍了优化Cartographer重定位速度的完整方法,从子图筛选到参数调优,帮助工程师在已知初始位姿的前提下将重定位耗时降低50%以上。重点分析了性能瓶颈、子图筛选策略、匹配算法选择及环境自适应的参数优化策略,并通过实战案例展示了显著效果提升。

weixin_28704565的博客 464

Vue笔记第七章vue3【动力节点】

绑定事件触发事件将组合式API拿出来,封装成一个函数,在需要复用的位置,使用这个hook函数。一般创建一个hooks目录,在hooks目录当中放hook函数。代码复用。

assdfgdfgjhtdo的博客 1475

NVMe与PCIe的完美结合:高速存储背后的技术解析

本文深入解析了NVMe与PCIe技术如何完美结合,实现高速存储性能的飞跃。从机械硬盘到NVMe SSD的进化历程出发,详细介绍了PCIe总线的高带宽优势与NVMe协议的低延迟设计,以及两者协同工作带来的显著性能提升。通过实测数据对比,展示了NVMe SSD在消费级和企业级应用中的卓越表现,并提供了选购与优化建议。

weixin_29216353的博客 376

动力节点杜老师Vue笔记——2、Vue核心技术

函数式:// element 是真实dom对象(可以通过 element instanceof HTMLElement 判断)// binding 是绑定的对象函数调用时机:第一时机:模板初次解析时(元素与指令初次绑定)。第二时机:模板重新解析时。对象式:可以使用对象式完成更加细致的功能。// 元素与指令初次绑定时自动调用。// 元素已经被插入页面后自动调用。// 模板重新解析时被自动调用。自定义指令的函数中的this是window。

Java_Coding1的博客 750

Zynq远程更新程序实战:从emmc到flash的完整方案解析

本文详细解析了Zynq远程更新程序的完整方案,重点探讨了从emmc到flash的实战操作。通过硬件连接限制破解、emmc配置技巧、flash擦写策略优化等关键技术点,提供了可靠的远程更新解决方案,特别适合需要频繁更新boot.bin的应用场景。

weixin_29163797的博客 179

【目标检测-YOLO】YOLOv5-v5.0-yolov5s网络架构详解(第一篇)

源码:GitHub - ultralytics/yolov5 at v5.0 由于YOLO v5 代码库在持续更新,如上图,有多个版本,每个版本的网络结构不尽相同。以下内容以 v5.0 为准,网络结构选用 yolov5s。 为了方便画图和理解网络结构,选用可视化工具:Netron 网页版进行可视化, 然后使用PPT作图。 在Releases · ultralytics/yolov5 · GitHub找到 v5.0中的Assets 中的yolov5s.pt并下载该权重。 下图为直接......

博观约取,厚积薄发 2万+

【动力节点】杜老师Vue笔记第七章vue3

绑定事件触发事件将组合式API拿出来,封装成一个函数,在需要复用的位置,使用这个hook函数。一般创建一个hooks目录,在hooks目录当中放hook函数。代码复用。

weixin_54585403的博客 1631

基于知识图谱的农作物病虫害问答系统设计与实现

基于规则的问题分类是自问答系统诞生以来就一直存在的方式,主要代表就是众多的专家系统,构建专家系统采用的是规则分类器,优点是能够对特定领域、特征明显的问题进行高效精准问答,但是。,在问答系统中,问题以语音及文本字符等自然语言形式输入,利用问答系统的内部的逻辑处理模块,通过自然语言处理技术获得输入问句的详细语义信息,再经过知识检索、置信分析等步骤,自然语言处理中,用于文本分类任务的机器学习方式有两种,一种用传统的机器学习,如 NBC、SVM 等,另一种采用深度学习,如 CNN 和 RNN 等。

全网粉丝30W+,优快云、稀土掘金人工智能领域签约作者,人工智能、大模型、Python 爬虫,商务合作,请私信沟通。 2166

动力节点老杜Vue框架教程【二】Vue核心技术

函数式:// element 是真实dom对象(可以通过 element instanceof HTMLElement 判断)// binding 是绑定的对象函数调用时机:第一时机:模板初次解析时(元素与指令初次绑定)。第二时机:模板重新解析时。对象式:可以使用对象式完成更加细致的功能。// 元素与指令初次绑定时自动调用。// 元素已经被插入页面后自动调用。// 模板重新解析时被自动调用。自定义指令的函数中的this是window。

2301_76637473的博客 374

31.XAPP1052乱序分析及处理

目录 1.XAPP1052乱序分析 2.XAPP1052乱序处理 2.1乱序处理方法选择 2.2 XAPP1052乱序处理代码详解 3.XAPP1052乱序处理后的波形分析 3.1发送引擎 3.2接收引擎 4.XAPP1052乱序处理后的带宽测试 5.下期内容 1.XAPP1052乱序分析 首先先给大家讲解下什么是PCIe的乱序。在PCIe系统中,乱序就是主机发送的TLP序列ID为1、2、3、4到从机,从机接收到的可能不是1、2、3、4。主机和从机如果都不解决乱序的问题,就会导致从机接

一个早起的程序员 1707

16、天文时间序列分类:基于人工神经网络的研究

本研究探讨了基于人工神经网络的天文时间序列分类方法,重点比较了MLP、LSTM和CNN等模型在BRITE和开普勒K2数据集上的表现。研究发现LSTM不适用于此类数据,而结合特征提取与PSO超参数优化的多层感知器(MLP)在开普勒K2数据上实现了98.55%的二分类准确率。通过精细的数据预处理和高置信度样本选择,显著提升了分类性能。研究成果为恒星变异性识别提供了高效工具,并对天文学与机器学习交叉领域具有重要参考价值。

pz8901234的博客 113

动力节点Vue笔记第七章

绑定事件触发事件将组合式API拿出来,封装成一个函数,在需要复用的位置,使用这个hook函数。一般创建一个hooks目录,在hooks目录当中放hook函数。代码复用。

Java_Coding1的博客 922

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

动力节点|Vue2+3全家桶教程,一套通关前端最火框架

•024.Vue数据代理时对属性名的要求.avi.baiduyun.uploading。•026.手写Vue框架数据代理的实现.avi.baiduyun.uploading。•034.关于事件回调函数中的this.avi.baiduyun.uploading。•028.Vue框架源代码解读.avi.baiduyun.uploading。•022.数据代理机制的实现.avi.baiduyun.uploading。•032.Vue的事件绑定.avi.baiduyun.uploading。

hujidedf的博客 291

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

动力节点Vue笔记第二章 Vue核心技术

函数式:// element 是真实dom对象(可以通过 element instanceof HTMLElement 判断)// binding 是绑定的对象函数调用时机:第一时机:模板初次解析时(元素与指令初次绑定)。第二时机:模板重新解析时。对象式:可以使用对象式完成更加细致的功能。// 元素与指令初次绑定时自动调用。// 元素已经被插入页面后自动调用。// 模板重新解析时被自动调用。自定义指令的函数中的this是window。

assdfgdfgjhtdo的博客 411

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

动力节点Vue3笔记——Vue程序初体验

可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的,对我们编写Vue程序起不到太大的作用,更何况现在说了一些特点之后,我们也没有办法彻底理解它,因此我们可以先学会用,使用一段时间之后,回头来熟悉一下Vue框架以及它的特点。以上程序执行原理:Vue编译器对template进行编译,遇到胡子{{}}时从data中取数据,然后将取到的数据插到对应的位置。第二:虽然是直接写到HTML代码当中的,但以上程序中第3~6行已经不是HTML代码了,它是具有Vue语法特色的模板语句。

Java_Coding1的博客 704

动力节点Vue3课程笔记——四、Vue与AJAX

原理:访问地址是http://localhost:8080/bugs,会优先去8080服务器上找/bugs资源,如果没有找到才会走代理。(11)在Search组件中触发事件的时候,将多个属性封装为对象的形式(语义化更明确)传给Weather组件。第三方库方式,基于Promise的HTTP库:axios (对XMLHttpRequest进行的封装)(7)初次打开页面的时候,不应该显示天气的任何信息,Weather组件应该是隐藏的。(9)如果访问的城市不存在时,应该提示“对不起,请检查城市名”

assdfgdfgjhtdo的博客 860
上一篇: 动力节点Vue3学习笔记一、Vue程序初体验
下一篇: 动力节点老杜Vue课程笔记——三、Vue组件化
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值