378 vue 之 事件修饰符,按键修饰符,v-if 和 v-show,计算属性 computed,key,条件渲染指令 v-else 和 v-else-if
七、事件修饰符
01-事件修饰符.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.fa {
width: 70px;
height: 70px;
margin-bottom: 10px;
background: green;
text-align: center;
}
button {
margin-top: 20px;
text-align: center;
}
</style>
</head>
<body>
<!--
事件修饰符
1. 事件.prevent: 阻止默认行为
2. 事件.stop: 阻止冒泡
3. 事件.capture: 捕获
4. 事件.self: 点击自己才会被触发
5. 事件.once: 点击只触发一次
6. 事件.passive: 移动端提高性能
-->
<div id="app">
<a href="https://baidu.com" @click.prevent="fn0">链接</a>
<hr>
<!-- 点击按钮,输出fn2,说明阻止了冒泡。如果去掉stop,则输出fn2、fn1。 -->
<div class="fa" @click="fn1">
<button class="btn" @click.stop='fn2'>按钮</button>
</div>
<!-- 点击按钮,先后输出fn2、fn1,说明先后执行fn2、fn1 -->
<div class="fa" @click="fn1">
<button @click.capture='fn2'>按钮</button>
</div>
<!-- 点击按钮,先后输出fn1、fn2,说明先后执行fn1、fn2 -->
<div class="fa" @click.capture="fn1">
<button @click='fn2'>按钮</button>
</div>
<div class="fa" @click.self="fn1">
<button @click='fn2'>按钮</button>
</div>
<div class="fa" @click="fn1">
<button @click.once='fn2'>按钮</button>
</div>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: ''
},
methods: {
fn0() {
console.log('fn0');
},
fn1() {
console.log('fn1');
},
fn2() {
console.log('fn2');
}
}
})
</script>
</body>
</html>
八、按键修饰符
记住 keyCode 太麻烦了
- 只有在键盘事件中生活效, (keydown、keypress、 keyup)
- 语法 : @keyup.enter='事件函数'
.enter 就是一个按键修饰符, 意思就是当按回车的时候, 事件才会被触发 - @keyup.13 也可以, 但是 keyCode 也是要记住的
- 完善 TodoMVC + 按键修饰符
# 按键修饰符
keyup/keydown/keypress
> 判断回车的例子
> 第一个版本 : @keyup='addTodo' ==> if(e.keyCode==13) { }
> 第二个版本 : @keyup.13='addTodo' => 不要判断了
> 第三个版本 : @keyup.enter='addTodo' 按键修饰符
```js
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
```
<button @click="delTodo(item.id)" class="destroy"></button>
// 删除任务
delTodo(id) {
// console.log(id)
// 拿到id, 直接删除不好删, 过滤, 过滤出来不等于当前id的元素, 新的数组, 把之前的list覆盖掉就可以了
this.list = this.list.filter(item => item.id != id)
}
九、v-if 和 v-show
-
代码
-
<h1 v-if='isShow'>我是h1 v-if</h1> <h1 v-show='isShow'>我是h1 v-show</h1>
-
异同点
-
v-if 和 v-show 的异同点 1. 相同点 : 可以切换元素的显示与隐藏 2. 不同点 : 切换显示和隐藏的实现不同 v-if : 显示:创建节点 隐藏: 删除节点 v-show : 显示: display:block 隐藏 : display:none 3. 使用场景 : v-if因为要不断的创建和删除来切换显示与隐藏 ,所以性能不高 v-if : 切换次数不频繁的时候, v-show : 切换次数频繁的时候
-
完善 TodoMVC + v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
v-if 和 v-show 切换元素的显示和隐藏
格式 v-if/v-show='布尔' true => 显示 false=> 隐藏
相同点 : v-if 和 v-show 都能够切换元素的显示和隐藏
不同点 : 实现的方式不一样
v-if 显示:创建节点 隐藏:删除节点
v-show 显示:display:block 隐藏:display:none
因为 v-if 是通过不断的创建和删除节点来切换显示和隐藏的,所以性能不好
所以要决定使用哪个,看切换的频繁与否
切换的频繁 : v-show 【切换的不频繁,也可以使用v-show。】
切换的不频繁 : v-if
-->
<div id="app">
<!-- <h1 v-if='isShow'>测试 v-if </h1> -->
<h1 v-show='isShow'>测试 v-show </h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
isShow: false
}
})
</script>
</body>
</html>
十一、计算属性 computed
计算属性其实就是一个属性
-
说明 : 计算属性只跟随相关的数据变化而变化 ,解决底部显示隐藏问题,
-
怎么使用?
- 在 computed 里面
- 写起来像一个方法
- 用起来像一个属性
-
特点 :
-
计算属性一定要有返回值, 返回的值,就会标签要展示的内容
-
计算属性可以使用data里之前已知的值
-
(重要) 只要 计算属性
相关的数据
发生了变化,计算属性会重新计算
-
(说一下 😃 num1就是totalNum计算属性的相关属性,所以num1变了,计算属性会重新计算,
但是num2不是相关的属性,所以不管你num2怎么变,计算属性都不会重新计算
-
-
注意点 :
- 4.1. 一定要有返回值
- 4.2. 用起来的时候,不能当方法用,因为它本来就是一个属性
- 4.3. 计算属性(computed里面的属性) 不能和 data里的属性重名
-
什么时候使用 计算属性?
- 根据已知的值,得到一个新值
- 并且 , 新值只想跟相关的数据(已知的值)的变化而变化 (实时更新)
-
案例 : 计算器
num1 <input type="text" v-model="num1" /> +
num2 <input type="text" v-model="num2" /> = <span>{{ num3 }}</span>
<hr />
<input type="text" v-model="test" />
- 完善 TodoMVC + 计算属性 + 底部显示与隐藏 / 左边的剩余未完成数 / 右边清除完成按钮显示与隐藏
05-计算属性的基本使用.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!--
计算属性 computed
1. 说明 : 计算属性就是一种属性 【Vue实例对象的属性。】
2. 如何使用 ?
- 写在 computed 里面
- 写起来像一个方法/函数
- 用起来像一个属性
3. 特点 :
- 一定要有返回值, 返回值就是计算属性得到的值
- 可以使用data里存在的值
- ** 计算属性只会随着相关的数据发生变化而变化, 只要相关的数据发生了变化, 计算属性会重新计算 **
4. 注意点
- 一定要有返回值
- 不能当方法用 【否则报错:函数未定义。】
- 不能和data里的数据重名 【否则报错:变量已声明。】
5. 以后何时使用计算属性 ?
- 根据已知值(data里值), 想得到一个新值
- 想得到一个效果 : 新值只和相关的数据变化有关, 相关的数据变化, 新值会随着变化, 其他值不受影响
-->
<div id="app">
<h1>{{ totalNum }}</h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
num1: 100,
num2: 200
},
computed: {
totalNum() {
console.log('重新计算了')
return this.num1 + 20
},
num3() {
return this.num1 * this.num2
}
}
})
</script>
</body>
</html>
06-计算属性小案例.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="app">
num1 : <input type="text" v-model="num1" /> + num2 :
<input type="text" v-model="num2" /> =
<span>{{ totalNum }}</span>
<hr />
<input type="text" v-model="num3" />
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
num1: '',
num2: '',
num3: ''
},
computed: {
// totalNum 只跟num1 、num2有关,跟num3无关,不管num3如何变化。
totalNum() {
// 诸如'111'的数字类型的字符串,前面加上 加号+ ,就转换为数字类型。
return +this.num1 + +this.num2
}
}
})
</script>
</body>
</html>
十二、key
- 说明 :
- Vue 中推荐, 在使用 v-for 的时候,添加 key 属性
看官网
-
介绍 就地复用,原地打滚
默认跟着索引走。
<!-- 显示组件 -->
<p v-for="(item,index) in list" :key="index">
{{ item.name}} <input type="text" />
</p>
<!-- 数据 -->
data: { list : [
{ id : 1, name : '老罗' },
{ id : 2, name : '涛涛' },
{ id : 3, name : '聪聪' }
]}
<!-- 演示 -->
vm.list.unshift({id:4,name:'马哥'})
- 怎么使用 key
- 如果数组的元素是一个对象 : 使用对象里固定属性,唯一
- 一般情况下,对象里都有 id, 99%都是取
item.id
- 如果数组的元素是一个简单类型,不是一个对象, 就可以取索引作为 key
- 语法 :
:key='item.id'
- 以后,写了
v-for
之后,立马写好:key
- 完善 TodoMVC + key
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
key
1. vue官网推荐, 我们以后使用v-for的时候, 加上key
2. 如果我们不加key的话, 会出现`就地复用`的策略 (了解) 【默认值是索引。】
3. 解决就地复用的问题 : 添加一个key属性,并且给key一个正确的值
4. 如何给key赋值呢??
1. 如果数组里的元素是一个对象(90%), key取对象里的属性(固定、唯一), :key='item.id'
2. 如果数组里的元素不是一个对象, 真的很简单, :key='index' (不要让顺序发生了改变)
-->
<div id="app">
<p v-for='(item,index) in list' :key='item.name'>
{{ item.id }} {{ item.name }} <input type="text">
</p>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list1: ['张三', '李四'],
list: [{
id: 1,
name: '聪聪',
done: false
}, {
id: 2,
name: '浪涛',
done: false
}, {
id: 3,
name: '傻春',
done: true
}]
}
})
</script>
</body>
</html>
十三、条件渲染指令 v-else 和 v-else-if
条件渲染指令
if(){ // v-if
}else if(){ // v-else-if
}else {} // v-else
- v-else : 两种情况的
<h1 v-if="num > 40">第一个</h1>
<h1 v-else>第二个</h1>
- v-else-if : 三种以上情况
<h1 v-if="num >= 40">第一个</h1>
<h1 v-else-if="num >= 30 && num < 40">第二个</h1>
<h1 v-else>第三个</h1>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
条件渲染指令
if(){ // v-if
}else if(){ // v-else-if
}else {} // v-else
-->
<div id="app">
<!--
只显示一种
-->
<h1 v-if='length >= 18'>特别长</h1>
<h1 v-else-if='length >= 12'>很长</h1>
<h1 v-else>一般般</h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
length: 25
}
})
</script>
</body>
</html>