1.插值
插值:用双大括号{{}}将数据绑定到模板中,实现简单的数据渲染。例如:
{{message}}
,其中message是一个变量。
1.1.3 属性
HTML属性中的值应使用v-bind指令
1.1.4 表达式
1.1.1 文本
{{msg}
1.1.2 html
使用v-html
Vue提供了完全的JavaScript表达式支持
效果如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>入门</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <style type="text/css"> .f30{ font-size: 30px; } </style> </head> <body> <div id="app"> {{msg}} <p>html解析</p> {{msg2}} <b :class="msg3" v-html="msg2"></b> {{msg4+1}} {{sb.substring(3,8)}} <input v-model="ok"> {{ok==1? "你好我是雪豹":"妈妈每天都给我抽点支烟,以及听雪"}} </div> <script type="text/javascript"> new Vue({ el:"#app", data(){ return {msg:'hellow 你好 vue', msg2:'<span style="color:yellow">hello 你好vue </span>', msg3:'f30', msg4:5, ok:1, sb:'邓郑伟学坤坤跳舞' } } }) </script> </body> </html>
2.指令:
用v-开头的特殊属性,可以实现DOM操作、条件渲染、循环、事件绑定等功能。例如:
{{message}}
,其中v-if是条件渲染的指令。
核心指令
(v-if|v-else|v-else-if)/v-show/v-for/v-bind/v-on/v-model
v-if|v-else|v-else-if:根据其后表达式的bool值进行判断是否渲染该元素
他们只能是兄弟元素
v-else-if上一个兄弟元素必须是v-if
v-else上一个兄弟元素必须是v-if或者是v-else-if
v-show:与v-if类似,只是会渲染其身后表达式为false的元素,而且会给这样的元素添加css代码:style="display:none"
v-for:类似JS的遍历,
遍历数组: v-for="item in items", items是数组,item为数组中的数组元素
遍历对象: v-for="(value,key,index) in stu", value属性值,key属性名,index下标
v-bind
v-on
v-model:用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值
v-for/v-model一起绑定[多选]复选框和单选框
使用:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <title>指令</title> </head> <body> <div id="app"> <input v-model="score"> <b v-if="score < 60 ">不及格</b> <b v-else-if="score >= 60 && score <70 ">及格</b> <b v-else-if="score >= 70 && score <80 ">中等</b> <b v-else-if="score >= 80 && score <90 ">良好</b> <b v-else="score >=90 && score <100>">优秀</b> <b>{{array}}</b> <i v-for="a in array">{{a}}||</i> <i v-for="u in User">{{u.name}}喜欢{{u.hobby}}今年{{u.age}}</i> <br /> <select> <option v-for="h in hobby" :value="h.id"> {{h.name}} </option></select> <br /> <div v-for="h in hobby"><input type="checkbox" name="hpbby" :value="h.id">{{h.name}}</div> <p>v-show</p> <div v-show="score>90">v-show-上优秀学员名单</div> <div v-if="score>90">v-if-上优秀学员名单</div> </div> <script type="text/javascript"> new Vue({ el:'#app', data(){ return {score:60, array:[1,2,3,4], User:[{name:'小威',hobby:'玩棒子',age:18}, {name:'小威',hobby:'玩棒子',age:18}, {name:'小威',hobby:'玩棒子',age:18}], hobby:[{id:1,name:'洗脚'}, {id:2,name:'保健'}, {id:3,name:'按摩'}, {id:4,name:'spa'}] } } }) </script> </body> </html>
效果:
3.动态参数
动态参数:除了用固定的指令名称,还可以使用动态参数来动态绑定数据。例如:{{ message }},其中v-bind动态绑定href属性的值。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <title>指令</title> </head> <body> <div id="app"> <input v-model="score"> <b v-if="score < 60 ">不及格</b> <b v-else-if="score >= 60 && score <70 ">及格</b> <b v-else-if="score >= 70 && score <80 ">中等</b> <b v-else-if="score >= 80 && score <90 ">良好</b> <b v-else="score >=90 && score <100>">优秀</b> <b>{{array}}</b> <i v-for="a in array">{{a}}||</i> <i v-for="u in User">{{u.name}}喜欢{{u.hobby}}今年{{u.age}}</i> <br /> <select> <option v-for="h in hobby" :value="h.id"> {{h.name}} </option></select> <br /> <div v-for="h in hobby"><input type="checkbox" name="hpbby" :value="h.id">{{h.name}}</div> <p>v-show</p> <div v-show="score>90">v-show-上优秀学员名单</div> <div v-if="score>90">v-if-上优秀学员名单</div> <p>动态参数</p> <input v-model="evname"/> <button v-on:[evname]="test">点我</button> </div> <script type="text/javascript"> new Vue({ el:'#app', data(){ return {score:60, array:[1,2,3,4], User:[{name:'小威',hobby:'玩棒子',age:18}, {name:'小威',hobby:'玩棒子',age:18}, {name:'小威',hobby:'玩棒子',age:18}], hobby:[{id:1,name:'洗脚'}, {id:2,name:'保健'}, {id:3,name:'按摩'}, {id:4,name:'spa'}], evname:'click' }; } ,methods:{ test(){ alert("点我试试") } } }) </script> </body> </html>
4.过滤器
vue允许自定义过滤器,一般用于常见的文本格式化,过滤器可用的两个地方:双花括号插值与v-bind表达式,过滤器应该被添加在js表达式的尾部,使用管道运算符 " | "
局部过滤器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <title>过滤器</title> </head> <body> <div id='app'> <p>局部过滤器</p> {{msg}} <p>局部过滤器串行使用</p> {{msg | filterA | filterB}} <p>局部过滤器传参</p> {{msg | filterC(2,5)}} </div> <script type="text/javascript"> new Vue({ el:'#app', filters:{ 'filterA':function(v){ return v.substring(0,5); }, 'filterB':function(v){ return v.substring(2,5); }, 'filterC':function(v,begin,end){ return v.substring(begin,end); } }, data(){ return { msg:'你好 饿了么' } } }) </script> </body> </html>
全局过滤器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="date.js"></script> <title>过滤器</title> </head> <body> <div id='app'> <p>局部过滤器</p> {{msg}} <p>局部过滤器串行使用</p> {{msg | filterA | filterB}} <p>局部过滤器传参</p> {{msg | filterC(2,5)}} <p>全局过滤器</p> 没有过滤器的结果: {{time}} 有过滤器的结果:{{time|fmtDate}} <script src="js/date.js"></script> </div> <script type="text/javascript"> Vue.filter('fmtDate', function(value) { return fmtDate(value, 'yyyy年MM月dd日') }); new Vue({ el:'#app', filters:{ 'filterA':function(v){ return v.substring(0,5); }, 'filterB':function(v){ return v.substring(2,5); }, 'filterC':function(v,begin,end){ return v.substring(begin,end); } }, data(){ return { msg:'你好 饿了么', time:new Date() } } }) </script> </body> </html>
data.js
//给Date类添加了一个新的实例方法format Date.prototype.format = function (fmt) { //debugger; var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; }; function fmtDate(date, pattern) { var ts = date.getTime(); var d = new Date(ts).format("yyyy-MM-dd hh:mm:ss"); if (pattern) { d = new Date(ts).format(pattern); } return d.toLocaleString(); };
结果:
5.计算属性监听属性
计算属性
<!DOCTYPE html> <html> <head> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <meta charset="utf-8"> <title>计算属性监听属性</title> </head> <body> <div id="app"> <p>计算属性</p> 单价:<input v-model="price"> 数量:<input v-model="num"> 小计:{{count}} </div> <script type="text/javascript"> new Vue({ el:'#app', data(){ return { price:79, num:1 }; }, computed:{ count:function(){ return this.price*this.num } } }) </script> </body> </html>
效果:
改为2
计算属性特点:一方影响另一方(单向)
监听属性:
<!DOCTYPE html> <html> <head> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <meta charset="utf-8"> <title>计算属性监听属性</title> </head> <body> <div id="app"> <p>计算属性</p> 单价:<input v-model="price"> 数量:<input v-model="num"> 小计:{{count}} <p>监听属性</p> 千米:<input v-model="km" /> 米:<input v-model="m"/> </div> <script type="text/javascript"> new Vue({ el:'#app', data(){ return { price:79, num:1, m:1000, km:1 }; }, computed:{ count:function(){ return this.price*this.num } }, watch:{ km:function(v){ this.m=parseInt(v) * 1000; }, m:function(v){ this.km=parseInt(v) / 1000; } } }) </script> </body> </html>
效果:
监听属性特点:两方互相影响(双向)
实战案例:
购物车:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>购物车</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <style> .container { width: 600px; margin: 0 auto; } table { border-collapse: collapse; width: 100%; } table td { border: 1px solid #ddd; padding: 10px; text-align: center; } .input-wrapper { display: flex; justify-content: center; align-items: center; } button { padding: 5px 10px; background-color: #eee; border: none; cursor: pointer; } </style> </head> <body> <div id="app" class="container"> <p>购物车</p> <table> <thead> <tr> <th>物品</th> <th>单价</th> <th>数量</th> <th>小计</th> </tr> </thead> <tbody> <tr v-for="(item, index) in items" :key="index"> <td>{{ item.name }}</td> <td>{{ item.price }}</td> <td class="input-wrapper"> <button @click="decrement(index)">-</button> <input v-model="item.quantity" /> <button @click="increment(index)">+</button> </td> <td>{{ item.price * item.quantity }}</td> </tr> <tr> <td colspan="3">总价</td> <td>{{ total }}</td> </tr> </tbody> </table> </div> <script type="text/javascript"> new Vue({ el: '#app', data() { return { items: [ { name: '帽子', price: 10, quantity: 1 }, { name: '衣服', price: 30, quantity: 1 }, { name: '裤子', price: 20, quantity: 1 }, { name: '肾宝片', price: 200, quantity: 1 }, { name: '羊腰子', price: 20, quantity: 1 }, ], }; }, methods: { increment(index) { this.items[index].quantity++; }, decrement(index) { if (this.items[index].quantity > 1) { this.items[index].quantity--; } }, }, computed: { total() { return this.items.reduce((sum, item) => sum + (item.price * item.quantity), 0); }, }, }); </script> </body> </html>
效果: