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> const app = Vue.createApp({ 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 } } } })
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> const app = Vue.createApp({ data: function() { return { name: "class" } }, })
app.mount("#app") </script>
|
绑定对象
如果我们希望将一个对象的所有属性,绑定到元素上的所有属性
<div id="app"> <!-- v-bind绑定对象: 给组件传递参数 --> <h2 v-bind="infos">Hello Bind</h2> </div>
<script src="../lib/vue.js"></script> <script> const app = Vue.createApp({ data: function() { return { infos: { name: "fredo", age: 18, height: 1.88, address: "广州市" }, } }, })
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> const app = Vue.createApp({ data: function() { return { message: "Hello Vue", age: 18 } }, methods: { btn1Click(event) { console.log("btn1Click:", event) },
btn2Click(name, age) { console.log("btn2Click:", name, age) },
btn3Click(name, age, event) { console.log("btn3Click:", name, age, event) } } })
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 不会被渲染出来
<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>
|
支持数字的遍历
<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 不存在的元素