三. v-show指令
v-show很简单, 就是隐藏/显示元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 我们开发过程中通常会遇到状态, 1:表示启用, 2:表示禁用 3: 表示删除--> <div id="app"> <h2 v-if = "isShow"> 启用 </h2> <h2 v-show = "isShow"> 启用 </h2> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { isShow: true } }); </script> </body> </html>
这两个都是可以显示出来, 我们设置isShow=false, 都隐藏了,但隐藏的结果是不同的. 我们来看看html代码
我们发现代码里只有useShow对象, 并且增加了display:none样式, 而没有useIf对象. 也就是被直接删除了
总结: v-if和v-show的区别
- v-if: true: 添加元素, false: 删除元素
- v-show: true: 增加样式display:block; false: 修改样式display:none
那么如何选择呢?
- 当现实与隐藏切换的很频繁的时候, 使用v-show
- 当只有一次切换时, 使用v-if
四. v-for指令
遍历有遍历数组, 遍历对象两种形式
1. 遍历数组
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> </head> <body> <div id="app"> <ul> <li v-for="item in languages">{{item}}</li> <li v-for="(item, index) in languages"> {{index}}--{{item}}</li> </ul> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { languages: ["java", "php", "python"] } }); </script> </body> </html>
遍历数组如果不带下标, 可以这么写
<li v-for="item in languages">{{item}}</li>
如果带有下标, 可以这么写
<li v-for="(item, index) in languages"> {{index}}--{{item}}</li>
2. 遍历对象
遍历对象有三种方式
- 只显示对象的value
- 显示对象的key和value
- 显示对象的index, key和value
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> </head> <body> <div id="app"> <p> 只显示对象的value </p> <ul> <li v-for="item in students">{{item}}</li> </ul> <p> 显示对象的key 和 value </p> <ul> <li v-for="(value, key) in students">{{key}} -- {{value}}</li> </ul> <p> 显示对象的编号 </p> <ul> <li v-for="(value, key, index) in students">{{index}} -- {{key}} -- {{value}} </li> </ul> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { students: { name: "zhangsan", age: 20, sex: "male" } } }); </script> </body> </html>
具体写法如上图. 需要注意的是, 当显示key和value的时候, value写在前面, key写在后面
3. 组件的key属性
官方推荐, 我们在使用v-for的时候, 应该给对应的元素添加一个:key属性
为什么要添加key属性呢?
详细参考这篇文章: https://www.jianshu.com/p/4bd5e745ce95
增加了:key以后,会让内部的计算性能提高, 那么应该怎么加呢?
<ul> <li v-for="item in students" :key="item">{{item}}</li> </ul>
使用的时候, 如上示例: :key="item",
- 写法: :key
- 值是什么? 这里的值必须是要可以和value一一对应的. 所以, 我们这里直接设置为item. 如果设置为index可以么? 当然不可以, 因为当想数组中增减元素的时候, index就变化了
4. 数组中哪些方法是响应式的
其实, 通常我们在遍历数组, 修改数组的值的时候, 习惯于使用下标修改.
如:
this.languages[0] = "aaaa";
但是, 我们看看,下标修改在vue中会怎么样呢?
我们发现修改了languages,但是页面没变化, 实际上确实是修改了
所以, 我们得出结论: 直接通过下标修改元素, 是非响应式的.
那么数组的其他方法呢?看下面的案例
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <ul> <li v-for="(item, index) in languages"> {{index}}--{{item}}</li> </ul> <br><br/><br/><br/><br/> <button @click="pushMethod">push</button> <button @click="popMethod">pop</button> <button @click="shiftMethod">shift</button> <button @click="unShiftMethod">unshift</button> <button @click="updateElement"></button> <button @click="spliceMethod">splice</button> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { languages: ["java", "php", "python", "go", "c语言"] }, methods: { pushMethod() { this.languages.push("其他语言") }, popMethod() { this.languages.pop() }, shiftMethod() { this.languages.shift() }, unShiftMethod() { this.languages.unshift("其他语言") }, updateElement(){ this.languages[0] = "aaaa"; }, spliceMethod() { /** * splice可以进行 * 1. 添加元素 splice(从第几个元素开始, 0, "未来语言1", "未来语言2") * 2. 删除元素 splice(从第几个元素开始, 删除几个元素) * 3. 修改元素: 其实是删除以后在添加 splice(从第几个元素开始, 修改几个元素, 修改的元素内容) */ // 删除元素 //this.languages.splice(1, 1) // 修改元素 //this.languages.splice(1, 2, "pthoon语言", "go语言") // 添加元素 this.languages.splice(1, 0, "未来语言1", "未来语言2") } } }); </script> </body> </html>
- push(从尾部添加元素---响应式的
- pop : 从尾部删除元素---响应式的
- shift : 从顶部删除元素---响应式的
- unshift : 从顶部添加元素---响应式的
- splice : 添加元素, 修改元素, 删除元素---响应式的
通过测试, 这几个方法都是响应式的.
所以, 如果我们想要修改/删除元素, 建议使用splice, 这样可以立刻看到效果.
五. v-model指令
1. v-model的基本用法
v-model指令用来实现表单元素和数组元素的双向绑定
- 在输入框输入内容时, 会实时将输入内容传递给data数据
- data数据发生变更, 也会实时同步给输入框
- 双向绑定
案例: 文本框输入双向同步
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <form> <input type="text" placeholder="请输入" v-model="message"> </form> message的内容是:{{message}} </div> <script src="../js/vue.js"></script> <script> let app = new Vue({ el: "#app", data: { message: "hello" } }); </script> </body> </html>
我们定义了一个变量message, 然后在input输入框中使用v-model="message"就可以和这个变量进行双向绑定了
2. v-model的原理
其实v-model包含了两个操作
- 一个是v-bind: 绑定data数据给input属性
- 另一个是v-on: 调用输入框的input事件, 实时修改data数据
案例: 模拟v-model的两步操作
首先, 我们知道让文本框显示data中message的值, 可以直接使用v-bind:value, 这样我们修改了message的值, 文本框自动响应
<input type="text" placeholder="请输入" :value="message">
这是将数据响应给文本框. 那么, 如何将文本框修改的内容,同步给数据呢? 使用文本框的输入事件: v-on:input
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <input type="text" placeholder="请输入" :value="message" @input="change"> <p>message的内容是:{{message}}</p> </div> <script src="../js/vue.js"></script> <script> let app = new Vue({ el: "#app", data: { message: "hello" }, methods: { change(event) { this.message = event.target.value; } } }); </script> </body> </html>
这里使用了@input给文本框绑定了input事件, change()方法没有加括号, 会自动将默认的参数event传过去, 如果想要显示的设置event参数, 可以试用@input="change($event)".
然后在change方法中, 设置this.message=event.target.value;
结论:
<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" v-on:input="message=$event.target.value">
2. v-model在radio中的使用
案例: 性别选择
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <form> <input type="radio" name="sex" id="male" value="男" v-model="sex">男 <input type="radio" name="sex" id="female" value="女" v-model="sex">女 </form> 当前选中的是: {{sex}} </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", sex: "男" } }); </script> </body> </html>
使用了v-model以后, 就可以不使用name属性了, 默认将具有同一个v-model值的radio作为一组
3. v-model在checkbox中的使用
1) checkbox单选框
案例: 是否同意协议
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <label for="agreeContent"> <input type="checkbox" name="agreeContent" id="agreeContent" value="同意协议" v-model="agreeContent">统一协议 <br/>当前选中的是: {{agreeContent}} </label> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", agreeContent: false } }); </script> </body> </html>
是否同意协议: data数据中agreeContent: 值是true或者false. true表示选中文本框, false表示取消选中
注意: label的好处
input被包在了label中, 这样的好处是, 点击文字也可以选中和取消. 如果不放在lable中,就必须选择复选框.
2) checkbox复选框
复选框的值是一个数组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <h2>单选框</h2> <label for="agreeContent"> <input type="checkbox" name="agreeContent" id="agreeContent" value="同意协议" v-model="agreeContent">同意协议 <br/>当前选中的是: {{agreeContent}} </label> <br/><br/><br/><br/><br/> <h2>复选框</h2> <form> <input type="checkbox" name = "hobby" value="乒乓球" v-model="hobbies">乒乓球 <input type="checkbox" name = "hobby" value="篮球" v-model="hobbies">篮球 <input type="checkbox" name = "hobby" value="足球" v-model="hobbies">足球 <input type="checkbox" name = "hobby" value="排球" v-model="hobbies">排球 <br/>当前选中的爱好是: {{hobbies}} </form> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", agreeContent: false, hobbies:[] } }); </script> </body> </html>
在data中定义了一个hobbies数组. 并且将这个数组绑定给checkbox付款框的每一项. 即可实现效果
区别:
- 单个复选框对应的data是bool类型
- 多个复选框对应的data是数组类型
4. v-model在select中的使用
1) select单选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <select v-model="selectOne"> <option id="apple" value="苹果" >苹果</option> <option id="banana" value="香蕉" >香蕉</option> <option id="strawberry" value="草莓" >草莓</option> <option id="grape" value="葡萄" >葡萄</option> </select> <br/> <p>当前选中的是: {{selectOne}}</p> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", sex: "男", selectOne:"苹果" } }); </script> </body> </html>
注意: 在select单选下拉框中, v-model要写在select元素上
2) select多选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <br/> <br/> <br/> <select v-model="favoriteFrite" multiple> <option id="apple" value="苹果" >苹果</option> <option id="banana" value="香蕉" >香蕉</option> <option id="strawberry" value="草莓" >草莓</option> <option id="grape" value="葡萄" >葡萄</option> </select> <br/> <p>当前选中的是: {{favoriteFrite}}</p> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", favoriteFrite:[] } }); </script> </body> </html>
在使用多选的时候, 在select中增加一个multiple即可设置为多复选.
在数据中, 我们需要将其设置为一个数组. 如favoriteFrite:[]
下面来看看效果
总结:
- 单选: 只能选中一个值, v-model绑定的是一个值
- 多选: 可以选中多个值, v-model绑定的是一个数组
6. v-model的修饰符
1. Lazy修饰符
默认情况下, v-model是实时双向同步的. 但有时候, 我们不希望他每次变化都实时响应, 那么, 可以使用lazy修饰符
v-model.lazy , 使用了lazy以后按回车或者文本框是去焦点即同步内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <input type="text" v-model.lazy="message"/> <p>message的内容是:{{message}}</p> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", count: 0, name:"zhangsan" } }); </script> </body> </html>
2. number修饰符
通常我们在写一个只能输入数字的文本框时, 会这么写<input type="number" v-model = "count">
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <input type="number" v-model = "count"> <p>count的类型: {{count}} --- {{typeof count}}</p> </div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "hello", count: 0, name:"zhangsan" } }); </script> </body> </html>
但这么写获取到的count值是什么类型呢? 我们使用{{typeof count}}来看看count的类型. 如下图
我们看到count的类型是String. 而不是number类型
如何才能让count是number类型呢? 使用v-model.number="count", 如下图:
<input type="number" v-model.number = "count">
3. trim修饰符
通常我们在文本框输入文本的时候, 可能会误输入空格, 我们可以使用trim修饰符, 去掉文本框左右的空格
<input type="text" v-model.trim="name">