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

发布时间 2023-04-25 15:20:59作者: Banlance

Vue.js是一个渐进式 MVVM 框架,目前被广泛使用,也成为前端中最火爆的框架

Vue可以按照实际需要逐步进阶使用更多特性,也是前端的必备技能

动力节点老杜的Vue2+3全家桶教程已经上线咯!

学习地址:https://www.bilibili.com/video/BV17h41137i4/

视频将从Vue2开始讲解,一步一个案例,知识点由浅入深,然后很自然的过度到Vue3版本。

每一个Vue的知识点讲解的非常通透,不但举例告诉你怎么用,还会告诉你底层实现原理。

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 事件修饰符

  1. .stop - 调用 event.stopPropagation()。

  2. <div @click="san">

  3. **<div** @click.stop="er"**>**  
    
  4.     **<button** @click="yi"**>**{{name}}**</button>**  
    
  5. **</div>**  
    
  6. .prevent - 调用 event.preventDefault()。

  7. <a href="http://www..com" @click.prevent="yi">

  8. {{name}}

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

  10. <div @click.capture="san">

  11. **<div** @click.capture="er"**>**  
    
  12.     **<button** @click="yi"**>**{{name}}**</button>**  
    
  13. **</div>**  
    

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

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

  2. <div @click="san">

  3. **<div** @click.self="er"**>**  
    
  4.     **<button** @click="yi"**>**{{name}}**</button>**  
    
  5. **</div>**  
    
  6. .once - 只触发一次回调。

  7. <button @click.once="yi">

  8. {{name}}  
    
  9. .passive - (2.3.0) 以 { passive: true } 模式添加侦听器

    1. 无需等待,直接继续(立即)执行事件默认行为。(对wheel事件有效果)
    2. .passive 和 .prevent 修饰符不能共存。

2.1.3 按键修饰符

  1. 常用的按键修饰符包括:
    1. .enter
    2. .tab (只能配合keydown使用)
    3. .delete (捕获“删除”和“退格”键)
    4. .esc
    5. .space
    6. .up
    7. .down
    8. .left
    9. .right
  2. 可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

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

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

Vue.config.keyCodes.huiche = 13

2.1.4 系统修饰键

  1. 系统修饰键包括4个
  2. .ctrl
  3. .alt
  4. .shift
  5. .meta
  6. 系统修饰键在使用时应注意:
    1. 只有当系统修饰键和其他键组合使用,并且组合键释放时,才会触发keyup事件。
    2. 只要按下系统修饰键,就会触发keydown事件。
  7. 小技巧
    1. <input type=”text” @keyup.ctrl.c=”getInfo”/>

2.2 计算属性

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

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

  1. 计算属性的使用

  2. <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. 计算属性需要使用:computed

  10. 计算属性通过vm.$data 是无法访问的。计算属性不能通过vm.$data访问。

  11. 计算属性的getter/setter方法中的this是vm。

  12. 计算属性的getter方法的调用时机:

    1. 第一个时机:初次访问该属性。
    2. 第二个时机:计算属性所依赖的数据发生变化时。
  13. 计算属性的setter方法的调用时机:

    1. 当计算属性被修改时。(在setter方法中通常是修改属性,因为只有当属性值变化时,计算属性的值就会联动更新。注意:计算属性的值被修改并不会联动更新属性的值。)
  14. 计算属性没有真正的值,每一次都是依赖data属性计算出来的。

  15. 计算属性的getter和setter方法不能使用箭头函数,因为箭头函数的this不是vm。而是window。

  16. 计算属性的简写形式

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

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

2.3 侦听属性的变化

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

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

  1. <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}}  
    

运行效果:


  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 绑定字符串

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

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

运行效果:

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

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

2.4.1.2 绑定数组

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

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

运行效果:

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

2.4.1.3 绑定对象

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

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

运行效果:

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

2.4.2 style绑定

2.4.2.1 绑定对象

  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>**  
    

2.4.2.2 绑定数组

  1. <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>**  
    

2.5 条件渲染

2.5.1 v-if

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

  1. <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>**  
    

运行效果:

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元素后面。

  1. <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>**  
    

2.5.3