3. Vue 模板语法
差值表达式
指令
事件绑定
属性绑定
样式绑定
分支循环结构
3.1 指令
1.什么是指令?
指令的本质就是自定义属性
指令的格式:以v-开始(例如:v-clock)
2. v-cloak指令用法
差值表达式存在的问题:“闪动“-连续刷新页面会出现先弹出{{msg}之后在替换成值的情况。
如何解决该问题:使用v-cloak指令
原理:先隐藏,替换好值之后在显示最终的值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>02 v-cloak</title> <style> [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <div v-cloak>{{msg}}</div> </div> <script src="js/vue.min.js"></script> <script> /* v-cloak指令的用法 1. 提供样式: [v-cloak] { display: none; } 2. 在差值表达式所在的标签中添加v-cloak指令 */ var vm = new Vue({ el: '#app', data: { msg: 'Hello Vue' } }); </script> </body> </html>
3. 数据绑定指令
v-text 填充纯文本
相比插值表达式更加简洁
v-html 填充HTML片段
存在安全问题
本网站内部数据可以使用,来自第三方的数据不可使用
v-pre 填充原始信息
显示原始信息,跳过编译过程
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>02 v-cloak</title> <style> [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <div v-cloak>{{msg}}</div> <div v-text=msg></div> <div v-html=msg1></div> <div v-pre>{{跳过编译过程输出内容}}</div> </div> <script src="js/vue.min.js"></script> <script> var vm = new Vue({ el: '#app', data: { msg: 'Hello Vue', msg1:'<h1>HTML</h1>' } }); </script> </body> </html>
4.数据响应式
如何理解响应式
html5中的响应式(屏幕尺寸的变化导致样式的变化)
数据的响应式(数据的变化导致页面内容的变化)
什么是数据绑定
数据绑定:将数据团填充到标签中
v-once 只编译一次
显示内容之后不再具有响应式功能
<body> <div id="app"> <div v-cloak>{{msg}}</div> <div v-once>{{msg1}}</div> </div> <script src="js/vue.min.js"></script> <script> /* v-once的应用场景:如果显示的信息后续不需要修改,可以使用v-once,提高性能 */ var vm = new Vue({ el: '#app', data: { msg: 'Hello Vue', msg1:'nihao' } }); </script> </body>
3.2 双向数据绑定
v-model指令用法:在表单控件或者组件上创建双向绑定
示例代码如下:
<body> <div id="app"> <div>{{msg}}</div> <div> <input type="text" v-model="msg"> </div> </div> <script src="js/vue.min.js"></script> <script> var vm = new Vue({ el: '#app', data: { msg: 'Hello Vue' } }); </script> </body>
MVVM设计思想
M(model)
V (View)
VM(View-Model)
3.3 事件绑定
Vue如何处理事件与实践函数的调用方式:
v-on指令用法 简写模式:@
<input type='button' v-on:click='num++'> //如下为简写样式,把v-on改成了@ <input type='button' @click='num++'>
事件函数的调用方式
直接绑定函数名称
<button v-on:click='say'>Hello</button>
事件绑定调用函数
<button v-on:click='say()'>Hello</button>
v-on 指令与实践函数的调用方式示例代码如下:
<body> <div id="app"> <div>{{num}}</div> <button v-on:click='num++'>点击1</button> <button @click='num++'>点击2</button> <button @click='handle'>点击3</button> <button @click='handle()'>点击4</button> </div> <script src="js/vue.min.js"></script> <script> // 事件绑定 var vm = new Vue({ el: '#app', data: { num: 0 }, methods:{ handle:function(){ // this是Vue的实例对象 this.num++; } } }); </script> </body>
事件函数参数传递
普通参数和事件参数
示例代码如下:
<body> <div id="app"> <div>{{num}}</div> <!-- 方式一:直接绑定函数名称 --> <button @click='handle1'>点击1</button> <!-- 方式二:事件绑定调用函数 --> <button @click='handle2(123,456,$event)'>点击2</button> <!-- $event为事件对象是固定的 --> </div> <script src="js/vue.min.js"></script> <script> /* 事件绑定 - 参数传递 1.如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数 2.如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递 */ var vm = new Vue({ el: '#app', data: { num: 0 }, methods: { /* 按钮2 */ handle2: function (event) { console.log(p1, p2); console.log(event.target.innerHTML) this.num++; // this是Vue的实例对象 }, /* 按钮1 */ handle1: function (event) { console.log(event.target.innerHTML) this.num++; // this是Vue的实例对象 } } }); </script> </body>
事件修饰符
.stop 阻止冒泡
.prevent 阻止默认事件
示例代码如下:
<body> <div id="app"> <div>{{num}}</div> <!-- 事件绑定调用函数 --> <div @click='handle1($event)'> <!-- .stop 阻止冒泡 --> <button @click.stop='handle2($event)'>点击</button> </div> <div> <!-- .prevent阻止默认事件 --> <a @click.prevent='handle3($event)' href="www.baidu.com">百度</a> </div> </div> <script src="js/vue.min.js"></script> <script> var vm = new Vue({ el: '#app', data: { num: 0 }, methods: { handle1: function (event) { this.num++; // this是Vue的实例对象 }, /* 按钮 */ handle2: function (event) {}, handle3: function (event) {} } }); </script> </body>
按键修饰符
.enter 回车键
.delete 删除键
示例代码如下:
<body> <div id="app"> <form action=""> 用户名:<input type="text" v-model='uname' v-on:keyup.delete='clearContent'><br> 密码:<input type="text" v-model='pwd' v-on:keyup.delete='clearContent'><br> <!-- v-on:.click.keyup.enter='handleSubmit'的意思是点击按钮或者敲击回车键都可提交 --> <input type="button" value="提交" v-on:.click.keyup.enter='handleSubmit'> </form> </div> <script src="js/vue.min.js"></script> <script> var vm = new Vue({ el: '#app', data: { uname: '', pwd: '' }, methods: { clearContent: function () { this.uname = '', this.pwd = ''; }, handleSubmit: function () { console.log(this.uname, this.pwd) }, } }); </script> </body>
自定义按键修饰符
全局 config.keyCodes对象
示例代码如下:
<body> <div id="app"> <form action=""> 用户名:<input type="text" v-model='info' v-on:keyup.a='handle1'><br> </form> </div> <script src="js/vue.min.js"></script> <script> /* 事件绑定 - 自定义按键修饰符 规则:自定义按键修饰符名字是自定义的,但是对应的值必须是按键对应的event.keyCode值 */ Vue.config.keyCodes.a = 65 var vm = new Vue({ el: '#app', data: { info: '' }, methods: { handle1: function (event) { console.log(event.keyCode) } } }); </script> </body>
3.4 属性绑定
1. Vue如何动态处理属性?
v-bind指令用法
<body> <div id="app"> <!-- 标准写法如下:v-bind:--> <!-- <a v-bind:href="url" id="a">{{msg1}}</a> --> <!-- 简写方法如下:':'--> <a :href="url" id="a">{{msg1}}</a> <button v-on:click='handle'>切换</button> </div> <script src="js/vue.min.js"></script> <script> /* 属性绑定 */ var a = document.getElementById("a") var vm = new Vue({ el: '#app', data: { url: 'http://www.baidu.com', msg1: '百度', }, methods: { handle: function () { this.url = 'http://www.change.tm'; this.msg1 = '启嘉网' } } }) </script> </body>
2. v-model的底层实现原理分析
<body> <div id="app"> <div>{{msg}}</div> <input type="text" v-bind:value='msg' v-on:input='handle'> <!-- 这一句就省略了下面的handle方法 --> <input type="text" v-bind:value='msg' v-on:input='msg=$event.target.value'> <!-- v-model 方法最简便 --> <input type="text" v-model='msg'> </div> <script src="js/vue.min.js"></script> <script> /* v-model的本质 */ var vm = new Vue({ el: '#app', data: { msg: 'hello' }, methods: { handle: function (event) { // 使用输入域中的最新的数据覆盖原来的数据 this.msg = event.target.value } } }) </script> </body>
3.5 样式绑定
1. class样式处理
对象语法
<div v-bind:class="{active:isActive}"></div>
示例代码如下:
<style> .active { border: 2px black solid; width: 100px; height: 100px; } .error { background-color: darkmagenta; } </style> <body> <div id="app"> <div v-bind:class="{active:isActive,error:isError}">测试内容</div> <button v-on:click='handle'>切换</button> </div> <script src="js/vue.min.js"></script> <script> /* 样式绑定 */ var vm = new Vue({ el: '#app', data: { isActive: true, isError: true }, methods: { handle: function (event) { // 控制isActive的值在true和false之间进行切换 this.isActive = !this.isActive; this.isError = !this.isError; } } }) </script> </body>
数组语法
<div v-bind:class="[activeClass,errorClass]"></div>
数组语法修改样式示例代码如下:
<style> .active { border: 2px black solid; width: 100px; height: 100px; } .error { background-color: darkmagenta; } </style> <body> <div id="app"> <div v-bind:class="[activeClass,errorClass]">测试内容</div> <button v-on:click='handle'>切换</button> </div> <script src="js/vue.min.js"></script> <script> /* 样式绑定 */ var vm = new Vue({ el: '#app', data: { activeClass: 'active', errorClass: 'error' }, methods: { handle: function (event) { //直接置空修改样式 this.errorClass = ''; } } }) </script> </body>
样式绑定 - 细节处理:
(1)对象绑定和数字绑定可以结合使用
(2)class绑定的值可以简化操作
(3)默认的class如何处理?答案是:默认的class会保留
上述三点的测试代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>16 样式绑定-细节处理</title> <style> .active { border: 2px black solid; width: 100px; height: 100px; } .error { background-color: darkmagenta; } .test { color: darkorange; } .base{ font-size: 24px; } </style> </head> <body> <div id="app"> <!-- 细节一:对象绑定和数组绑定可以结合使用 --> <div v-bind:class="[activeClass,errorClass,{test:isTest}]">测试内容</div> <!-- 细节二:class绑定的值的简化操作--数组和对象都可简化 --> <div v-bind:class="arrClasses"></div> <div v-bind:class="objClasses">对象样式简化操作</div> <!-- 细节三:默认的class如何处理?答案是:默认的class会保留 --> <div class="base" v-bind:class="objClasses">默认的class</div> <button v-on:click='handle'>切换</button> </div> <script src="js/vue.min.js"></script> <script> /* 样式绑定 */ var vm = new Vue({ el: '#app', data: { activeClass: 'active', errorClass: 'error', isTest: true, arrClasses: ['active', 'error'], objClasses: { active: true, test: true } }, methods: { handle: function (event) { this.errorClass = ''; } } }) </script> </body> </html>
2. style(内联)样式处理
对象语法
<div v-bind:style="{color:activecolor,fontsize:fontsize}"></div>
数组语法
<div v-bind:style="[basestyle,overridingStyles]"></div>
style(内联)样式处理的对象语法和数组语法如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>16 样式绑定-细节处理</title> </head> <body> <div id="app"> <!-- 对象语法 --> <div v-bind:style='{border:borderStyle,width:widthStyle,height:heightStyle}'></div> <div v-bind:style='objStyle'></div> <!-- 数组语法: --> <div v-bind:style='[objStyle,overridingStyles]'></div> <button v-on:click='handle'>切换</button> </div> <script src="js/vue.min.js"></script> <script> /* 样式绑定 */ var vm = new Vue({ el: '#app', data: { borderStyle: '2px solid black', widthStyle: '100px', heightStyle: '100px', objStyle: { border: '5px solid green', width: '200px', height: '200px' }, overridingStyles: { /* overridingStyles会覆盖之前原有的样式 */ border: '3px solid red', backgroundColor: 'pink' } }, methods: { handle: function (event) { this.widthStyle = '200px'; this.objStyle.width = '100px' } } }) </script> </body> </html>
3.6 分支循环结构
1. 分支结构
v-if
v-else
v-else-if
v-show
2. v-if与v-show的区别
v-if控制元素是否渲染到页面
v-show控制元素是否显示(已经渲染到了页面)
示例代码如下:
<body> <div id="app"> <div v-if='score>=90'>优秀</div> <div v-else-if='score<90&&score>=80'>良好</div> <div v-else-if='score<80&&score>=60'>及格</div> <div v-else>差</div> <div v-show='flag'>测试v-show</div> <button v-on:click='handle'>点击切换</button> </div> <script src="js/vue.min.js"></script> <script> /* 分支结构 v-show的原理:控制元素样式是否显示 display:none */ var vm = new Vue({ el: '#app', data: { score:20, flag:false }, methods: { handle:function(){ this.flag=!this.flag } } }); </script> </body>
3. 循环结构
v-for遍历数组
key的作用:帮助Vue区分不同的元素,从而提高性能
<body> <div id="app"> <div>水果列表</div> <ul> <li v-for='item in fruits'>{{item}}</li> <!-- 可以加上索引 --> <li v-for='(item,index) in fruits'>{{item + '---' + index}}</li> <!-- key 的作用:帮助Vue区分不同的元素,从而提高性能 --> <li :key='item.id' v-for='item in myFruits'> <span>{{item.ename}}</span> <span>------</span> <span>{{item.cname}}</span> </li> </ul> </div> <script src="js/vue.min.js"></script> <script> /* 循环结构 */ var vm = new Vue({ el: '#app', data: { fruits: ['apple', 'banana', 'orange'], myFruits: [{ id: 1, ename: 'apple', cname: '苹果' }, { id: 2, ename: 'banana', cname: '香蕉' }, { id: 3, ename: 'orange', cname: '橘子' }] }, }); </script> </body>
4. v-if和v-for结合使用
v-for遍历对象
<div v-for='(value,key,index) in object'></div>
v-if和v-for结合使用
语法如下:
<div v-if='value == 12' v-for='(value,key,index) in object'></div>
示例代码如下:
<body> <div id="app"> <div v-if='value== "张三"' v-for='(value,key,index) in object'>{{value + '---' + key + '---' + index}}</div> </div> <script src="js/vue.min.js"></script> <script> /* v-if和v-for结合使用 */ var vm = new Vue({ el: '#app', data: { object : { name: '张三', age: 19, hobby: 'eat' } } }); </script> </body>