模板语法⭐
1.插值操作
- 如何将data中的文本数据,插入到HTML中呢?
- 我们已经学习过了,可以通过Mustache语法(也就是双大括号)。
- Mustache: 胡子/胡须.
- 我们可以像下面这样来使用,并且数据是响应式的
1.1 on-once 的基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <body> <div id="app"> <h2>{{message}} </h2> <h2 v-once>{{message}} </h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello Vue' } }) </script>
|
1.2 v-html的基本使用
- 某些情况下,我们从服务器请求到的数据本身就是一个HTML代码
- 如果我们直接通过
双括号
来输出,会将HTML代码也一起输出。
- 但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。
- 如果我们希望解析出HTML展示
- 可以使用v-html指令
- 该指令后面往往会跟上一个string类型
- 会将string的html解析出来并且进行渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <body> <div id="app"> <h2>{{url}} </h2> <h2 v-html='url'></h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { url: '<a href="https://www.baidu.com">百度一下</a>' } }) </script>
|
1.3 v-text 的基本用法
- v-text作用和Mustache比较相似:都是用于将数据显示在界面中
- v-text通常情况下,接受一个string类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <body> <div id="app"> <h2>{{message}},haha </h2> <h2 v-text='message'>hahha</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue' } }) </script>
|
1.4 v-pre 的基本使用
- v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
- 比如下面的代码:
- 第一个p标签中的内容会被编译解析出来对应的内容
- 第二个p标签中会直接显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <body> <div id="app"> <h2>{{message}} </h2> <h2 v-pre>{{message}}</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue' } }) </script>
|
1.5 v-cloak 的基本使用
- 在某些情况下,我们浏览器可能会直接显然出未编译的Mustache标签。
- cloak: 斗篷
- 在刷新之前不希望把 {message}} 以这种形式显示出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <style> [v-cloak] { display: none; } </style> <!-- 在刷新之前不希望把 {message}} 以这种形式显示出来 -->
<body> <div id="app"> <h2 v-cloak>{{message}} </h2> </div> </body> <script src="../js/vue.js"></script> <script> setTimeout(() => { const app = new Vue({ el: '#app', data: { message: 'hello vue' } }) }, 1000) </script>
|
2. 绑定属性 v-bind的使用
2.1 v-bind 绑定 class (对象语法)
绑定方式:对象语法
- 对象语法的含义是:class后面跟的是一个对象。
- 对象语法有下面这些用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 用法一:直接通过{}绑定一个类 <h2 :class="{'active': isActive}">Hello World</h2>
用法二:也可以通过判断,传入多个值 <h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法三:和普通的类同时存在,并不冲突 注:如果isActive和isLine都为true,那么会有title/active/line三个类 <h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法四:如果过于复杂,可以放在一个methods或者computed中 注:classes是一个计算属性 <h2 class="title" :class="classes">Hello World</h2>
|
2.2 v-bind 绑定 style
:style=”{color: currentColor, fontSize: fontSize + ‘px’}”
- style后面跟的是一个对象类型
- 对象的key是CSS属性名称
- 对象的value是具体赋的值,值可以来自于data中的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <body> <div id="app"> <h2 :style="{fontSize:'50px',color:'red'}">{{message}}</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue', } }) </script>
|
3.计算属性
3.1什么是计算属性,为什么要使用它
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,例如:
1 2 3
| <div id="example"> {{ message.split('').reverse().join('') }} </div>
|
在这个地方,模板不再是简单的声明式逻辑,你必须看一段时间才能意识到,这里是想要显示变量 message
的翻转字符串,当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
- 使用 方法 methods
- 使用 计算属性 compute
3.2 计算属性和方法的区别
- 计算属性是基于他们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时,才会重新求值(也就是说,计算属性会把数据进行缓存)
- 而方法不会把数据进行缓存, 所以用计算属性效率会更高点
所以,对于任何复杂逻辑,都应该使用计算属性
- 在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
- 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
- 但是如果多个地方都需要显示完整的名称,我们就需要写多个
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 27 28 29 30 31 32
| <body> <div id="app"> <h2>{{firstName + ' ' + lastName}}</h2> <h2>{{firstName}} {{lastName}}</h2> <h2>{{getFullName()}}</h2> <h2>{{fullName}}</h2>
</div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { firstName: 'Lron', lastName: 'Man' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName
} }, methods: { getFullName: function () { return this.firstName + ' ' + this.lastName } } }) </script>
|
3.3 计算属性的setter和getter
每个计算属性都有 set 和 get 方法 ,但一般我们不用去设置 set 方法, 只用 get 的方法 只读属性
1 2 3 4 5 6 7 8 9 10
| computed:{ fullName:{ get(){}, set(){} } }
fullName(){ }
|
4.监听事件(v-on),事件处理
在前端开发中,我们需要经常和用于交互。
- 这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等
- 在Vue中如何监听事件呢?使用v-on指令
v-on介绍
- 作用:绑定事件监听器
- 缩写:@
- 预期:Function | Inline Statement | Object
- 参数:event
4.1 v-on 基本语法
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 27 28 29 30 31 32 33 34 35
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <div id="app"> <h1>{{ message }}</h1> <button v-on:click="onClick">测试</button>
</div> <script src="node_modules/vue/dist/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message: "Hello Vue.js!" },
methods: { onClick() { window.alert("hello"); } } }); </script> </body> </html>
|
4.2 处理函数的 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <div id="app"> <h1>{{ message }}</h1> <button @click="onClick">测试</button> <button @click="onClick2">测试2</button> </div> <script src="node_modules/vue/dist/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message: "Hello Vue.js!" }, methods: { onClick() { console.log(this === app);
this.message = "hello"; },
onClick2: () => { console.log(this); } } }); </script> </body> </html>
|
4.3 v-on 的参数传递问题
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div id="app"> <button @click="btn1()">按钮1</button> <button @click="btn1">按钮1</button>
<button @click="btn2(123)">按钮2</button> <button @click="btn2()">按钮2</button> <button @click="btn2">按钮2</button>
<button @click="btn3(123,$event)">按钮3</button>
</div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: {
}, methods: { btn1() { console.log('btn1'); }, btn2(event) { console.log(event); }, btn3(abc, event) { console.log(abc, event); } } }) </script>
</html>
|
4.4 v-on 修饰符
- .stop - 调用 event.stopPropagation()。
- .prevent - 调用 event.preventDefault()。
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
- .native - 监听组件根元素的原生事件。
- .once - 只触发一次回调。
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <style> .my { width: 100px; height: 100px; background-color: pink; } </style>
<body> <h4>.stop : 调用 event.stopPropagation() 阻止冒泡事件</h4> <h4>.prevent : 调用 event.preventDefault() 阻止默认事件</h4> <h4> .[keyCode|keyAlias] 只当事件是从待定键触发时才触发回调</h4>
<div id="app"> <div class="my" @click="divClick"> <button @click.stop="btnClick">按钮</button> </div> <br> <form action="aaa"> <input type="submit" value="提交" @click.prevent="inpClick"> </form> <br> <input type="text" @keyup.enter="keyup"> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue', }, methods: { divClick() { console.log('div'); }, btnClick() { console.log('btn'); }, inpClick() { console.log('inp'); }, keyup() { console.log('keyup'); } } }) </script>
</html>
|
5.条件判断
5.1 v-if 、 v-else-if 、 v-else
v-if、v-else-if、v-else
- 这三个指令与JavaScript的条件语句if、else、else if类似。
- Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件
5.2 v-if 和 v-show 的区别
- v-if条件渲染,如果条件为 false , 则不渲染元素
- true 渲染 DOM
- false 不渲染 DOM
- v-show 条件显示,无论条件的真假始终都渲染元素
- true 渲染 DOM
- false 渲染DOM ,但不显示(display:none)
- 不能和 v-else-if 、 v-else 结合使用
一般来说, v-if
有更高的切换开销, 而 v-show
有更高的初始渲染开销。 因此、如果需要非常频繁地切换,则使用 v-show
较好; 如果在运行时条件很少改变,则使用v-if
较好
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 27 28 29 30 31 32
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body>
<div id="app"> <h2 v-if="isShow" id="A">{{message}}</h2> <h2 v-show="isShow" id="B">{{message}}</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue', isShow: false } }) </script>
</html>
|
6.循环遍历
6.1 v-for 遍历数组
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 27
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div id="app"> <h2 v-for="item in names">{{item}}</h2> <h2 v-for="(item,index) in names">{{index}}.{{item}}</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { names: ['张三', '李四', '王五'] } }) </script>
</html>
|
6.2 检测数组更新
这些常见的数组操作方法都会正常的进行视图更新:
1 2 3 4 5 6 7
| push(); pop(); shift(); unshift(); splice(); sort(); reverse();
|
或者直接对数组进行重新赋值:
6.3 v-for 遍历对象
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 27 28 29 30 31 32 33 34 35 36
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div id="app"> <h2 v-for="value in info">{{value}}</h2>
<h2 v-for="(value,key) in info">{{key}}:{{value}}</h2>
<h2 v-for="(value,key,index) in info">{{index}}--{{key}}:{{value}}</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { info: { name: 'wpf', age: 18, sex: '男' } } }) </script>
</html>
|
6.4 v-for 和 key
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
属性:
1 2 3
| <div v-for="item in items" v-bind:key="item.id"> </div>
|
建议尽可能在使用 v-for
时提供 key
attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key
并不仅与 v-for
特别关联。后面我们将在指南中看到,它还具有其它用途。
注意:
- 不要使用对象或数组之类的非基本类型值作为
v-for
的 key
。请用字符串或数值类型的值。
- 不要使用遍历索引 index 作为唯一的 key 值,会有问题
- 一般使用数据中能表示唯一的那个字段,例如 id
7.表单绑定
- Vue中使用v-model指令来实现表单元素和数据的双向绑定。
- 案例的解析:
- 当我们在输入框输入内容时
- 因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。
- 当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
所以,通过v-model实现了双向的绑定。
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 27 28
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div id="app"> <div>{{message}}</div> <input type="text" v-model="message"> {{message}} </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue', } }) </script>
</html>
|
7.1 v-model 原理
- v-model 其实是一个语法糖,它的背后本质上是包含俩个操作:
- v-bind 绑定一个 value 属性
- v-on 指令给当前元素绑定 input 事件
- 也就是说下面的代码:等同于下面的代码:
1 2 3
| <input type="text" v-model="message"> 等同于 <input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
|
7.2 v-model : checkbox
- 复选框分为俩种情况:单个勾选框和多个勾选框
- 单个勾选框:
- v-model 即为布尔值。
- 此时input的value并不影响v-model的值。
- 多个复选框:
- 当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
- 当选中某一个时,就会将input的value添加到数组中。
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div id="app"> <label for="agreement"> <input type="checkbox" id="agreement" v-model="isAgree">同意协议 </label> <br> <button :disabled="!isAgree">下一步</button> <br><br>
<h2>你的爱好是:{{hobbies}}</h2>
<label v-for="item in originHobbies" :for="item"> <input type="checkbox" :id="item" :value="item" v-model="hobbies">{{item}} </label> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue', isAgree: false, hobbies: [], originHobbies: ['足球', '篮球', '羽毛球', '排球'] } }) </script>
</html>
|
7.3 v-model : select
- 和checkbox一样,select也分单选和多选两种情况。
- 单选:只能选中一个值。
- v-model绑定的是一个值。
- 当我们选中option中的一个时,会将它对应的value赋值到mySelect中
- 多选:可以选中多个值。
- v-model绑定的是一个数组。
- 当选中多个值时,就会将选中的option对应的value添加到数组mySelects中
7.4 v-model 修饰符的使用
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div id="app">
<input type="text" v-model.lazy="message"> <h2>{{message}}</h2>
<input type="number" v-model.number="age"> <h2>{{age}}--- {{typeof age}}</h2>
<input type="text" v-model.trim="name"> <h2>你的名字是:{{name}} 注意在这里(浏览器里默认空格去除了,但真实的数据没有,F12进行操作查看)</h2> </div> </body> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'hello vue', age: 18, name: '' } }) </script>
</html>
|