其实,我们上一章的时候就已经说过了一些系统指令,这里详细介绍一下
一、v-on的事件修饰符
事件 | 作用 |
---|---|
click | 点击时触发 |
submit | 表单被提交时触发 |
input | 输入框发生改变时触发 |
keyup | 按键松开时触发 |
keydown | 按键按下时触发 |
mouseover | 鼠标悬停触发 |
mouseout | 当鼠标移开元素时触发 |
.stop | 阻止冒泡。本质是调用 event.stopPropagation()。 |
.prevent | 阻止默认事件(默认行为)。本质是调用 event.preventDefault() |
.capture | 添加事件监听器时,使用捕获的方式(也就是说,事件采用捕获的方式,而不是采用冒泡的方式) |
.self | 只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调 |
.once | 事件只触发一次 |
.{keyCode | keyAlias} | 只当事件是从侦听器绑定的元素本身触发时,才触发回调 |
.native | 监听组件根元素的原生事件 |
1、click事件
<!-- click事件 -->
<button v-on:click="doThis"></button>
<!-- 缩写 -->
<button @click="doThis"></button>
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<!-- click事件 -->
<button v-on:click="doThis">按钮1</button>
<!-- 缩写 -->
<button @click="doThis">按钮2</button>
</div>
<script>
new Vue({
el: '#app1',
methods: {
doThis() { //添加一个触发函数
alert(' 被点击了'); //做一个弹窗提示效果
},
}
});
</script>
</body>
</html>
2、内链调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<!-- click事件 -->
<button v-on:click="doThat('hello', $event)">按钮</button>
</div>
<script>
new Vue({
el: '#app1',
methods: {
doThat(param, event) {
// 在这里编写处理点击事件的逻辑
alert(param)
console.log(event);
}
}
});
</script>
</body>
</html>
3、.stop
阻止父子标签冒泡关系
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<div class="father" @click="fatherClick">
<div class="child" @click="childClick">
</div>
</div>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {},
methods: {
fatherClick: function () {
console.log('father 被点击了');
},
childClick: function () {
console.log('child 被点击了');
}
}
})
</script>
</body>
</html>
可以看到上面的代码中两个div存在父子标签关系,当点击绿色的子标签时,粉色的父标签管理的按钮同时也会触发,而单独点击粉色的父标签则只会触发自己独立的函数,为了解决这种父子关系,需要使用到阻止触发.stop
<div class="child" @click.stop="childClick">
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<div class="father" @click="fatherClick">
<div class="child" @click.stop="childClick">
</div>
</div>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {},
methods: {
fatherClick: function () {
console.log('father 被点击了');
},
childClick: function () {
console.log('child 被点击了');
}
}
})
</script>
</body>
</html>
4、.capture
子标签冒泡捕获
.capture
事件修饰符的主要作用是改变事件的传播顺序。在默认情况下,事件从目标元素开始在冒泡阶段向外传播,而使用.capture
修饰符后,事件将在捕获阶段先行触发当您在包含子元素的父元素上绑定
.capture
修饰符的事件监听器时,该监听器会在子元素上的事件监听器之前触发,我们通常用他来做下面两件事
1、阻止事件冒泡 #当您需要阻止事件冒泡到父元素或更外层元素时
#可以在父元素上使用 .capture 修饰符,并在父元素上处理事件
#从而阻止子元素上的事件处理器被触发。
2、处理全局事件 #有时您可能需要在应用程序的根元素上全局监听某个特定的事件
#以便捕获所有子组件中相应的事件,这时可以使用 .capture 修饰符来确保您的
#监听器在其他组件的监听器之前被触发
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<!-- 在父标签上添加.capture 阻止冒泡行为-->
<div class="father" @click.capture="fatherClick">
<div class="child" @click="childClick">
</div>
</div>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {},
methods: {
fatherClick: function () {
console.log('father 被点击了');
},
childClick: function () {
console.log('child 被点击了');
}
}
})
</script>
</body>
</html>
这样一来,当我们的子标签生效之前,会被父标签捕获,等待父标签执行完毕后才会执行子标签
5、.prevent 超链接跳转捕获
比如说,超链接
<a>
默认有跳转行为,那我可以通过事件修饰符.prevent
阻止这种跳转行为
案例1 阻止链接跳转页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<!-- 通过 .prevent 阻止超链接的默认跳转行为 -->
<a href="http://www.baidu.com" @click.prevent="linkClick">百度一下</a>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {},
methods: {
linkClick: function () {
console.log('超链接被点击了');
}
}
})
</script>
</body>
</html>
案例2 阻止表单提交跳转
假设我们现在有一个表单,如下
<form action="http://www.baidu.com">
<input type="submit" value="表单提交">
</form>
正常来说,我们点击上面表单的按钮时,这个表单就会被提交到form标签的action属性中指定的那个页面中去,我们并不是每次都希望这样,当不希望他进行跳转的时候,也可以使用
.prevent
来阻止这种默认行为,而修改为点击按钮后,不提交到服务器,而是执行我们自己想要的事件(在submit方法中另行定义 )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<!-- 阻止表单中submit的默认事件 -->
<form @submit.prevent action="http://www.baidu.com">
<!-- 执行自定义的click事件 -->
<input type="submit" @click="mySubmit" value="表单提交">
</form>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {},
methods: {
//添加
mySubmit: function() {
alert('ok');
}
}
})
</script>
</body>
</html>
6、.self 限制返回自身元素
我们知道,在事件触发机制中,当点击子标签时,父标签会通过冒泡的形式被触发(父标签本身并没有被点击)。可如果我给父标签的点击事件设置
.self
修饰符,达到的效果是:子标签的点击事件不会再冒泡到父标签了,只有点击符标签本身,父标签的事件才会被触发总结:
.self
只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<!-- 定义父标签为self-->
<div class="father" @click.self="fatherClick">
<div class="child" @click="childClick">
</div>
</div>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {},
methods: {
fatherClick: function () {
console.log('father 被点击了');
},
childClick: function () {
console.log('child 被点击了');
}
}
})
</script>
</body>
</html>
可以看到两个标签都是独立的了,点击互不影响 (看右侧调试的次数就是点击了几次)
二、系统命令
1、v-model 双向绑定
双向数据绑定,只能用于表单元素,或者用于自定义组件
我们在上一张装完vue环境后做过了一个v-bind 通过给
<input>
标签绑定了data
对象里的name
属性。当data
里的name
的值发生改变时,<input>
标签里的内容会自动更新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="div1">
<!-- 添加text和html的msg区分-->
<!-- value里的值只是简单的字符串 -->
<input type="text" value="name">
<!-- 加上 v-bind 之后,value里的值是 Vue 里的变量 -->
<input type="text" v-bind:value="name">
<!-- 超链接后面的path是 Vue 里面的变量 -->
<a v-bind="{href:'http://www.baidu.com/'+path}">超链接</a>
</div>
</body>
<script>
var myVue = new Vue({
el: '#div1',
data: {
name: 'smyhvae',
path: `2.html`,
},
});
</script>
</html>
可我现在要做的是,在在
<input>
标签里修改内容,要求data
里的name
的值自动更新。从而实现双向数据绑定。这就可以利用v-model
这个属性
1、v-bind 和 v-model的区别
v-bind #只能实现数据的单向绑定,从 M 自动绑定到 V。
v-model #只有`v-model`才能实现双向数据绑定。注意v-model后面不需要跟冒号,
2、v-model案例
v-model 只能运用在表单元素中,或者用于自定义组件。常见的表单元素包括:
input(radio, text, address, email....) 、select、checkbox 、textarea
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<form action="#">
<!-- 将 input 标签中的value值双向绑定到 Vue实例中的data。注意,v-model 后面不需要跟冒号 -->
<input type="text" id="username" v-model="myAccount.username">
<input type="password" id="pwd" v-model="myAccount.userpwd">
<input type="submit" v-on:click="submit1" value="注册">
</form>
</div>
<script>
var vm = new Vue({
el: '#app1',
//上面的标签中采用v-model进行双向数据绑定,数据会自动更新到data里面来
data: {
name: 'test',
myAccount: {username: '', userpwd: ''}
},
//在methods里绑定各种方法,根据业务需要进行操作
methods: {
submit1: function () {
alert(this.myAccount.username + " pwd=" + this.myAccount.userpwd);
}
}
})
</script>
</body>
</html>
我们可以看到,当我们输入的文本会自动更新到data的数据中,后续我们可以搭配data和函数去定义一些关于访问其他api,然后值后,再去自动更新页面数据v-bind的操作
3、练习 计算器
现在两个输入框,用来做加减乘除,将运算的结果放在第三个输入框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.father {
height: 300px;
width: 300px;
background: pink;
}
.child {
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div id="app1">
<input type="text" v-model="n1">
<select v-model="opt">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" v-model="n2">
<input type="button" value="=" @click="calc">
<input type="text" v-model="result">
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
n1: 0,
n2: 0,
result: 0,
opt: '+'
},
methods: {
calc() { // 计算器算数的方法
// 逻辑判断:
switch (this.opt) {
case '+':
this.result = parseInt(this.n1) + parseInt(this.n2)
break;
case '-':
this.result = parseInt(this.n1) - parseInt(this.n2)
break;
case '*':
this.result = parseInt(this.n1) * parseInt(this.n2)
break;
case '/':
this.result = parseInt(this.n1) / parseInt(this.n2)
break;
}
}
}
})
</script>
</body>
</html>
验证如下,当我们输入前两个值后点击=按钮 会自动更新结尾的数据
2、.class 类样式
Vue中通过属性绑定为元素设置class 类样式的,我们首先定义一个基础的带css样式的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.my-red {
/*字体颜色为红色*/
color: red;
}
.my-thin {
/* 设置字体的粗细 */
font-weight: 200;
}
.my-italic {
/*设置字体样式*/
font-style: italic;
}
.my-active {
/* 设置字符之间的间距 */
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app1">
<!-- 定义标题,并使用css样式-->
<h1 class="my-red my-thin">今天又是充满希望的一天</h1>
</div>
<script>
</script>
</body>
</html>
方法1 数组引用
直接传递一个数组。这里的 class 需要使用 v-bind 做数据绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.my-red {
color: red;
}
.my-thin {
font-weight: 200;
}
.my-italic {
font-style: italic;
}
.my-active {
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app1">
<!-- 普通写法 -->
<h1 class="my-red my-thin">今天又是充满希望的一天</h1>
<!-- vue的写法1:数组的形式 -->
<h1 :class="['my-red', 'my-thin']">今天又是充满希望的一天</h1>
</div>
<script>
var vm = new Vue({
el: '#app1'
});
</script>
</body>
</html>
注意,数组里写的是字符串;如果不加单引号,就不是字符串了,而是变量
方法2 在数组中使用三元表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.my-red {
color: red;
}
.my-thin {
font-weight: 200;
}
.my-italic {
font-style: italic;
}
.my-active {
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app1">
<!-- vue的写法2:在数组中使用三元表达式。注意格式不要写错-->
<!-- 通过data中布尔值 flag 来判断:如果 flag 为 true,就给 h1 标签添加`my-active`样式;否则,就不设置样式。 -->
<!-- 这里如果为true 则会添加文本间距的效果-->
<h1 :class="[flag?'my-active':'']">今天又是充满希望的一天</h1>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
flag: true
}
});
</script>
</body>
</html>
上方代码的意思是,通过data中布尔值 flag 来判断:如果 flag 为 true,就给 h1 标签添加
my-active
样式;否则,就不设置样式
方法3 在数组中使用 对象 来代替 三元表达式
方法二的可读性较差,就有这个方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.my-red {
color: red;
}
.my-thin {
font-weight: 200;
}
.my-italic {
font-style: italic;
}
.my-active {
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app1">
<!-- vue的写法3:在数组中使用对象来代替三元表达式。-->
<h1 :class="[ {'my-active':flag} ]">今天又是充满希望的一天</h1>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
flag: true
}
});
</script>
</body>
</html>
方法4 直接写对象
在定义html的时候直接声明 css中的名称 是true还是false,true则生效,false不生效
<h1 :class="{style1:true, style2:false}">今天又是充满希望的一天</h1>
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.my-red {
color: red;
}
.my-thin {
font-weight: 200;
}
.my-italic {
font-style: italic;
}
.my-active {
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app1">
<!-- vue的写法4:直接使用对象-->
<!-- 在为 class 使用 v-bind 绑定 对象的时候,:class 就是v-bind:class 别忘了哈-->
<h1 :class="{style1:true, style2:false}">今天又是充满希望的一天</h1>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
classObj:{style1:true, style2:false}
}
});
</script>
</body>
</html>
上面这种对象,我们也可以对象通过存放在 data 的变量中 ,声明如下
,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.my-red {
color: red;
}
.my-thin {
font-weight: 200;
}
.my-italic {
font-style: italic;
}
.my-active {
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app1">
<!-- vue的写法4:直接使用对象-->
<!-- 在为 class 使用 v-bind 绑定 对象的时候,对象的属性是类名。由于 对象的属性名可带引号,也可不带引号,所以 这里我没写引号; 属性的值 是一个标识符 -->
<h1 :class="classObj">今天又是充满希望的一天</h1>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
classObj:{style1:true, style2:false}
}
});
</script>
</body>
</html>
3、.style 行内样式
通过属性绑定为元素设置 style 行内样式, 注意是行内样式(即内联样式)
写法1 元素中直接书写
直接在元素上通过
:style
的形式,书写样式对象
<h1 :style="{color: 'red', 'font-size': '20px'}">今天好漫长</h1>
写法2 定义到data中
将样式对象,定义到
data
中,并直接引用到:style
中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<h1 :style="styleObj">好无聊啊</h1>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
//在data中定义样式
styleObj: { color: 'red', 'font-size': '20px' }
}
});
</script>
</body>
</html>
写法3 定义多组样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<!-- 调用多个样式-->
<h1 :style="[ styleObj1, styleObj2 ]">好无聊啊</h1>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
//声明多种样式
styleObj1: { color: 'red', 'font-size': '20px' },
styleObj2: { 'font-style': 'italic' }
}
});
</script>
</body>
</html>
4、v-for 循环使用
根据数组中的元素遍历指定模板内容生成内容 ,比如说,如果我想给一个
ul
中的多个li
分别赋值1、2、3...。如果不用循环,就要挨个赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<ul>
<li>{{list[0]}}</li>
<li>{{list[1]}}</li>
<li>{{list[2]}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
list: [1, 2, 3]
}
});
</script>
</body>
</html>
写法1 循环普通数组的遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<ul>
<!-- 使用v-for对多个li进行遍历赋值 -->
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
list: [1, 2, 3]
}
});
</script>
</body>
</html>
上面的方法只是将数组的值打印出来,如果我们想要将索引和值一块打印出来可以使用下面的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<ul>
<!-- 使用v-for对多个li进行遍历赋值 -->
<li v-for="(item,index) in list">值:{{item}} --- 索引:{{index}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
list: [1, 2, 3]
}
});
</script>
</body>
</html>
方式2:对象数组的遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<ul>
<!-- 对象数组的遍历。括号里如果写两个参数:第一个参数代表数组的单个item,第二个参数代表 index 索引-->
<li v-for="(item, index) in dataList">姓名:{{item.name}} --- 年龄:{{item.age}} --- 索引:{{index}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
//对象数组
dataList: [
{ name: 'smyh', age: '26' },
{ name: 'vae', age: '32' },
{ name: 'xiaoming', age: '20' }
]
}
});
</script>
</body>
</html>
方式3:对象的遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<ul>
<!-- 括号里如果写两个参数:则第一个参数代表value,第二个参数代表key -->
<li v-for="(value,key) in obj1">值:{{value}} --- 键:{{key}} </li>
<h3>---分隔线---</h3>
<!-- 括号里如果写三个参数:则第一个参数代表value,第二个参数代表key,第三个参数代表index -->
<li v-for="(value,key,index) in obj1">值:{{value}} --- 键:{{key}} --- index:{{index}} </li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
obj1: {
name: 'zhangsa',
age: '26',
gender: '男'
}
}
});
</script>
</body>
</html>
方式4:遍历数字
in
后面还可以直接放数字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<ul>
<!-- 对象数组的遍历 -->
<!-- 注意:如果使用 v-for 遍历数字的话,前面的 myCount 值从 1 开始算起 -->
<li v-for="myCount in 10">这是第 {{myCount}}次循环</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
obj1: {
name: 'zhangsa',
age: '26',
gender: '男'
}
}
});
</script>
</body>
</html>
v-for中key的使用注意事项
**注意**:在 Vue 2.2.0+ 版本里,当在**组件中**使用 v-for 时,key 属性是必须要加上的。
这样做是因为:每次 for 循环的时候,通过指定 key 来标示当前循环这一项的**唯一身份**。
> 当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “**就地复用**” 策略。如果数据项的顺序被改变,Vue将**不是移动 DOM 元素来匹配数据项的顺序**, 而是**简单复用此处每个元素**,并且确保它在特定索引下显示已被渲染过的每个元素。
> 为了给 Vue 一个提示,**以便它能跟踪每个节点的身份,从而重用和重新排序现有元素**,你需要为每项提供一个唯一 key 属性。
key的类型只能是:string/number,而且要通过 v-bind 来指定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<div>
<label>Id:
<input type="text" v-model="id">
</label>
<label>Name:
<input type="text" v-model="name">
</label>
<input type="button" value="添加" @click="add">
</div>
<!-- 注意: v-for 循环的时候,key 属性只能使用 number 或者 string -->
<!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 -->
<!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值 -->
<p v-for="item in list" :key="item.id">
<input type="checkbox">{{item.id}} --- {{item.name}}
</p>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
id: '',
name: '',
list: [
{ id: 1, name: 'smyh' },
{ id: 2, name: 'vae' },
{ id: 3, name: 'qianguyihao' },
{ id: 4, name: 'xiaoming' },
{ id: 5, name: 'xiaohong' }
]
},
methods: {
add() { // 添加方法
this.list.unshift({ id: this.id, name: this.name })
}
}
});
</script>
</body>
</html>
5、v-if 设置元素的显示和隐藏(添加/删除DOM元素)
根据表达式的值的真假条件,来决定是否渲染元素,如果为false则不渲染(达到隐藏元素的目的),如果为true则渲染。在切换时,元素和它的数据绑定会被销毁并重建
案例 点击按钮时,切换和隐藏盒子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<button v-on:click="toggle">显示/隐藏</button>
<div v-if="isShow">我是盒子</div>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
isShow: true
},
methods: {
toggle: function() {
this.isShow = !this.isShow;
}
}
});
</script>
</body>
</html>
6、v-show 设置元素的显示和隐藏
(在元素上添加/移除
style="display:none"
属性)根据表达式的真假条件,来切换元素的 display 属性。如果为false,则在元素上添加
display:none
属性;否则移除display:none
属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app1">
<button v-on:click="toggle">显示/隐藏</button>
<div v-show="isShow">我是盒子</div>
</div>
<script>
var vm = new Vue({
el: '#app1',
data: {
isShow: true
},
methods: {
toggle: function() {
this.isShow = !this.isShow;
}
}
});
</script>
</body>
</html>
v-if和v-show的区别
v-if和v-show都能够实现对一个元素的隐藏和显示操作。
区别:
v-if:每次都会重新添加/删除DOM元素
v-show:每次不会重新进行DOM的添加/删除操作,只是在这个元素上添加/移除style="display:none"属性,表示节点的显示和隐藏。
优缺点:
v-if:有较高的切换性能消耗。这个很好理解,毕竟每次都要进行dom的添加/删除操作。
v-show:有较高的初始渲染消耗。也就是说,即使一开始v-show="false",该节点也会被创建,只是隐藏起来了。而v-if="false"的节点,根本就不会被创建。
总结:
如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if