v-bind

一系列指令,主要是将值插入到模板内容中, 但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定

  • 比如动态绑定 a 元素的 href 属性
  • 比如动态绑定 img 元素的 src 属性

绑定属性用法

使用 v-bind:

  • 缩写成:**:**
  • 预期:any (with argument) | Object (without argument)
  • 参数:attrOrProp (optional)
  • 修饰符
    • .camel - 将 kebab-case attribute 名转换为 camelCase
  • 用法:动态地绑定一个或多个 attribute,或者一个组件 prop 到表达式

绑定基本属性

可以绑定一个或多个属性值,或者向另一个组件传递 props 值

  • 比如图片的链接 src、网站的链接 href、动态绑定一些类、样式等等
  • v-bind 有一个对应的语法糖,也就是简写方式
  • 在开发中,我们通常会使用语法糖的形式,因为这样更加简洁
<!-- 1.绑定img的src属性 -->
<img v-bind:src="showImgUrl" alt="">
<!-- 语法糖: v-bind -> : -->
<img :src="showImgUrl" alt="">

<!-- 2.绑定a的href属性 -->
<a :href="href">百度一下</a>

绑定 class

使元素 class 变成动态的

绑定 class 有两种方式:

  • 对象语法
  • 数组语法

对象语法

  • 传给 :class (v-bind: class 的简写) 一个对象,以动态地切换 class
<div id="app">
<!-- 1.基本绑定class -->
<h2 :class="classes">Hello World</h2>

<!-- 2.动态class可以写对象语法 -->
<button :class=" isActive ? 'active': '' " @click="btnClick">我是按钮</button>

<!-- 2.1.对象语法的基本使用 -->
<button :class="{ active: isActive }" @click="btnClick">我是按钮</button>

<!-- 2.2.对象语法的多个键值对 -->
<button :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">我是按钮</button>

<!-- 2.3.动态绑定的class是可以和普通的class同时的使用 -->
<button class="abc cba" :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">我是按钮</button>

<!-- 2.4.动态绑定的class是可以和普通的class同时的使用 -->
<button class="abc cba" :class="getDynamicClasses()" @click="btnClick">我是按钮</button>

<!-- 3.动态class可以写数组语法(了解) -->
<h2 :class="['abc', 'cba']">Hello Array</h2>
<h2 :class="['abc', className]">Hello Array</h2>
<h2 :class="['abc', className, isActive? 'active': '']">Hello Array</h2>
<h2 :class="['abc', className, { active: isActive }]">Hello Array</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
classes: "abc cba nba",
isActive: false,
className: "why"
}
},

methods: {
btnClick: function() {
this.isActive = !this.isActive
},

getDynamicClasses: function() {
return { active: this.isActive, why: true, kobe: false }
}
}
})

// 2.挂载app
app.mount("#app")
</script>

绑定 style

可以利用 v-bind: style 来绑定一些 CSS 内联样式:

  • 根据数据动态来决定
  • 比如某段文字的颜色,大小等等

CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名

绑定 class 有两种方式

  • 对象语法
  • 数组语法
<div id="app">
<!-- 1.普通的html写法 -->
<h2 style="color: red; font-size: 30px;">哈哈哈哈</h2>

<!-- 2.style中的某些值, 来自data中 -->
<!-- 2.1.动态绑定style, 在后面跟上 对象类型 (重要)-->
<h2 v-bind:style="{ color: fontColor, fontSize: fontSize + 'px' }">哈哈哈哈</h2>
<!-- 2.2.动态的绑定属性, 这个属性是一个对象 -->
<h2 :style="objStyle">呵呵呵呵</h2>

<!-- 3.style的数组语法 -->
<h2 :style="[objStyle, { backgroundColor: 'purple' }]">嘿嘿嘿嘿</h2>
</div>

动态绑定属性

在某些情况下,我们属性的名称可能也不是固定的:

  • 前面无论绑定 src、href、class、style,属性名称都是固定的
  • 如果属性名称不是固定的,我们可以使用 :[属性名]=“值” 的格式来定义
  • 即动态绑定属性
<div id="app">
<h2 :[name]="'aaaa'">Hello World</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
name: "class"
}
},
})

// 2.挂载app
app.mount("#app")
</script>

绑定对象

如果我们希望将一个对象的所有属性,绑定到元素上的所有属性

  • 直接使用 v-bind 绑定一个对象语法
<div id="app">
<!-- v-bind绑定对象: 给组件传递参数 -->
<h2 v-bind="infos">Hello Bind</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
infos: { name: "fredo", age: 18, height: 1.88, address: "广州市" },
}
},
})

// 2.挂载app
app.mount("#app")
</script>

v-on

开发中,我们需要经常和用户进行各种各样的交互

  • 须监听用户发生的事件,比如点击、拖拽、键盘事件等等
  • 使用 v-on 指令即可

语法

绑定事件监听

  • 缩写:@
  • 预期:Function | Inline Statement | Object
  • 参数:event
  • 修饰符:
    • .stop - 调用 event. stopPropagation ()
    • .prevent - 调用 event. preventDefault ()
    • .capture - 添加事件侦听器时使用 capture 模式
    • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调
    • .{keyAlias} - 仅当事件是从特定键触发时才触发回调
    • .once - 只触发一次回调
    • .left - 只当点击鼠标左键时触发
    • .right - 只当点击鼠标右键时触发
    • .middle - 只当点击鼠标中键时触发
    • .passive - { passive: true } 模式添加侦听器

演示

  • 使用 v-on 来监听一下点击的事件:
    • 不推荐绑定表达式, 建议绑定方法
  • v-on:click 可以写成@click,是它的语法糖写法:
  • 绑定其他的事件
  • 绑定多个事件
    • 传入一个对象
<div id="app">
<!-- 1.基本的写法 -->
<div class="box" v-on:click="divClick"></div>

<!-- 2.语法糖写法 -->
<div class="box" @click="divClick"></div>

<!-- 3.绑定的方法位置, 也可以写成一个表达式(不常用, 不推荐) -->
<h2>{{ counter }}</h2>
<button @click="increment">+1</button>
<button @click="counter++">+1</button>

<!-- 4.绑定其他方法 -->
<div class="box" @mousemove="divMousemove"></div>

<!-- 5.元素绑定多个事件 -->
<div class="box" @click="divClick" @mousemove="divMousemove"></div>
<!-- <div class="box" v-on="{ click: divClick, mousemove: divMousemove }"></div> -->
<!-- <div class="box" @="{ click: divClick, mousemove: divMousemove }"></div> -->
</div>

参数传递

情况一:如果该方法不需要额外参数,那么方法后的 () 可以不添加

  • 但是:如果方法本身中有一个参数,那么会默认将原生事件 event 参数传递进去

情况二:如果需要同时传入某个参数,同时需要 event 时,可以通过 $event 传入事件

<div id="app">
<!-- 1.默认传递event对象 -->
<button @click="btn1Click">按钮1</button>

<!-- 2.只有自己的参数 -->
<button @click="btn2Click('fredo', age)">按钮2</button>

<!-- 3.自己的参数和event对象 -->
<!-- 在模板中想要明确的获取event对象: $event -->
<button @click="btn3Click('fredo', age, $event)">按钮3</button>
</div>

<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue",
age: 18
}
},
methods: {
// 1.默认参数: event对象
// 总结: 如果在绑定事件的时候, 没有传递任何的参数, 那么event对象会被默认传递进来
btn1Click(event) {
console.log("btn1Click:", event)
},

// 2.明确参数:
btn2Click(name, age) {
console.log("btn2Click:", name, age)
},

// 3.明确参数+event对象
btn3Click(name, age, event) {
console.log("btn3Click:", name, age, event)
}
}
})

// 2.挂载app
app.mount("#app")
</script>

修饰符

修饰符相当于对事件进行了一些特殊的处理

  • .stop - 调用 event. stopPropagation ()
    • 阻止冒泡行为
    • 冒泡: 在子 div 中绑定事件, 触发后父 div 也会触发
    • 比如下面: 按钮在 div 内部, 但是点击按钮也会触发 div 点击事件
    • 对按钮进行 .stop 就会阻止冒泡
<div id="app">
<div class="box" @click="divClick">
<button @click.stop="btnClick">按钮</button>
</div>
</div>
  • .prevent - 调用 event. preventDefault ()
  • .capture - 添加事件侦听器时使用 capture 模式
  • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调
  • .{keyAlias} - 仅当事件是从特定键触发时才触发回调
  • .once - 只触发一次回调
  • .left - 只当点击鼠标左键时触发
  • .right - 只当点击鼠标右键时触发
  • .middle - 只当点击鼠标中键时触发
  • .passive - { passive: true } 模式添加侦听器

v-if

在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,这个时候我们就需要进行条件判断

Vue 提供了下面的指令来进行条件判断:

  • v-if
  • v-else
  • v-else-if
  • v-show

v-if、v-else、v-else-if 用于根据条件来渲染某一块的内容

  • 这些内容只有在条件为 true 时,才会被渲染出来
  • 这三个指令与 JavaScript 的条件语句 if、else、else if 类似
<div id="app">
<h1 v-if="score > 90">优秀</h1>
<h2 v-else-if="score > 80">良好</h2>
<h3 v-else-if="score >= 60">及格</h3>
<h4 v-else>不及格</h4>
</div>

注意:

  • v-if 是惰性的;
  • 当条件为 false 时,其判断的内容完全不会被渲染或者会被销毁掉
  • 当条件为 true 时,才会真正渲染条件块中的内容

template 元素

Vue 3. x 中新增元素

因为 v-if 是一个指令,所以必须将其添加到一个元素上

  • 但是如果我们希望切换的是多个元素呢
  • 此时我们渲染 div,但是我们并不希望 div 这种元素被渲染
  • 这个时候,我们可以选择使用 template

template 元素可以当做不可见的包裹元素,并且在 v-if 上使用,若条件不成立则最终 template 不会被渲染出来

  • 有点类似于小程序中的 block
<div id="app">
<!-- v-if="条件" -->
<template v-if="Object.keys(info).length">
<h2>个人信息</h2>
<ul>
<li>姓名: {{info.name}}</li>
<li>年龄: {{info.age}}</li>
</ul>
</template>

<!-- v-else -->
<template v-else>
<h2>没有输入个人信息</h2>
<p>请输入个人信息后, 再进行展示~</p>
</template>
</div>

v-show

和 v-if 的用法看起来是一致的,也是根据一个条件决定是否显示元素或者组件

<div id="app">
<div>
<button @click="toggle">切换</button>
</div>

<div v-show="isShowCode">
<img src="https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg" alt="">
</div>

<div v-if="isShowCode">
<img src="https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg" alt="">
</div>
</div>

用法的区别:

  • v-show 是不支持 template
  • v-show 不可以和 v-else 一起使用

本质的区别:

  • v-show 元素无论是否需要显示到浏览器上,它的 DOM 实际都是有存在的,只是通过 CSS 的 display 属性 (将值改成 none ) 来进行切换
  • v-if 当条件为 false 时,其对应的原生压根不会被渲染到 DOM中

如何选择

  • 如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用 v-show
  • 如果不会频繁的发生切换,那么使用 v-if

v-for

开发中,我们往往会从服务器拿到一组数据,并且需要对其进行渲染

  • 可以使用 v-for 来完成
  • 类似于 JavaScript 的 for 循环,可以用于遍历一组数据

基本使用

基本格式是 “item in 数组名

  • 数组通常是来自 data 或者 prop,也可以是其他方式 (计算出)
  • item 是我们给每项元素起的一个别名,这个别名可以自定来定义
<!-- 1.电影列表进行渲染 -->
<h2>电影列表</h2>
<ul>
<li v-for="movie in movies">{{ movie }}</li>
</ul>

在遍历一个数组的时候会经常需要拿到数组的索引

  • 如果我们需要索引,可以使用格式: “ (item, index) in 数组”
  • 注意顺序:数组元素项 item 是在前面的,索引项 index 是在后面的
<!-- 2.电影列表同时有索引 -->
<ul>
<li v-for="(movie, index) in movies">{{index + 1}} - {{ movie }}</li>
</ul>

支持的类型

支持遍历对象,并且支持有一二三个参数

  • 一个参数: “value in object”
  • 二个参数: “ (value, key) in object”
  • 三个参数: “ (value, key, index) in object”
<!-- 遍历对象 -->
<ul>
<li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
</ul>

支持数字的遍历

  • 每一个 item 都是一个数字
<ul>
<li v-for="item in 10">{{ item }}</li>
</ul>

可以遍历其他可迭代对象 (Iterable)

数组更新检测

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新

这些被包裹过的方法包括:

  • push ()
  • pop ()
  • shift ()
  • unshift ()
  • splice ()
  • sort ()
  • reverse()

注意:

上面的方法会直接修改原来的数组

但是某些方法不会替换原来的数组,而是会生成新的数组,比如 filter()、concat() 和 slice()

v-for 中的 key

在使用 v-for 进行列表渲染时,我们通常会给元素或者组件绑定一个 key 属性

这个 key 属性有什么作用呢?官方的解释:

  • key 属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes
  • 如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法
  • 而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除/销毁 key 不存在的元素