前言

本文将介绍Vue的基础语法


补充ES6新特性

对象字面量的增强写法

在引入外部属性时可以直接写属性名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const name = 'why';
const age = 18;
const height = 1.88;

const obj = {
name,
age,
height,

//等价于下面的写法
//name: name,
//age: age,
//height: height,
}
console.log(obj)

在定义方法时可省略function()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const obj = {
run() {
console.log('奔跑中');
},
eat() {
console.log('吃饭中');
}

//等价于下面的写法
run: function () {
console.log('奔跑中');
},
eat: function () {
console.log('吃饭中');
}
}

let和const

见下方

基础语法

插值语法

Mustache语法

最基本的vue的使用实例:

1
2
3
<div id="app">
{{message}}
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
})
</script>

注意声明:

  • let:声明一个变量(含块级作用域)
  • const:声明一个常量(第一次赋值之后不可更改)
    • 在使用const定义时,必须进行赋值
    • 常量的含义是指向的对象不能修改,但是对象的内部属性可以修改
  • var:变量声明(不含块级作用域)

建议在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才使用let。

在Mustache语法中,不仅仅可以直接写变量,也可以写简单的表达式:

1
2
3
4
<div id="app">
{{firstName + lastName}} <!--姓名紧挨着-->
{{firstName + ' ' + lastName}} <!--姓名之间有空格-->
</div>
1
2
3
4
5
6
7
8
9
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
})
</script>

包括计算:

1
2
3
<div id="app">
{{Number * 2}} <!--显示200-->
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
Number: 100
},
})
</script>

v-once指令

在Mustache语法中,只要改变了Vue实例中data的数据,那么相应的双大括号中被渲染的数据就会发生改变,但是如果我们希望前端展示的数据在只显示一次后便固定,不由data中数据修改而变化,这时就需要v-once

1
2
3
4
<div id="app">
<h2 v-once>{{message}}</h2>
<h2>{{message}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇'
}
})
</script>

如果在浏览器中输入app.message = '李银河',则只有第二个内容会发生改变,如下图:

v-html指令

在展示url链接时需要用到v-html指令:

1
2
3
4
<div id="app">
<h2>{{url}}</h2> <!-- 将显示完整的字符串,不具备超链接效果 -->
<h2 v-html="url">这里的内容不会显示</h2> <!-- 将显示<a>标签中的text文本 -->
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
url: '<a href="http://www.baidu.com">百度一下</a>',
}
})
</script>

效果如下:

v-text指令

如果只希望展示实例化Vue对象中data的数据,而不显示被标签包裹的text文本,则使用v-text指令:

1
2
3
4
<div id="app">
<h2>{{message}},李银河!</h2>
<h2 v-text="message">,李银河!</h2> <!--此处的text文本信息不显示-->
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇'
}
})
</script>

v-pre指令

如果只想展示{{内容}},而不被Vue渲染显示数据,则使用v-pre指令:

1
2
3
4
<div id="app">
<h2>{{message}}</h2> <!--显示:你好哇-->
<h2 v-pre>{{message}}</h2> <!--显示:{{message}}-->
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇'
}
})
</script>

v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

1
2
3
<div id="app" v-cloak>
<h2>{{message}}</h2>
</div>
1
2
3
4
5
<style>
[v-cloak] {
display: none;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
<script>
// 在vue解析之前, div中有一个属性v-cloak
// 在vue解析之后, div中没有属性v-cloak
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
}, 1000) //一秒后显示
</script>

动态绑定属性

v-bind使用

v-bind用于绑定html属性。

基本使用

可以绑定img标签中的src链接:

1
2
3
<div id="app">
<img v-bind:src="imgURL" alt="头像">
</div>

注意避免错误写法:<img src="{{imgURL}}" alt="">

1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
imgURL: 'https://gcore.jsdelivr.net/gh/CNhuazhu/Image/avatar.jpg',
}
})
</script>

可以绑定超文本链接中的href链接:

1
2
3
<div id="app">
<a :href="aHref">百度一下</a> <!--语法糖表示-->
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
aHref: 'http://www.baidu.com'
}
})
</script>

注意v-bind的语法糖:直接用冒号表示

v-bind:src=“xxx” <==> :src=“xxx”

动态绑定class(对象语法)

v-bind:class="{类名1: boolean, 类名2: boolean}"

注意:这里的value的值只能是布尔类型。当为true值时,该class属性存在;当为false时

下面展示一个简单的点击按钮切换颜色的案例:

1
2
3
4
5
<div id="app">
<h2 v-bind:class="{active1: isActive1, active2: isActive2}">{{message}}</h2>
<h2 v-bind:class="getClass()">{{message}}</h2> <!--使用函数返回class属性(效果同上)-->
<button v-on:click="btnClick">点击</button>
</div>
1
2
3
4
5
6
7
8
<style>
.active1 {
color: red;
}
.active2 {
font-size: 100px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇',
isActive1: true,
isActive2: true
},
methods: {
btnClick: function() {
this.isActive1 = !this.isActive1
this.isActive2 = !this.isActive2
},
getClass: function() {
return {active1: this.isActive1, active2: this.isActive2}
}
}
})
</script>

动态绑定class(数组语法)

v-bind:class="[active1, active2]"

注意:利用数组直接赋予标签多个class属性,如果再另写其他的class属性,会自动合并。

区别:直接书写的形式一旦写成就会固定,而采用vue的这种方式可以在控制台动态修改属性。

1
2
3
4
<div id="app">
<h2 class="title" :class="[active1, active2]">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2> <!--使用函数返回class属性(效果同上)-->
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
const app = new Vue({
el: '#app',
data: {
active1: 'first',
active1: 'second'
},
methods: {
getClasses: function () {
return [this.active1, this.active1]
}
}
})
</script>

动态绑定style(对象语法)

v-bind:style="{key: value}"

1
2
3
4
5
6
<div id="app">
<h2 v-bind:style="{fontSize: '50px'}">{{message}}</h2> <!-- 使用font-size会报错(与css不同) -->
<h2 v-bind:style="{fontSize: finaleSize1}">{{message}}</h2>
<h2 v-bind:style="{fontSize: finaleSize2 + 'px', color: finalColor}">{{message}}</h2>
<h2 v-bind:style="getStyle()">{{message}}</h2> <!--使用函数返回class属性(效果同上)-->
</div>

注意:

  • 使用字体大小时,key值为fontSize,使用font-size会报错(这与css不同)
  • 在第一种表示中,50px必须被单引号所包裹,否则会被认为是一个名“50px”的变量,会报错
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇',
finaleSize1: '100px', //正常的字体大小的值应该被引号包裹,且带px单位
finaleSize2: 150, //如果采用数字,则另外需要加px单位
finalColor: 'red'
},
methods: {
getStyle: function() {
return {fontSize: this.finaleSize2 + 'px', color: this.finalColor}
}
}
})
</script>

动态绑定style(数组语法)

v-bind:style="[Style1, Style2]"

1
2
3
<div id="app">
<h2 :style="[bgColor, fontSize]">{{message}}</h2>
</div>
1
2
3
4
5
6
7
8
9
10
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇',
bgColor: {backgroundColor: 'red'},
fontSize: {fontSize: '100px'}
}
})
</script>

计算属性

在Vue实例化对象中,还有一个computed参数,内部依然是书写函数,但是返回值可以被当作同data参数中的一个属性值一样被使用。

基本使用

下面编写一个获取书籍总价格的实例:

1
2
3
<div id="app">
<h2>总价格: {{totalPrice}}</h2>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<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},
]
},
computed: {
totalPrice: function () {
let result = 0
for (let i=0; i < this.books.length; i++) {
result += this.books[i].price
}
return result
}
}
})
</script>

注意:

很显然书写methods方法也可以实现同样的效果,但是computed计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。

计算属性是按照属性去使用的,因此同方法的使用方式不同,不需要加括号()

getter和setter方法

实际上在上一案例中直接以方法形式书写的计算属性是一种简写,本质上是调用了其get方法。

1
2
3
<div id="app">
<h2>{{fullName}}</h2>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
computed: {
fullName: {
get: function () {
return this.firstName + ' ' + this.lastName
}
},
// 等价于下面的简写方式
// fullName: function () {
// return this.firstName + ' ' + this.lastName
// }
}
})
</script>

计算属性一般是没有set方法,是只读属性。但是如果需要也可以加入set方法,用于修改值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
computed: {
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
}
},
}
})
</script>

当在控制台输入app.fullName = 'Lebron James',可以看到计算属性fullName的值发生了改变。

事件监听

v-on

绑定事件监听器

基本使用

下面以按钮计数器为例:

1
2
3
4
5
6
7
<div id="app">
<h2>{{counter}}</h2>
<!--<button v-on:click="counter++">+</button>--> <!--可以直接在双引号中写表达式-->
<!--<button v-on:click="counter--">-</button>-->
<button @click="increment()">+</button> <!--语法糖:@-->
<button @click="decrement()">-</button>
</div>

注意v-on的语法糖:

@click=“xxx” <==> v-on:click=“xxx”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
const app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
</script>

参数的使用

如果在methods中定义的方法没有参数,则在使用的时候方法的括号()可以省略不写。(注意只有在监听事件中才有此规则)

1
2
3
4
<div id="app">
<button @click="btn1Click()">按钮一</button>
<button @click="btn1Click">按钮一</button> <!-- 效果同上 -->
</div>
1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
btn1Click() {
console.log('----按钮一被点击');
}
}
})
</script>

如果在定义方法时需要一个参数:

  • 在使用时书写括号但没有往其中传参,则会显示undefined
  • 在使用时省略该方法的括号不写,则Vue会默认将浏览器生产的event事件对象作为参数传入到方法中
1
2
3
4
<div id="app">
<button @click="btn1Click()">按钮一</button>
<button @click="btn2Click">按钮二</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
btn1Click(event) {
console.log('----按钮一被点击',event);
},
btn2Click(event) {
console.log('----按钮二被点击',event);
}
}
})
</script>

效果如下图:

如果在方法定义时,即需要其它自定义参数,又需要event对象,则要使用$event获取(直接使用event会报错,被当做一个自定义参数):

1
2
3
<div id="app">
<button @click="btn1Click('参数一',$event)">按钮一</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
btn1Click(parameter,event) {
console.log('----按钮一被点击',parameter,event);
},
}
})
</script>

效果如下图:

修饰符

.stop

调用 event.stopPropagation(),可以防止事件冒泡。

1
2
3
4
5
6
<div id="app">
<div @click="divClick">
点击触发div事件
<button @click.stop="btnClick">按钮</button>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
divClick () {
console.log('div事件被触发');
},
btnClick () {
console.log('按钮事件被触发');
}
}
})
</script>

说明:如果不加.stop,则点击按钮的时候两个事件会同时触发

.prevent

调用 event.preventDefault(),可以防止默认事件的发生

1
2
3
4
5
<div id="app">
<form action="http://www.baidu.com">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
submitClick () {
console.log('表单提交事件被触发');
},
}
})
</script>

说明:如果不加.prevent,则在点击表单提交按钮之后会执行action,跳转到百度页面

.{keyCode | keyAlias}

只当事件是从特定键触发时才触发回调,这里以enter键为例:

1
2
3
<div id="app">
<input type="text" @keyup.enter="keyUp">
</div>
1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = new Vue({
el: '#app',
data: {
},
methods: {
keyUp () {
console.log('enter键被释放');
},
}
})
</script>

.once

只触发一次回调,这里不再代码展示

条件判断

v-if、v-else-if、v-else

可以根据表达式的值在DOM中渲染或销毁元素或组件:

1
2
3
4
5
6
<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>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
score: 85
}
})
</script>

当然并不建议较为复杂的判断写在DOM中,一般会将其写入computed计算属性之中:

1
2
3
<div id="app">
<h2>{{showScore}}</h2>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
const app = new Vue({
el: '#app',
data: {
score: 85
},
computed: {
showScore () {
let show = '';
if(this.score>=90) {
show = '优秀'
}
else if(this.score>=80) {
show = '良好'
}
else if(this.score>=60) {
show = '合格'
}
else {
show = '不及格'
}
return show
}
}
})
</script>

v-if对比v-show

这里再介绍一个v-show,可以达到同样的效果:

1
2
3
4
<div id="app">
<h2 v-if="isShow" id="ifff">{{message}}</h2>
<h2 v-show="isShow" id="shhh">{{message}}</h2>
</div>
1
2
3
4
5
6
7
8
9
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇',
isShow: true
}
})
</script>

二者的区别:

  • v-if: 当条件为false时, 包含v-if指令的元素, 根本就不会存在dom中

  • v-show: 当条件为false时, v-show只是给我们的元素添加一个行内样式: display: none

    当 isShow 为false时(如下图所示)

二者的选择:

  • 当需要在显示与隐藏之间进行频繁切换时,选择v-show
  • 当只需要少量切换时,用v-if

循环遍历

v-for遍历数组

1
2
3
4
5
<div id="app">
<ul>
<li v-for="item in movies">{{item}}</li>
</ul>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
movies: ['星际穿越','蜘蛛侠','复仇者联盟','泰坦尼克号']
}
})
</script>

如果想要显示出数组中每一个元素的索引,则使用index

1
2
3
4
5
<div id="app">
<ul>
<li v-for="(item, index) in movies">{{index}}·{{item}}</li> <!--显示元素索引-->
</ul>
</div>

v-for遍历对象属性

1
2
3
4
5
<div id="app">
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'HuaZhu',
age: 18,
height: 1.84
}
}
})
</script>

效果如下图:

如果想获取key值以及index,可以参考下面的写法:

1
2
3
4
5
6
7
<div id="app">
<ul>
<li v-for="(item, key, index) in info">{{index}}-{{key}}-{{item}}</li>
<br>
<li v-for="(index, key, item) in info">{{index}}-{{key}}-{{item}}</li>
</ul>
</div>

效果如下图:

注意顺序:

一般按照v-for="(item, key, index)该顺序去编写。(不由关键字,而是与位置有关)

key属性

一般在使用v-for时,会绑定一个key属性,以提高效率。

以上述列表展示为例,如果说在一个数组中插入一个元素,那么插入位置之后的<li>标签都会更新(向后推value值),但是一旦列表元素多了,这样的插入是很低效地,于是使用key去绑定item(注意:不可以绑定index,这样是无效的)。如此一来进行插值等更新列表的操作就只会在改动的列表元素对应的更新<li>标签。

另一方面,使用key去绑定item还可以保证数组元素的唯一性,如果添加重复数据会报错。

1
2
3
4
5
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>

建议使用此写法,以提高性能。

关于数组的响应式方法

首先明确什么是相应式方法:在数组调用该方法修改内部元素时,前端页面会实时更新。包含:

  • push():在数组末尾增添元素(可以为多个)。
  • pop():在数组末尾删除元素。
  • shift():在数组头部增添元素。
  • unshift():在数组头部删除元素
  • splice()
    • 删除元素:第二个参数传入你要删除几个元素(如果没有传,就删除后面所有的元素)
    • 替换元素:第二个参数, 表示我们要替换几个元素, 后面是用于替换前面的元素
    • 插入元素:第二个参数, 传入0, 并且后面跟上要插入的元素
  • sort():给数组元素排序
  • reverse():反转数组元素

这里以push()方法为例:

1
2
3
4
5
6
<div id="app">
<ul>
<li v-for="item in letters">{{item}}</li>
</ul>
<button @click="btnClick">按钮</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A','B','C','D','E']
},
methods: {
btnClick () {
this.letters.push('Z')
}
}
})
</script>

效果如下:

了解了响应式方法之后要说明:通过索引值修改数组中的元素页面是不会实时响应的(尽管数组元素会发生变化)

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A','B','C','D','E']
},
methods: {
btnClick () {
this.letters[0] = 'ZZZZ';
}
}
})
</script>

效果如下:

表单绑定(v-model)

表单元素和数据的双向绑定

之前一直都是通过修改data中数据的值去改变前端页面展示的效果,现在通过v-model可以双向绑定,即在input输入框中键入字符,data中的数据也可以随之改变,具体效果如下:

代码如下,通过v-model绑定message:

1
2
3
4
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇'
}
})
</script>

当然按照之前的学习内容我们也可以实现相同的效果,需要v-on绑定事件,以及event事件:

1
2
3
4
<div id="app">
<input type="text" :value="message" @input="message = $event.target.value">
<h2>{{message}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇'
}
})
</script>

所以:

<input type="text" v-model="message">

等同于

<input type="text" :value="message" @input="message = $event.target.value">

结合radio类型使用

1
2
3
4
5
6
7
8
9
<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>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
sex: '' //如果要设定初始默认选项,直接修改sex的值即可
}
})
</script>
  • 之前为了实现选项间的互斥,还需要在每一个input标签中增添相同的name属性,而v-model本身就可以实现互斥。

  • 如果要增添初始默认选项,直接在data中修改关键字即可。

  • 在每一个input项外套一个label标签的好处就是,在点击文字的时候也可以进行选择,效果如下:

结合checkbox类型使用

一般在单选框时,v-model绑定的值为布尔类型:

1
2
3
4
5
6
7
<div id="app">
<label for="license">
<input type="checkbox" id="license" v-model="isAgree">同意协议
</label>
<h2>您选择的是: {{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
isAgree: false
}
})
</script>

效果如下:

下面来看多选框的情况:

1
2
3
4
5
6
7
<div id="app">
<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>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
hobbies: [], //如果默认选定项目,可以在列表中提前写入
}
})
</script>

效果如下:

结合select类型使用

首先来看单选的情况:

1
2
3
4
5
6
7
8
9
<div id="app">
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruit}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
fruit: '' //如果默认选中某一项,可在此处添加
}
})
</script>

效果如下:

下面再看多选的情况,利用multiple属性:

1
2
3
4
5
6
7
8
9
<div id="app">
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruits}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
fruits: [] //默认选中某些选项,可在此处添加
}
})
</script>

按住Ctrl键,就可以实现多选,效果如下:

动态值绑定

前面的例子中所有的input或是option标签中的value属性都是写死在前端的,这样的话在后期修改的时候会很麻烦,因此在实际操作过程中建议使用动态值绑定,可以根据后端传来的数据动态更新选项列表:

1
2
3
4
5
6
<div id="app">
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" v-model="hobbies" :id="item">{{item}}
</label>
<h2>您的爱好是: {{hobbies}}</h2>
</div>
1
2
3
4
5
6
7
8
9
<script>
const app = new Vue({
el: '#app',
data: {
hobbies: [],
originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球'] //接收后端传来的数据
}
})
</script>

v-model的修饰符

lazy修饰符

v-model双向绑定时会实时更新内容,但是在一些场景中我们并不需要如此,一方面会降低效率,另一方面也会影响观感。所以希望仅在敲击Enter键input失去焦点时进行更新,由此使用lazy修饰符:

1
2
3
4
<div id="app">
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好哇'
}
})
</script>

效果如下:

number修饰符

v-model默认输入的内容都为string类型,即便在一开始设初值为number类型,在绑定后输入任何字符都会改为string类型。因此想要输入number类型,就需要用到number修饰符。(不允许输入除数字以外的字符类型)

1
2
3
4
<div id="app">
<input type="number" v-model.number="num">
<h2>{{num}}-{{typeof num}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
num: ''
}
})
</script>

效果如下:

注意:如果一开始赋初值为或者string类型的字符串,那么最开始会显示为string类型,一旦输入了数字之后,原先默认的字符串会被清除。(且不允许输入除数字以外的字符类型)

在Mustache中可以利用typeof关键词去查看变量类型。

trim修饰符

如果不加以限制,在字符串首尾输入任意数量的空格将会被记录,如果想要去除首尾空格,则可以使用trim修饰符:

1
2
3
4
<div id="app">
<input type="text" v-model.trim="name">
<h2>您的名字为:{{name}}</h2>
</div>
1
2
3
4
5
6
7
8
<script>
const app = new Vue({
el: '#app',
data: {
name: ''
}
})
</script>

这里就不做演示了。

箭头函数

再补充一下ES6的箭头函数的使用方式。

箭头函数:一种定义函数的方式。一般在当一个函数作为另一个函数的参数时使用。

基本使用

格式:const 函数名 = (参数列表) => {}

例(加法函数):

1
2
3
const sum = (num1, num2) => {
return num1 + num2
}

注意:

  • 如果参数只有一个的情况,则参数的小括号可以省略:

    例(平方函数):

    1
    2
    3
    const power = num => {
    return num * num
    }
  • 如果函数体只有一行,则可以省略return

    例(乘法函数):

    1
    const mul = (num1, num2) => num1 * num2

    注意:函数体大括号和return要么都写,要么都不写。只写一个会报错。

this的使用

结论:箭头函数中的this引用的是最近作用域中的this。(向外层查找this,直到有this的定义)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const obj = {
fun() {
setTimeout(function () {
setTimeout(function () {
console.log(this); // Window
})

setTimeout(() => {
console.log(this); // Window
})
})

setTimeout(() => {
setTimeout(function () {
console.log(this); // Window
})

setTimeout(() => {
console.log(this); // Object(指向定义的fun()函数)
})
})
}
}

obj.fun()

后记

此篇结束。

(欢迎评论区留言指正)