本节内容
Vue指令系统简介
vue1.x写法 vue2.x的写法
v-html ----> {{ }} # vue2.x 也支持v-html
v-bind:属性名 ----> :属性
v-on:事件名 ----> @事件名
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test vue</title> </head> <body> <div id="app"> <!-- vue的模板语法 --> <div>{{ msg }}</div> <div v-text="msg"></div> <div v-html="msg"></div> </div> <script src="vue.js"></script> <script> new Vue({ el:'#app', data(){ //记着data中是一个函数,函数中return一个对象,可以是一个空对象,但必须return return{ msg:'<h2>超</h2>', //后端返回的是标签,那么我们就可以直接通过v-html渲染出来标签效果 } } }) </script> </body> </html>
标签元素: <!-- vue对象最终会把条件的结果变成布尔值 --> <h1 v-if="ok">Yes</h1> data数据: data:{ ok:false // true则是显示,false是隐藏 }
标签元素: <h1 v-if="ok">Yes</h1> <h1 v-else>No</h1> data数据: data:{ ok:false // true则是显示,false是隐藏 }
标签元素: <h1 v-if="num===1">num的值为1</h1> <h1 v-else-if="num===2">num的值为2</h1> <h1 v-else>num的值是{{num}}</h1> data数据: data:{ num:2 }
标签元素: <h1 v-show="ok">Hello!</h1> data数据: data:{ ok:false // true则是显示,false是隐藏 }
v-show后面不能v-else或者v-else-if
v-show隐藏元素时,使用的是display:none来隐藏的,而v-if是直接从HTML文档中移除元素[DOM操作中的remove]
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
<标签名 :标签属性="data属性"></标签名>
<p :title="str1">{{ str1 }}</p> <!-- 也可以使用v-html显示双标签的内容,{{ }} 是简写 --> <a :href="url2">淘宝</a> <a v-bind:href="url1">百度</a> <!-- v-bind是vue1.x版本的写法 -->
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="index"> <img :src="url" :alt="title"><br> <input :type="type" placeholder="请输入wifi密码"> <button @click="type='text'">显示密码</button> <!--切换密码显示写法,但是一般不建议将这么复杂的逻辑直接写到属性值里面,一般通过事件操作来玩,下面就说一下事件操作--> <button @click="type=(type=='password'?'text':'password')">切换显示密码</button> // 还可以按照下面的方式用,但必须是{}包裹 <p v-bind:class="{active:status===false}">你是个p</p> <p v-bind:class="{active:status}">你是个p</p> </div> <script> let vm = new Vue({ el:"#index", data:{ url:"https://www.luffycity.com/static/img/head-logo.a7cedf3.svg", title:"路飞学成", type:"password", status:false, } }) </script> </body> </html>
<button v-on:click="num++">按钮</button> <!-- v-on 是vue1.x版本的写法 --> <button @click="num+=5">按钮2</button>
总结:
1. 使用@事件名来进行事件的绑定 语法: <h1 @click="num++">{{num}}</h1> 2. 绑定的事件的事件名,全部都是js的事件名: @submit ---> onsubmit @focus ---> onfocus ....
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <input :type="type"> <button @click="change_password_status">{{btn_text}}</button> </div> </body> <script src="vue.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return { num:10, btn_text:'显示密码', type:'password', } }, methods:{ change_password_status(){ if (this.type === 'password'){ this.type = 'text'; this.btn_text = '隐藏密码'; }else { this.type = 'password'; this.btn_text = '显示密码'; } } } })
格式: <h1 :class="值">元素</h1> 值可以是对象、对象名、数组(数组的方式用的比较少)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ background-color: red; height: 100px; width: 100px; } .c2{ background-color: green; height: 200px; width: 200px; } </style> </head> <body> <div id="app"> <div class="c1" :class="{c2:status}"></div> <div class="c1" :class="{c2:num>10,c3:num<10}"></div> <!-- <div :class="xx"></div>--> </div> </body> <script src="vue.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return { status:true, num:10, xx:'c1', } }, methods:{ } }) </script> </html>
总结:
1. 给元素绑定class类名。 vue对象的data数据: data:{ myObj:{ complete:true, uncomplete:false, } } html元素: <div class="box" :class="myObj">2222</div> 最终浏览器效果: <div class="box complete">2222</div>
注意:不能出现中横杠,有的话就套上'font-size',或者去掉横杠,后一个单词的首字母大写,比如fontSize
格式1:值是json对象,对象写在元素的:style属性中 标签元素: <div :style="{color: activeColor, fontSize: fontSize + 'px' }"></div> <!-- 注意:不能出现中横杠,有的话就套上'font-size',或者去掉横杠,后一个单词的首字母大写,比如fontSize --> data数据如下: data: { activeColor: 'red', fontSize: 30 } 格式2:值是对象变量名,对象在data中进行声明 标签元素: <div v-bind:style="styleObject"></div> data数据如下: data: { styleObject: { color: 'red', fontSize: '13px' } } 格式3:值是数组,不提了 标签元素: <div v-bind:style="[style1, style2]"></div> data数据如下: data: { style1:{ color:"red" }, style2:{ background:"yellow", fontSize: "21px" } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #card{ width: 500px; height: 350px; } .title{ height:50px; } .title span{ width: 100px; height: 50px; background-color:#ccc; display: inline-block; line-height: 50px; /* 设置行和当前元素的高度相等,就可以让文本内容上下居中 */ text-align:center; } .content .list{ width: 500px; height: 300px; background-color: yellow; display: none; } .content .active{ display: block; } .title .current{ background-color: yellow; } </style> <script src="vue.js"></script> </head> <body> <div id="card"> <div class="title"> <span :class="{current:num===0}" @click="num=0">国内新闻</span> <span :class="{current:num===1}" @click="num=1">国际新闻</span> <span :class="{current:num===2}" @click="num=2">银河新闻</span> <!--<span>{{num}}</span>--> </div> <div class="content"> <div class="list" :class="{active:num===0}">国内新闻列表</div> <div class="list" :class="{active:num===1}">国际新闻列表</div> <div class="list" :class="{active:num===2}">银河新闻列表</div> </div> </div> <script> // 思路: // 当用户点击标题栏的按钮[span]时,显示对应索引下标的内容块[.list] // 代码实现: var card = new Vue({ el:"#card", data:{ num:0, }, }); </script> </body> </html>
在vue中,可以通过v-for指令可以将一组数据渲染到页面中,数据可以是数组或者自定义对象。
key指定的生成的标签,不会再重复的创建了,渲染效率就高一些,重点:如果不通过:key来绑定标签,那么频繁的调整标签顺序时,会导致数据混乱的问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> </style> </head> <body> <div id="app"> <h1>演员列表:</h1> <ul> <!-- <li v-for="(value,index) in person_list" :key="index">{{value}} -- {{index}}</li>--> <!-- 通过:key指定的生成的标签,不会再重复的创建了,渲染效率就高一些,重点:如果不通过:key来绑定标签,那么频繁的调整标签顺序时,会导致数据混乱的问题 --> <!-- <li v-for="(value,index) in person_info">{{value}} -- {{index}}</li>--> <!-- <li v-for="value in person_info">{{value}} -- {{index}}</li>--> <!-- <li v-for="value,index in person_info">{{value}} -- {{index}}</li>--> <li v-for="(value,index) in person_info">{{value}} -- {{index}}</li> </ul> </div> </body> <script src="vue.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return { person_list:['尤佳', '鸿昌', '老白', '王照',], person_info:{ name:'白金鸽', age:18, sex:'不知道', } } }, methods:{ } }) </script> </html>
数据是数组: <ul> <!--i是列表的每一个元素--> <li v-for="book in book_list">{{book.title}}</li> </ul> <ul> <!-- v-for不仅可以遍历数组,还可以遍历对象,这里大家记住v-for里面的一个东西 :key, 就是v-bind:key,这个key是干什么的呢,就是为了给现在已经渲染好的li标签做个标记,以后即便是有数据更新了,也可以在这个li标签里面进行数据的更新,不需要再让Vue做重新生成li标签的dom操作,提高页面渲染的性能,因为我们知道频繁的添加删除dom操作对性能是有影响的,我现在将数据中的id绑定到这里,如果数据里面有id,一般都用id,如果没有id,就绑定v-for里面那个index(当然你看你给这个索引取的变量名是什么,我这里给索引取的名字是index),这里面它用的是diff算法,回头再说这个算法 --> <!-- <li v-for="(item,index) in data.users" :key="item.id" @click> 还可以绑定事件 --> <li v-for="(item,index) in book_list" :key="item.id"> 第{{index+1}}本图书:{{book.title}}</li> <!-- v-for的优先级最高,先把v-for遍历完,然后给:key加数据,还有,如果没有bind这个key,有可能你的页面都后期用动态数据渲染的时候,会出现问题,所以以后大家记着,一定写上v-bind:key --> </ul> <script> var vm1 = new Vue({ el:"#app", data:{ book_list:[ {"id":1,"title":"图书名称1","price":200}, {"id":2,"title":"图书名称2","price":200}, {"id":3,"title":"图书名称3","price":200}, {"id":4,"title":"图书名称4","price":200}, ] } }) </script> 数据是对象: <ul> <!--i是每一个value值--> <li v-for="value in book">{{value}}</li> </ul> <ul> <!--value是每一个value值,attr是每一个键名--> <li v-for="value,attr in book">{{attr}}:{{value}}</li> </ul> <script> var vm1 = new Vue({ el:"#app", data:{ book: { // "attr属性名":"value属性值" "id":11, "title":"图书名称1", "price":200 }, }, }) </script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ background-color: green; } </style> </head> <body> <div id="app"> <table border="1"> <thead> <tr> <th>名称</th> <th>价格</th> </tr> </thead> <tbody> <tr :class="{c1:goods_value.price>60}" v-for="(goods_value,goods_index) in goods" :key="goods_index"> <td>{{goods_value.name}}</td> <td>{{goods_value.price}}</td> </tr> </tbody> </table> </div> </body> <script src="vue.js"></script> <script> let vm = new Vue({ el:'#app', // 圈地 data(){ return { goods:[ {"name":"python入门","price":150}, {"name":"python进阶","price":100}, {"name":"python高级","price":75}, {"name":"python研究","price":60}, {"name":"python放弃","price":110}, ] } }, // 数据属性 methods:{ // 声明方法 } }) </script> </html>
七、 双向数据绑定 v-model
通过v-model 绑定data中数据,可以是相互影响的,例如input中的默认值等于msg的值,改变input值msg的值也相应改变
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <h2>{{msg}}</h2> <input type="text" v-model="msg"> </div> </body> <script src="../vue.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return { num:100, msg:'hello', } }, }) </script> </html>