一、模版语法
1.1 插值
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。vue将模板编译成虚拟dom,结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
html模板语法: 这是一种基于字符串的模板技术,以字符串和数据为输入,通过用正则表达式将占位符替换为所需数据的方式,构建出完整的 HTML 字符串。
1.1.1 文本
直接使用{{xxx}}的形式,标签将会被替换成为数据对象(data)上xxx属性值,当绑定的数据对象上的xxx属性值发生变化时,插值处的值也会发生变化(双向绑定)
<div id="app">
{{msg}}
</div>
1.1.2 html解析
如果要输出html格式的数据,需要使用v-html指令。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>html解析</title> <!-- 1.导入工具 --> <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> </head> <body> <!-- 2.定义边界 --> <div id="app"> <div v-html="htmlstr"></div> </div> <!-- 3.构建vue实例并绑定边界 --> <script> new Vue({ el: "#app", data() { return { htmlstr: '<h3 style="color:red;">这是一个html片段</h3>' } } }) </script> </body> </html>
1.1.3 属性
HTML属性中的值应使用v-bind指令。类型与jQuery中的$("#xxx").attr(Name,Val)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>html解析</title> <!-- 1.导入工具 --> <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> .red{ font-size: 30px; color: red; } </style> </head> <body> <!-- 2.定义边界 --> <div id="app"> <p v-bind:class="hontColor">哈哈</p> </div> <!-- 3.构建vue实例并绑定边界 --> <script> new Vue({ el: "#app", data() { return { hontColor:"red" } } }) </script> </body> </html>
1.1.4 表达式
Vue提供了完全的JavaScript表达式支持:
- {{str.substr(0,3)}}
- {{ number + 1 }}
- {{ ok ? 'YES' : 'NO' }}
- <li v-bind:id="'list-' + id">我的Id是js动态生成的</li>
这些就不一一演示了,大家自己去玩
1.2.3 动态参数
注意:在动态参数中,作为参数的变量名(如:attrname)要全部小写,否则无效 !!
<!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> </head> <body> <!-- 定义边界 --> <div id="app"> <p>动态参数</p> <input v-model="evname" /> <button v-on:[evname]="handle">动态参数</button> </div> </body> <script type="text/javascript"> new Vue({ el: '#app', data() { return { evname:'dblclick' } }, methods: { handle() { alert("触发事件"); } } }) </script> </html>
Vue为v-bind和v-on这两个最常用的指令,提供了特定简写
指令 | 简写 | 示例 |
v-bind:xxx | :xxx | v-bind:href 简写为 :href |
v-on:xxx | @xxx | v-on:click 简写为 @click |
二、过滤器
vue允许自定义过滤器,一般用于常见的文本格式化,过滤器可用的两个地方:双花括号插值与v-bind表达式,过滤器应该被添加在js表达式的尾部,使用管道运算符 " | "
2.1 局部过滤器
<!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> </head> <body> <!-- 定义边界 --> <div id="app"> {{msg}}<br /> {{msg|single}}<br /> {{msg|param(9,10)}} </div> <script type="text/javascript"> // 绑定边界 ES6具体体现 new Vue({ el: '#app', data() { return { msg: "bui快离开~bu坤快离开~" }; }, filters: { 'single': function(val) { return val.substring(2, 3); }, 'param': function(val, start, end) { return val.substring(start, end); } } }) </script> </body> </html>
2.2 全局过滤器
时间转换案例:
//给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(); };
拷入date.js(日期格式化)放入项目js目录中,在页面中引入。
定义全局过滤器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>过滤器</title> <script src="data.js"></script> <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> </head> <body> <!-- 定义边界 --> <div id="app"> <p>{{date | fmtDate}}</p> 无过滤器:<br /> {{date}} </div> <script type="text/javascript"> // 全局过滤器 Vue.filter('fmtDate', function(value) { return fmtDate(value, 'yyyy年MM月dd日') }); // 绑定边界 ES6具体体现 new Vue({ el: '#app', data() { return { date: new Date() }; } }) </script> </body> </html>
三、监听器
监听属性 watch,我们可以通过 watch 来响应数据的变化
语法:watch:{}
示例: 米和厘米的单位换算
<!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> </head> <body> <!-- 定义边界 --> <div id="app"> <p>监听属性</p> 米:<input v-model="m" /> 厘米:<input v-model="cm" /> </div> </body> <script type="text/javascript"> // 绑定边界 ES6具体体现 new Vue({ el: '#app', data() { return { m: 2, cm: 200 }; }, watch: { m: function(v) { this.cm = parseInt(v) * 100; }, cm: function(v) { this.m = parseInt(v) / 100; } } }) </script> </html>
四、完整购物车案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ShopCar</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script> </head> <body> <h1 style="text-align: center;">东天帝商城</h1> <hr> <br> <br> <table id="ShopCarTable" class="table table-light" style="border-radius: 50%; width: 80%; margin: auto;"> <tr class="table-info"> <td> <!-- 全选框 --> <input type="checkbox" v-model="checkAllStatus" @change="toggleCheckAll"> </td> <td>商品名称</td> <td>商品价格</td> <td>商品数量</td> <td>商品总价</td> </tr> <!-- 循环渲染商品列表 --> <tr v-for="(good, index) in goods" :key="index"> <td> <!-- 商品选择框 --> <input type="checkbox" v-model="good.isChecked" @change="update"> </td> <td>{{ good.name }}</td> <td>{{ good.price }}</td> <td> <!-- 商品数量输入框 --> <input type="number" v-model="good.number" @input="sum"> </td> <td>{{ good.number * good.price }}</td> </tr> <tr> <td colspan="5" style="text-align: right;"> <!-- 总价 --> 总价:{{ totalPrice }} </td> </tr> </table> <script> new Vue({ el: "#ShopCarTable", data() { return { goods: [ { name: '皮带', price: 10, isChecked: false, number: 1 }, // 商品对象,包含名称、价格、选中状态和数量 { name: '皮鞭', price: 20, isChecked: false, number: 1 }, { name: '皮椅', price: 30, isChecked: false, number: 1 } ], checkAllStatus: false, // 全选状态,默认为未选中 totalPrice: 0 // 总价,默认为0 } }, methods: { toggleCheckAll() { // 切换全选状态以及更新商品列表中每个商品的选中状态 this.goods.forEach(item => { item.isChecked = this.checkAllStatus; }); this.sum(); // 更新总价 }, update() { // 更新全选状态 // every方法会遍历goods数组中的每个元素,对于每个元素,会执行回调函数。回调函数中的item表示当前遍历到的元素。如果所有元素都满足回调函数中的条件,即item.isChecked为true,则every方法的返回值为true,否则返回值为false。 // 这里的目的是检查是否所有的商品都被选中(isChecked为true),如果是,则将checkAllStatus设置为true,表示全选选中;否则,将其设置为false,表示全选未选中。 this.checkAllStatus = this.goods.every(item => item.isChecked); // 接下来,调用sum方法来更新总价: this.sum(); // 更新总价 }, sum() { // 计算总价 //reduce方法接受两个参数,一个是回调函数,另一个是初始值。回调函数中的第一个参数 total 是累加器,表示当前的累加结果,初始值为0。第二个参数 item 是遍历时的当前元素。 // 在每次遍历时,如果当前商品 item 被选中(isChecked 为 true),则将当前商品的价格 price 乘以数量 number,然后加到累加器 total 中。如果当前商品未被选中,则直接返回累加器 total,继续下一次遍历。 // 最后,reduce方法返回最终的累加结果,即所有选中商品的总价,并将其赋值给 this.totalPrice 属性。 this.totalPrice = this.goods.reduce((total, item) => { if (item.isChecked) { return total + item.price * item.number; // 若商品被选中,则计算该商品的总价并加入总价中 } else { return total; } }, 0); } } }); </script> </body> </html>
五、计算属性--简易购物车(无复选框)
计算属性可用于快速计算视图(View)中显示的属性。这些计算将被缓存,并且只在需要时更新。
使用场景:当一个属性需要复杂的逻辑运算之后才能获取其值,可以使用计算属性,在一个计算属性中可以完成各种复杂的逻辑,包括运算,方法调用等,只要最终返回一个结果就可以了
语法:computed:{}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ShopCar</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script> </head> <body> <h1 style="text-align: center;">东天帝商城</h1> <hr> <br> <br> <table id="ShopCar" class="table table-light" style="border-radius: 50%; width: 80%; margin: auto;" > <tr class="table-info"> <td>商品名称</td> <td>商品价格</td> <td>商品数量</td> <td>商品总价</td> </tr> <tr> <td>男人得装</td> <td>{{man}}</td> <td> <input type="number" v-model="man2"> </td> <td>{{man1}}</td> </tr> <tr> <td>和天下</td> <td>{{smoke}}</td> <td> <input type="number" v-model="smoke2"> </td> <td>{{smoke1}}</td> </tr> <tr> <td>奥特曼变身手环</td> <td>{{Ultraman}}</td> <td> <input type="number" v-model="Ultraman2"> </td> <td>{{Ultraman1}}</td> </tr> <tr> <td colspan="3" style="text-align: right;">总价:</td> <td>{{sum}}</td> </tr> </table> <script> new Vue({ // 挂载组件 el:"#ShopCar", // 回显数据 data(){ return { man:79, smoke:100, Ultraman:10000, man2:1, smoke2:1, Ultraman2:1 } }, // 计算函数 computed:{ man1(){ return this.man * this.man2 }, smoke1(){ return this.smoke * this.smoke2 }, Ultraman1(){ return this.Ultraman * this.Ultraman2 }, sum(){ return this.man1+this.smoke1+this.Ultraman1 } } }) </script> </body> </html>