一、内容概述
- 插值操作
- 绑定属性
- 计算属性
- 事件监听
- 条件判断
- 循环遍历
- 阶段案例
- v-model
二、插值操作
2.1 Mustache
- 如何将data中的文本数据,插入到HTML中呢?
- 我们已经学习过了,可以通过Mustache语法(也就是双大括号)。
- Mustache: 胡子/胡须.
- 我们可以像下面这样来使用,并且数据是响应式的
2.2 v-once
- 但是,在某些情况下,我们可能不希望界面随意的跟随改变
- 这个时候,我们就可以使用一个Vue的指令
- v-once:
- 该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
- 该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。
- 代码如下:
2.3 v-html
- 某些情况下,我们从服务器请求到的数据本身就是一个HTML代码
- 如果我们直接通过{{}}来输出,会将HTML代码也一起输出。
- 但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。
- 如果我们希望解析出HTML展示
- 可以使用v-html指令
- 该指令后面往往会跟上一个string类型
- 会将string的html解析出来并且进行渲染
- 可以使用v-html指令
2.4 v-text
- v-text作用和Mustache比较相似:都是用于将数据显示在界面中
- v-text通常情况下,接受一个string类型
2.5 v-pre
- v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
- 比如下面的代码:
- 第一个h2元素中的内容会被编译解析出来对应的内容
- 第二个h2元素中会直接显示{{message}}
2.6 v-cloak
- 在某些情况下,我们浏览器可能会直接显然出未编译的Mustache标签。
- cloak: 斗篷
三、绑定属性
3.1 v-bind介绍
- 前面我们学习的指令主要作用是将值插入到我们模板的内容当中。
- 但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定。
- 比如动态绑定a元素的href属性
- 比如动态绑定img元素的src属性
- 这个时候,我们可以使用v-bind指令:
- 作用:动态绑定属性
- 缩写::
- 预期:any (with argument) | Object (without argument)
- 参数:attrOrProp (optional)
- 下面,我们就具体来学习v-bind的使用。
3.2 v-bind基础
- v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍)
- 在开发中,有哪些属性需要动态进行绑定呢?
- 还是有很多的,比如图片的链接src、网站的链接href、动态绑定一些类、样式等等
- 比如通过Vue实例中的data绑定元素的src和href,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 错误的做法: 这里不可以使用mustache语法-->
<!--<img src="{{imgURL}}" alt="">-->
<!-- 正确的做法: 使用v-bind指令 -->
<img v-bind:src="imgURL" alt="">
<a v-bind:href="aHref">百度一下</a>
<!--<h2>{{}}</h2>-->
<!--语法糖的写法-->
<img :src="imgURL" alt="">
<a :href="aHref">百度一下</a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
imgURL: 'https://img11.360buyimg.com/mobilecms/s350x250_jfs/t1/20559/1/1424/73138/5c125595E3cbaa3c8/74fc2f84e53a9c23.jpg!q90!cc_350x250.webp',
aHref: 'http://www.baidu.com'
}
})
</script>
</body>
</html>
3.3 v-bind语法糖
- v-bind有一个对应的语法糖,也就是简写方式
- 在开发中,我们通常会使用语法糖的形式,因为这样更加简洁。
- 简写方式如下:
3.4 v-bind绑定class(一)
- 很多时候,我们希望动态的来切换class,比如:
- 当数据为某个状态时,字体显示红色。
- 当数据另一个状态时,字体显示黑色。
- 绑定class有两种方式:
- 对象语法
- 数组语法
3.5 v-bind绑定class(二)
- 绑定方式:对象语法
- 对象语法的含义是:class后面跟的是一个对象。
- 对象语法有下面这些用法:
用法一:直接通过{}绑定一个类
Hello World
用法二:也可以通过判断,传入多个值Hello World
用法三:和普通的类同时存在,并不冲突 注:如果isActive和isLine都为true,那么会有title/active/line三个类Hello World
用法四:如果过于复杂,可以放在一个methods或者computed中 注:classes是一个计算属性Hello World
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<!--<h2 class="active">{{message}}</h2>-->
<!--<h2 :class="active">{{message}}</h2>-->
<!--<h2 v-bind:class="{key1: value1, key2: value2}">{{message}}</h2>-->
<!--<h2 v-bind:class="{类名1: true, 类名2: boolean}">{{message}}</h2>-->
<h2 class="title" v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
<h2 class="title" v-bind:class="getClasses()">{{message}}</h2>
<button v-on:click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isActive: true,
isLine: true
},
methods: {
btnClick: function () {
this.isActive = !this.isActive
},
getClasses: function () {
return {active: this.isActive, line: this.isLine}
}
}
})
</script>
</body>
</html>
3.6 v-bind绑定class(三)
- 绑定方式:数组语法
- 数组语法的含义是:class后面跟的是一个数组。
- 数组语法有下面这些用法:
用法一:直接通过{}绑定一个类
Hello World
用法二:也可以传入多个值Hello World
用法三:和普通的类同时存在,并不冲突 注:会有title/active/line三个类Hello World
用法四:如果过于复杂,可以放在一个methods或者computed中 注:classes是一个计算属性Hello World
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 class="title" :class="[active, line]">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
active: 'aaaaaa',
line: 'bbbbbbb'
},
methods: {
getClasses: function () {
return [this.active, this.line]
}
}
})
</script>
</body>
</html>
3.7 v-bind绑定style(一)
- 我们可以利用v-bind:style来绑定一些CSS内联样式。
- 在写CSS属性名的时候,比如font-size
- 我们可以使用驼峰式 (camelCase)fontSize
- 或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
- 绑定class有两种方式:
- 对象语法
- 数组语法
3.8 v-bind绑定style(二)
- 绑定方式一:对象语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.title {
font-size: 50px;
color: red;
}
</style>
</head>
<body>
<div id="app">
<!--<h2 :style="{key(属性名): value(属性值)}">{{message}}</h2>-->
<!--'50px'必须加上单引号, 否则是当做一个变量去解析-->
<!--<h2 :style="{fontSize: '50px'}">{{message}}</h2>-->
<!--finalSize当成一个变量使用-->
<!--<h2 :style="{fontSize: finalSize}">{{message}}</h2>-->
<h2 :style="{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{message}}</h2>
<h2 :style="getStyles()">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
finalSize: 100,
finalColor: 'red',
},
methods: {
getStyles: function () {
return {fontSize: this.finalSize + 'px', backgroundColor: this.finalColor}
}
}
})
</script>
</body>
</html>
- 绑定方式二:数组语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
baseStyle: {backgroundColor: 'red'},
baseStyle1: {fontSize: '100px'},
}
})
</script>
</body>
</html>
3.9 作业(v-for和v-bind的结合)
作业需求: 点击列表中的哪一项, 那么该项的文字变成红色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item, index) in movies"
:class="{active: currentIndex === index}"
@click="liClick(index)">
{{index}}.{{item}}
</li>
<!--<li :class="{active: 0===currentIndex}"></li>-->
<!--<li :class="{active: 1===currentIndex}"></li>-->
<!--<li :class="{active: 2===currentIndex}"></li>-->
<!--<li :class="{active: 3===currentIndex}"></li>-->
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies: ['海王', '海贼王', '加勒比海盗', '海尔兄弟'],
currentIndex: 0
},
methods: {
liClick(index) {
this.currentIndex = index
}
}
})
</script>
</body>
</html>
四、计算属性
4.1 什么是计算属性?
- 我们知道,在模板中可以直接通过插值语法显示一些data中的数据。
- 但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
- 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
- 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
- 我们可以将上面的代码换成计算属性:
- OK,我们发现计算属性是写在实例的computed选项中的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Lebron',
lastName: 'James'
},
// computed: 计算属性()
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
4.2 计算属性的复杂操作
- 计算属性中也可以进行一些更加复杂的操作,比如下面的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>总价格: {{totalPrice}}</h2>
<h2>总价格: {{totalPrice}}</h2>
<h2>总价格: {{totalPrice}}</h2>
<h2>总价格: {{totalPrice}}</h2>
<h2>总价格: {{getTotalPrice()}}</h2>
<h2>总价格: {{getTotalPrice()}}</h2>
<h2>总价格: {{getTotalPrice()}}</h2>
<h2>总价格: {{getTotalPrice()}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
books: [
{id: 110, name: 'Unix编程艺术', price: 119},
{id: 111, name: '代码大全', price: 105},
{id: 112, name: '深入理解计算机原理', price: 98},
{id: 113, name: '现代操作系统', price: 87},
]
},
methods: {
getTotalPrice: function () {
let result = 0
for (let i=0; i < this.books.length; i++) {
result += this.books[i].price
}
return result
}
},
computed: {
totalPrice: function () {
let result = 0
for (let i=0; i < this.books.length; i++) {
result += this.books[i].price
}
return result
// for (let i in this.books) {
// this.books[i]
// }
//
// for (let book of this.books) {
//
// }
}
}
})
</script>
</body>
</html>
4.3 计算属性的setter和getter
- 每个计算属性都包含一个getter和一个setter
- 在上面的例子中,我们只是使用getter来读取。
- 在某些情况下,你也可以提供一个setter方法(不常用)。
- 在需要写setter的时候,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
computed: {
// fullName: function () {
// return this.firstName + ' ' + this.lastName
// }
// name: 'coderwhy'
// 计算属性一般是没有set方法, 只读属性.
fullName: {
set: function(newValue) {
// console.log('-----', newValue);
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
},
get: function () {
return this.firstName + ' ' + this.lastName
}
},
// fullName: function () {
// return this.firstName + ' ' + this.lastName
// }
}
})
</script>
</body>
</html>
4.4 计算属性的缓存
- 我们可能会考虑这样的一个问题:
- methods和computed看起来都可以实现我们的功能,
- 那么为什么还要多一个计算属性这个东西呢?
- 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。
- 我们来看下面的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.直接拼接: 语法过于繁琐-->
<h2>{{firstName}} {{lastName}}</h2>
<!--2.通过定义methods-->
<!--<h2>{{getFullName()}}</h2>-->
<!--<h2>{{getFullName()}}</h2>-->
<!--<h2>{{getFullName()}}</h2>-->
<!--<h2>{{getFullName()}}</h2>-->
<!--3.通过computed-->
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
// angular -> google
// TypeScript(microsoft) -> ts(类型检测)
// flow(facebook) ->
const app = new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
methods: {
getFullName: function () {
console.log('getFullName');
return this.firstName + ' ' + this.lastName
}
},
computed: {
fullName: function () {
console.log('fullName');
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
五、事件监听
5.1 事件监听
- 在前端开发中,我们需要经常和用于交互。
- 这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等
- 在Vue中如何监听事件呢?使用v-on指令
- v-on介绍
- 作用:绑定事件监听器
- 缩写:@
- 预期:Function | Inline Statement | Object
- 参数:event
- 下面,我们就具体来学习v-on的使用。
5.2 v-on基础
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{counter}}</h2>
<!--<h2 v-bind:title></h2>-->
<!--<h2 :title></h2>-->
<!--<button v-on:click="counter++">+</button>-->
<!--<button v-on:click="counter--">-</button>-->
<!--<button v-on:click="increment">+</button>-->
<!--<button v-on:click="decrement">-</button>-->
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
</script>
</body>
</html>
5.3 v-on参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.事件调用的方法没有参数-->
<button @click="btn1Click()">按钮1</button>
<button @click="btn1Click">按钮1</button>
<!--2.在事件定义时, 写方法时省略了小括号, 但是方法本身是需要一个参数的, 这个时候, Vue会默认将浏览器生产的event事件对象作为参数传入到方法-->
<!--<button @click="btn2Click(123)">按钮2</button>-->
<!--<button @click="btn2Click()">按钮2</button>-->
<button @click="btn2Click">按钮2</button>
<!--3.方法定义时, 我们需要event对象, 同时又需要其他参数-->
<!-- 在调用方式, 如何手动的获取到浏览器参数的event对象: $event-->
<button @click="btn3Click(abc, $event)">按钮3</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
abc: 123
},
methods: {
btn1Click() {
console.log("btn1Click");
},
btn2Click(event) {
console.log('--------', event);
},
btn3Click(abc, event) {
console.log('++++++++', abc, event);
}
}
})
// 如果函数需要参数,但是没有传入, 那么函数的形参为undefined
// function abc(name) {
// console.log(name);
// }
//
// abc()
</script>
</body>
</html>
5.4 v-on修饰符
- 在某些情况下,我们拿到event的目的可能是进行一些事件处理。
- Vue提供了修饰符来帮助我们方便的处理一些事件:
- .stop - 调用 event.stopPropagation()。
- .prevent - 调用 event.preventDefault()。
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
- .native - 监听组件根元素的原生事件。
- .once - 只触发一次回调。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1. .stop修饰符的使用-->
<div @click="divClick">
aaaaaaa
<button @click.stop="btnClick">按钮</button>
</div>
<!--2. .prevent修饰符的使用-->
<br>
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<!--3. .监听某个键盘的键帽-->
<input type="text" @keyup.enter="keyUp">
<!--4. .once修饰符的使用-->
<button @click.once="btn2Click">按钮2</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
btnClick() {
console.log("btnClick");
},
divClick() {
console.log("divClick");
},
submitClick() {
console.log('submitClick');
},
keyUp() {
console.log('keyUp');
},
btn2Click() {
console.log('btn2Click');
}
}
})
</script>
</body>
</html>
六、条件判断
6.1 v-if、v-else-if、v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
{{message}}
</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
{{message}}
</h2>
<h1 v-else>isShow为false时, 显示我</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-if="score>=90">优秀</h2>
<h2 v-else-if="score>=80">良好</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-else>不及格</h2>
<h1>{{result}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
score: 99
},
computed: {
result() {
let showMessage = '';
if (this.score >= 90) {
showMessage = '优秀'
} else if (this.score >= 80) {
showMessage = '良好'
}
// ...
return showMessage
}
}
})
</script>
</body>
</html>
6.2 条件渲染案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户账号">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱">
</span>
<button @click="isUser = !isUser">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
}
})
</script>
</body>
</html>
6.3 案例小问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户账号" key="username">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱" key="email">
</span>
<button @click="isUser = !isUser">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
}
})
</script>
</body>
</html>
6.4 v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--v-if: 当条件为false时, 包含v-if指令的元素, 根本就不会存在dom中-->
<h2 v-if="isShow" id="aaa">{{message}}</h2>
<!--v-show: 当条件为false时, v-show只是给我们的元素添加一个行内样式: display: none-->
<h2 v-show="isShow" id="bbb">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true
}
})
</script>
</body>
</html>
七、循环遍历
7.1 v-for遍历数组
- 当我们有一组数据需要进行渲染时,我们就可以使用v-for来完成。
- v-for的语法类似于JavaScript中的for循环。
- 格式如下:item in items的形式。
- 我们来看一个简单的案例:
- 如果在遍历的过程中不需要使用索引值
- v-for=”movie in movies”
- 依次从movies中取出movie,并且在元素的内容中,我们可以使用Mustache语法,来使用movie
- 如果在遍历的过程中,我们需要拿到元素在数组中的索引值呢?
- 语法格式:v-for=(item, index) in items
- 其中的index就代表了取出的item在原数组的索引值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.在遍历的过程中,没有使用索引值(下标值)-->
<ul>
<li v-for="item in names">{{item}}</li>
</ul>
<!--2.在遍历的过程中, 获取索引值-->
<ul>
<li v-for="(item, index) in names">
{{index+1}}.{{item}}
</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
names: ['why', 'kobe', 'james', 'curry']
}
})
</script>
</body>
</html>
7.2 v-for遍历对象
- v-for可以用户遍历对象:
- 比如某个对象中存储着你的个人信息,我们希望以列表的形式显示出来。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.在遍历对象的过程中, 如果只是获取一个值, 那么获取到的是value-->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!--2.获取key和value 格式: (value, key) -->
<ul>
<li v-for="(value, key) in info">{{value}}-{{key}}</li>
</ul>
<!--3.获取key和value和index 格式: (value, key, index) -->
<ul>
<li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'why',
age: 18,
height: 1.88
}
}
})
</script>
</body>
</html>
7.3 组件的key属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'D', 'E']
}
})
</script>
</body>
</html>
7.4 检测数组更新
- 因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。
Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新。
push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in letters">{{item}}</li>
</ul>
<button @click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['a', 'b', 'c', 'd']
},
methods: {
btnClick() {
// 1.push方法
// this.letters.push('aaa')
// this.letters.push('aaaa', 'bbbb', 'cccc')
// 2.pop(): 删除数组中的最后一个元素
// this.letters.pop();
// 3.shift(): 删除数组中的第一个元素
// this.letters.shift();
// 4.unshift(): 在数组最前面添加元素
// this.letters.unshift()
// this.letters.unshift('aaa', 'bbb', 'ccc')
// 5.splice作用: 删除元素/插入元素/替换元素
// 删除元素: 第二个参数传入你要删除几个元素(如果没有传,就删除后面所有的元素)
// 替换元素: 第二个参数, 表示我们要替换几个元素, 后面是用于替换前面的元素
// 插入元素: 第二个参数, 传入0, 并且后面跟上要插入的元素
// splice(start)
// splice(start):
this.letters.splice(1, 3, 'm', 'n', 'l', 'x')
// this.letters.splice(1, 0, 'x', 'y', 'z')
// 5.sort()
// this.letters.sort()
// 6.reverse()
// this.letters.reverse()
// 注意: 通过索引值修改数组中的元素
// this.letters[0] = 'bbbbbb';
// this.letters.splice(0, 1, 'bbbbbb')
// set(要修改的对象, 索引值, 修改后的值)
// Vue.set(this.letters, 0, 'bbbbbb')
}
}
})
// function sum(num1, num2) {
// return num1 + num2
// }
//
// function sum(num1, num2, num3) {
// return num1 + num2 + num3
// }
// function sum(...num) {
// console.log(num);
// }
//
// sum(20, 30, 40, 50, 601, 111, 122, 33)
</script>
</body>
</html>
八、阶段案例
8.1 图书购物车
8.2 代码实现:HTML、CSS
8.3 代码实现:JS代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th {
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
</style>
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(book,index) in books" :key="book.id">
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.date}}</td>
<td>{{book.price | priceFilter}}</td>
<td>
<button @click="decrement(index)" v-bind:disabled="book.count <= 1">-</button>
{{book.count}}
<button @click="increment(index)">+</button>
</td>
<td><button @click="remoteBook(index)">移除</button></td>
</tr>
</tbody>
</table>
<h3>总价格: {{totalPrice | priceFilter}}</h3>
</div>
<div v-else>
<h3>购物车清空</h3>
</div>
</div>
<script>
const app = new Vue({
el : "#app",
data : {
books: [
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 1
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 1
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128.00,
count: 1
},
]
},
filters : {
priceFilter(price){
return "$" + price.toFixed(2);
}
},
methods : {
decrement(index){
this.books[index].count--
},
increment(index){
this.books[index].count++
},
remoteBook(index){
this.books.splice(index,1);
}
},
computed : {
totalPrice(){
// let result = 0;
// for(let book of this.books){
// result += book.price * book.count;
// }
// return result;
return this.books.reduce(function(preVilus,book){
return preVilus + book.price * book.count;
},0)
}
}
})
</script>
</body>
</html>
九、v-model
9.1 表单绑定v-model
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
</body>
</html>
9.2 v-model原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--<input type="text" v-model="message">-->
<!--<input type="text" :value="message" @input="valueChange">-->
<input type="text" :value="message" @input="message = $event.target.value">
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
valueChange(event) {
this.message = event.target.value;
}
}
})
</script>
</body>
</html>
9.3 v-model:radio
- 当存在多个单选框时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<label for="male">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>您选择的性别是: {{sex}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
sex: '女'
}
})
</script>
</body>
</html>
9.4 v-model:checkbox
- 复选框分为两种情况:单个勾选框和多个勾选框
- 单个勾选框:
- v-model即为布尔值。
- 此时input的value并不影响v-model的值。
- 多个复选框:
- 当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
- 当选中某一个时,就会将input的value添加到数组中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.checkbox单选框-->
<!--<label for="agree">-->
<!--<input type="checkbox" id="agree" v-model="isAgree">同意协议-->
<!--</label>-->
<!--<h2>您选择的是: {{isAgree}}</h2>-->
<!--<button :disabled="!isAgree">下一步</button>-->
<!--2.checkbox多选框-->
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<h2>您的爱好是: {{hobbies}}</h2>
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
</label>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isAgree: false, // 单选框
hobbies: [], // 多选框,
originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
}
})
</script>
</body>
</html>
9.5 v-model:select
- 和checkbox一样,select也分单选和多选两种情况。
- 单选:只能选中一个值。
- v-model绑定的是一个值。
- 当我们选中option中的一个时,会将它对应的value赋值到mySelect中
- 多选:可以选中多个值。
- v-model绑定的是一个数组。
- 当选中多个值时,就会将选中的option对应的value添加到数组mySelects中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.选择一个-->
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruit}}</h2>
<!--2.选择多个-->
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruits}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
fruit: '香蕉',
fruits: []
}
})
</script>
</body>
</html>
9.6 值绑定
- 初看Vue官方值绑定的时候,我很疑惑:what the hell is that?
- 但是仔细阅读之后,发现很简单,就是动态的给value赋值而已:
- 我们前面的value中的值,可以回头去看一下,都是在定义input的时候直接给定的。
- 但是真实开发中,这些input的值可能是从网络获取或定义在data中的。
- 所以我们可以通过v-bind:value动态的给value绑定值。
- 这不就是v-bind吗?
- 这不就是v-bind在input中的应用吗?搞的我看了很久,搞不清他想将什么。
- 这里不再给出对应的代码,因为会用v-bind,就会值绑定的应用了。
9.7 修饰符
- lazy修饰符:
- 默认情况下,v-model默认是在input事件中同步输入框的数据的。
- 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。
- lazy修饰符可以让数据在失去焦点或者回车时才会更新:
- number修饰符:
- 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
- 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。
- number修饰符可以让在输入框中输入的内容自动转成数字类型:
- trim修饰符:
- 如果输入的内容首尾有很多空格,通常我们希望将其去除
- trim修饰符可以过滤内容左右两边的空格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.修饰符: lazy-->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
<!--2.修饰符: number-->
<input type="number" v-model.number="age">
<h2>{{age}}-{{typeof age}}</h2>
<!--3.修饰符: trim-->
<input type="text" v-model.trim="name">
<h2>您输入的名字:{{name}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
age: 0,
name: ''
}
})
var age = 0
age = '1111'
age = '222'
</script>
</body>
</html>