{{ 可以写简单的表达式,不能是语句 }} 只能用于开始标签与结束标签中间,不能用于标签中
<div id="app"> <h1>{{ msg }},love baby</h1> <h1>{{ msg + '' + site}}</h1> <h1>{{ msg }} {{site}}</h1> <h1>{{ count*2 / 10 }}</h1> </div>
<div id="app"> <h1>会变化:{{ msg }}</h1> <h1 v-once>不会变化:{{ msg }}</h1> </div>
v-text会把innerTEXT中的内容覆盖,{{}}不会覆盖
<div id="app"> <h1>{{ msg }}内容不被覆盖</h1> <h1 v-text='msg'>内容被覆盖</h1> </div>
业务型功能有注入风险,不使用v-html
<div id="app"> <div>{{ web }}解析为文本</div> <br> <div v-html='web'>解析为html标签</div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { msg: '我爱宝贝', web: '<a href="http://www.baidu.com/">百度</a>' }, methods: { } }) </script>
<div id="app"> <h1 v-pre>不产生编译:{{ msg }}</h1> <br> <h1>正常双向绑定:{{ msg }}</h1> </div>
vue实例解析之前,h1标签有v-cloak属性
vue实例解析之后,h1标签没有了v-cloak属性
<style type="text/css"> [v-cloak]{ display: none; } </style> <div id="app"> <h1 v-cloak>{{ msg }}</h1> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> setTimeout(()=>{ var app = new Vue({ el: '#app', data: { msg: '我爱宝贝', web: '<a href="http://www.baidu.com/">百度</a>' }, methods: { } }) },1000) </script>
属性可变时,v-bind动态绑定标签属性和vue对象中数据
v-bind:src 可以写为 :src
<div id="app"> <!-- <img src="imgUrl" > imgUrl会被解析为普通字符串--> <img v-bind:src="imgUrl" v-bind:alt="alt"> <a :href="site">撩课学院</a> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { msg:'我爱宝贝', imgUrl:'https://i0.hdslb.com/bfs/face/ca4767f400f735032a9a8053db730476ea94e27d.jpg@96w_96h_1c_1s.webp', alt:'撩课学院', site:'http://www.baidu.com' }, methods: { } }) </script>
模板界面中,很多元素的样式是变化的,class/style用于动态绑定类和样式
<style type="text/css"> .red { color: red; } .f60 { font-size: 60px; } </style> <div id="app"> <h1 class="red">{{ msg }}</h1> <h1 :class="red">{{ msg }}</h1> <!--动态绑定样式--> <!--多个样式--> <!-- <p :class="{类名1:布尔值,类名2:布尔值}">{{ msg }}</p> --> <p class="box" :class="{red:true,f60:true}">{{ msg }}</p> <!--动态绑定样式和固定样式可以并存,不会相互覆盖--> <p class="box" :class="{red:isRed,f60:isF60}">{{ msg }}</p> <button type="button" @click="change">切换</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { msg: '我爱宝贝', red: 'red', f60: 'f60', isRed: true, isF60: true }, methods: { change(){ this.isRed = !this.isRed, this.isF60 = !this.isF60 } } }) </script>
使用数组动态绑定样式
<h1 class="red f60">{{ msg }}</h1> <!--用数组的方式动态绑定样式--> <h1 :class="[red,f60]">{{ msg }}</h1> <!--样式多的时候,封装到一个函数--> <!--使用事件调用函数时不写小括号,其他时候调用函数时要写小括号--> <h1 :class="getClass()">{{ msg }}</h1> <script> var app = new Vue({ el: '#app', data: { msg: '我爱宝贝', red: 'red', f60: 'f60', }, methods: { getClass(){ return [this.red,this.f60]; } } }) </script>
动态绑定style样式,以键值对数组的方式绑定多个可变样式,样式长可以抽出为一个函数
style=" 之间的内容是以 css 的形式解析的"
v-bind:style=" 之间的内容是以 js 的形式解析的"
font-size 对应 fontSize
<div id="app"> <p style="font-size: 50px;">{{ msg }}</p> <p :style="{fontSize: '50px'}">{{ msg }}</p> <!-- 以键值对数组的方式绑定多个样式 --> <p :style="{fontSize: f50,backgroundColor:red}">{{ msg }}</p> <!-- 样式多的时候抽出为一个函数 --> <p :style="getStyle()">{{ msg }}</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { msg: '我爱宝贝', red: 'red', f50: '50px', }, <!-- 注意这里的逗号,没有逗号报错 --> methods: { getStyle(){ return {fontSize: this.f50,backgroundColor:this.red}; } } }) </script>
v-on:click 可以简写为 @click
<div id="app"> <p>运算结果:{{count }}</p> <button v-on:click="sub()">-</button> <!-- 不用传参可以去掉小括号,仅限于事件调用函数,其他情况调用函数括号都不能去掉 --> <button @click="add">+</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { count: 0 }, methods: { sub(){ this.count--; }, add(){ this.count++; } } }) </script>
绑定事件的参数传递
<div id="app"> <!--不带参数--> <button type="button" @click="btn1()">有括号不传参</button> <button type="button" @click="btn2">没括号</button> <button type="button" @click="btn3(123,'a',true,msg)">有参数</button> <!--msg会在vue对象中找--> <!--事件对象参数用$event--> <button type="button" @click="btn4(123,'a',true,msg,$event)">事件对象参数</button> <!--msg会在vue对象中找--> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { msg:'我爱宝贝' }, methods: { btn1(args){ console.log(args); <!--undefined--> }, btn2(args){ console.log(args); <!--输出click事件对象--> }, btn3(arg1,arg2,arg3,arg4){ console.log(arg1,arg2,arg3,arg4); <!--输出所有参数--> // console.log(Arguments); <!--输出所有参数--> }, btn4(arg1,arg2,arg3,arg4,arg5){ console.log(arg1,arg2,arg3,arg4,arg5); <!--输出所有参数--> } } }) </script>
下面第一张图点击了button按钮,div关联的事件也触发了,称为冒泡
第二张图点击button,div关联事件不触发,阻止了冒泡
<div id="app"> <!--阻止冒泡:点击div内部按钮时,不会冒泡到div相关的事件--> <div class="box" @click="boxClick"> <button type="button" @click.stop="btnClick">按钮</button> </div> <!--阻止默认事件:阻止表单提交,不阻止的话,点击submit表单会直接提交到action--> <form action="http://www.baidu.com/"> <input type="submit" value="提交" @click.prevent="doSubmit"/> </form> <a href="http://www.baidu.com" @click.prevent="doSubmit">百度</a> <!--响应一次事件--> <button type="button" @click.once="btnClick">只有第一次点击生效</button> <!--键盘事件修饰符:获取用户按键信息 .keycode .enter .tab .delete .esc .space .up .down .left .right--> <input type="text" @keyup="getMsg" /> <input type="text" @keyup.enter="getMsg" /> <!--回车时事件才响应--> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { }, methods: { boxClick(){ console.log("点击了盒子") }, btnClick(event){ // event.stopPropagation(); <!--阻止冒泡原始写法--> console.log("点击了按钮") }, doSubmit(event){ // event.preventDefault(); 阻止默认事件 console.log("表单提交") }, getMsg(event){ console.log(event); }, } }) </script>
<div id="app"> <p>宝贝·老婆</p> <!--常规写法,不应该在这里写太多的逻辑代码,容易与vue对象产生耦合--> <p>{{ firstName + '·' + lastName}}</p> <!--函数--> <p>{{ getFullName() }}</p> <!--除事件调用函数之外不能省略小括号--> <!--计算属性-->d <p>{{ fullName }}</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { firstName:'宝贝', lastName:'老婆', }, // 计算属性 computed:{ // 本质上还是属性,写法如函数,命名如属性 fullName(){ return this.firstName + '·' + this.lastName; } }, methods: { getFullName(){ return this.firstName + '·' + this.lastName; } } }) </script>
计算属性处理数组,用到 for(let member of this.members){} 循环for
<div id="app"> <p>{{ members[0].score + members[1].score + members[2].score}}</p> <!--使用计算属性--> <p>{{ totalScore }}</p> <!--计算属性本质是一个属性,不能写totalScore() --> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { members:[ {name:'张三',score:89}, {name:'李四',score:92}, {name:'王五',score:91} ] }, computed:{ totalScore(){ let total = 0; for(let member of this.members){ total += member.score; } return total; } }, <!--vue对象中只要有语法错误,mustache就会直接显示{{}}原始格式--> methods: { } }) </script>
<div id="app"> <div v-if="flag">和宝贝去深圳</div> <div v-else="flag">和宝贝去北京</div> <p>===============</p> <div v-show="flag">和宝贝去北京</div> <div v-show="!flag">和宝贝去天津</div> <br> <button type="button" @click="flag=!flag">切换</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { flag:true }, methods: { } }) </script>
<div id="app"> <!-- v-if切换登录方式,会把原来输入的内容清空,因为原理是div的销毁和创建 --> <!-- <div v-if="loginType==='phone'"> === 三个等号表示恒等于,类型相同值相同 手机:<input type="text" placeholder="请输入手机号码"/><br> 密码:<input type="password" placeholder="请输入密码"/><br> </div> <div v-else> 邮箱:<input type="text" placeholder="请输入邮箱"/><br> 密码:<input type="password" placeholder="请输入密码"/><br> </div> --> <!-- v-show切换登录方式,会记录上一次填入的内容 --> <div v-show="loginType ==='phone'"> 手机:<input type="text" placeholder="请输入手机号码"/><br> 密码:<input type="password" placeholder="请输入密码"/><br> </div> <div v-show="loginType === 'email'"> 邮箱:<input type="text" placeholder="请输入邮箱"/><br> 密码:<input type="password" placeholder="请输入密码"/><br> </div> <button @click="change">切换登录方式</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { loginType:'phone' }, methods: { change(){ this.loginType === 'phone' ? this.loginType = 'email' : this.loginType = 'phone' } } }) </script>
v-for=“e in elements” 或者v-for="(e,index) in elements"
v-if 的优先级大于 v-for,一般不要在同一个标签中,同时使用两者
<div id="app"> <ul> <li v-for="e in aicheng">{{ e }}</li> </ul> <ul> <li v-for="(e,index) in aicheng">{{ index }}:{{ e }}</li> </ul> <ul> <li v-for="e in date">{{ e.begin }}-{{ e.location }}-{{ e.love }}</li> </ul> <ul> <li v-for="item in baby">{{ item }}</li> <!--得到的是value--> <p>===============</p> <li v-for="(item,key) in baby">{{ key }}:{{ item }}</li> <p>===============</p> <li v-for="(item,key,index) in baby">{{ index }}-{{ key }}:{{ item }}</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { //数组 aicheng:['宝贝','老婆','宝儿','媳妇儿'], //json数组 date:[ {begin:'1.5',location:'邯郸',love:'爱你'}, {begin:'4.22',location:'武汉',love:'永远爱你'}, {begin:'7.2',location:'济南',love:'这辈子就是你了'}, ], //对象 baby:{ name:'宝贝', age:18, love:'我可爱的女朋友', } }) </script>
<head> <meta charset="utf-8"> <title>Vue基础</title> <style type="text/css"> ul li{ list-style: none; line-height: 40px; } body{ text-align: center; } </style> </head> <body> <div id="app"> <h3>搜索</h3> <label><input type="text" placeholder="请输入关键词" v-model="searchStr"/></label> <h3>排序</h3> <button type="button" @click="setOrderType(2)">年龄升序</button> <button type="button" @click="setOrderType(1)">年龄降序</button> <button type="button" @click="setOrderType(0)">还原</button> <div> <ul> <li v-for="(p,index) in filterPerson">{{ index + 1 }}-{{ p.name }}-{{ p.age }}</li> </ul> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { person:[ {name:'张三',age:'19'}, {name:'王五',age:'22'}, {name:'张六',age:'20'} ], //管理输入框 searchStr:'', //flag 默认0,升序1,降序2 orderType:0 }, //计算属性,得到筛选后的展示数组 computed:{ filterPerson(){ //1.取出相关属性 const{person,searchStr,orderType} = this; //2.定义过滤数组 let arr = [...person]; //深拷贝 //3.根据条件过滤 if(searchStr.trim()){ arr = person.filter((p)=>{ return p.name.indexOf(searchStr) != -1; }) } //4.排序 if(orderType){ arr.sort((p1,p2)=>{ //sort底层是冒泡排序 //升序 if(orderType === 2){ return p1.age - p2.age; //表示从p1到p2升序 //降序 }else{ return p2.age - p1.age; } }) } //5.返回过滤后的数组 return arr; } }, methods:{ setOrderType(orderType){ this.orderType = orderType; } } }) </script> </body>
v-model绑定的元素值和输入框同步
<div id="app"> <!-- <input type="text" :value="msg" @input="valueChange"/> --> <input type="text" :value="msg" @input="msg=$event.target.value"/> <h1>{{ msg }}</h1> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { msg:'我爱宝贝' }, methods:{ valueChange(event){ console.log("---------------") this.msg = event.target.value; } } }) </script>
v-model 结合单选
<div id="app"> <label><input name="sex" type="radio" value="男" v-model="sex"/>男</label> <label><input name="sex" type="radio" value="女" v-model="sex"/>女</label> <p>==========</p> <h2>选择的性别是:{{ sex }}</h2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { sex:'' } }) </script>
v-model 结合多选
<div id="app"> <!-- 单个选项 --> <label> <input type="checkbox" v-model="isAgree"/>同意永远爱宝贝协议 </label> <h2>是否同意协议:{{ isAgree ? '同意' : '不同意' }}</h2> <button type="button" :disabled="!isAgree">注册</button> <p>=================</p> <!-- 多个选项 --> <label>兴趣爱好:</label> <input type="checkbox" value="宝贝" v-model="hobbies"/>宝贝 <input type="checkbox" value="老婆" v-model="hobbies"/>老婆 <input type="checkbox" value="小韩" v-model="hobbies"/>小韩 <h2>用户兴趣爱好:{{ hobbies }}</h2> <p>==================</p> <!-- 值绑定 --> <label v-for="like in likes" :for="like"> <!-- :for 关联ID--> <!-- 循环的是like,绑定的是love ,选中什么,在love中存入什么 --> <input type="checkbox" :value="like" :id="like" v-model="love"/>{{ like }} </label> <h2>用户兴趣爱好:{{ love }}</h2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { isAgree:'', hobbies:[], likes:["宝贝","老婆","小韩"], love:[] } }) </script>
为了给vue一个提示,方便它追踪每个节点的身份,从而重用和重新排序现有的元素,需要为每一项提供一个唯一的key
不要使用对象或者数组之类的非基本类型的值作为v-for的key,请使用字符串或数值类型的值
<div v-for="item in items" :key="item.id"> </div>
略