一、模版语法
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="xw">
{{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="xw"> <div v-html="htmlstr"></div> </div> <!-- 3.构建vue实例并绑定边界 --> <script> new Vue({ el: "#xw", data() { return { htmlstr: '<h3 style="color:blue;">这是一个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> .blueClass{ font-size: 30px; color: skyblue; } </style> </head> <body> <!-- 2.定义边界 --> <div id="xw"> <p v-bind:class="hontColor">哈哈</p> </div> <!-- 3.构建vue实例并绑定边界 --> <script> new Vue({ el: "#xw", data() { return { hontColor:"blueClass", } } }) </script> </body> </html>
也可以这样写:
//在html使用v-bind:style指令设置样式 <p v-bind:style="color">哈哈</p>
data() { return { //定义一个属性,其值为所需样式 color:"color: yellowgreen;" } }
1.1.4 表达式
Vue提供了完全的JavaScript表达式支持:
- {{str.substr(0,3)}}
- {{ number + 1 }}
- {{ ok ? 'YES' : 'NO' }}
- <li v-bind:id="'list-' + id">我的Id是js动态生成的</li>
示例1:字符截取
<!-- 在html中加入元素,定义表达式 --> <p>{{str.substring(5,9)}}</p>
data() { return { str: '大家都叫我king' } }
示例二:很简单就不一一演示了
<p>数字:{{number+1}}</p> <p>{{ok ? 'yes' : 'no'}}</p> <span :id="'users_id_'+id">小威</span>
new Vue({ el: "#xw", data() { return { number: 99, ok: false, id: 66 } } })
1.2 指令
1.2.1 核心指令
v-if|v-else|v-else-if :根据其后表达式的bool值进行判断是否渲染该元素
v-show:与v-if类似,只是会渲染其身后表达式为false的元素,而且会给这样的元素添加css代码:style="display:none"
v-for:类似JS的遍历
v-bind:在上面已用到,添加属性或元素
v-on:v-on:(也可以用@替代),在上篇已讲述过,用来调用函数。
v-model:用来自动更新绑定的元素的值
示例1:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>核心指令</title> <script src="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> 分数:<input v-model="score" /> <div v-if="score>80">优秀</div> <div v-else-if="score>60">良好</div> <div v-else="score<60">还需努力</div> </div> </body> <script type="text/javascript"> new Vue({ el: '#xw', data() { return { score: 60 } } }) </script> </html>
示例二:
<div v-show="score==90">v-show-上优秀学员名单</div>
示例3:
结合v-model实现下拉框和复选框
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>核心指令</title> <script src="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> <p>v-for</p> <select v-model="hobbySelected"> <option v-for="h in hobby" :value="h.id">{{h.name}}</option> </select> <div v-for="h in hobby"> <input :value="h.id" type="checkbox" />{{h.name}} </div> </div> </body> <script type="text/javascript"> new Vue({ el: '#xw', data() { return { hobby: [{ id: "1", name: "beautifulgirl" }, { id: "2", name: "按摩" }, { id: "3", name: "洗jio" } ], hobbySelected: 3 }; } }) </script> </html>
示例4:
<!--参数:href--> <div> <a v-bind:href="url">baidu</a> </div> <!-- 参数:动态参数. attname需要在data中定义, 注意:attname要全部小写!! --> <div> <a v-bind:[attrname]="url">baidu</a> <button v-on:[evname]="clickme">点我看看</button> </div>
1.2.3 动态参数
注意:在动态参数中,作为参数的变量名(如:attrname)要全部小写,否则无效 !!
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>动态参数</title> <script src="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> <p>动态参数</p> <input v-model="evname" /> <button v-on:[evname]="handle">动态参数</button> </div> </body> <script type="text/javascript"> new Vue({ el: '#xw', 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="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> {{msg}}<br /> {{msg|single}}<br /> {{msg|param(2,3)}} </div> <script type="text/javascript"> // 绑定边界 ES6具体体现 new Vue({ el: '#xw', data() { return { msg: "bug快离开~bug快离开~" }; }, filters: { 'single': function(val) { return val.substring(2, 3); }, 'param': function(val, start, end) { return val.substring(start, end); } } }) </script> </body> </html>
注1:过滤器函数接受表达式的值作为第一个参数
注2:过滤器可以串联
{{ message | filterA | filterB }}
注3:过滤器是JavaScript函数,因此可以接受参数:
{{ message | filterA('arg1', arg2) }}
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="js/date.js"></script> <script src="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> <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: '#xw', data() { return { date: new Date() }; } }) </script> </body> </html>
三、计算属性
计算属性可用于快速计算视图(View)中显示的属性。这些计算将被缓存,并且只在需要时更新。
使用场景:当一个属性需要复杂的逻辑运算之后才能获取其值,可以使用计算属性,在一个计算属性中可以完成各种复杂的逻辑,包括运算,方法调用等,只要最终返回一个结果就可以了
语法:computed:{}
购物车案例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>计算属性</title> <script src="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> <p>计算属性</p> <table border="1" style="width: 600px;height: 300px;"> <tr> <td>物品</td> <td>单价</td> <td> 数量 </td> <td> 小计 </td> </tr> <tr> <td>帽子</td> <td>{{maoziDanjia}}</td> <td> <input v-model="maozi" /> </td> <td> {{maoziTotal}} </td> </tr> <tr> <td>衣服</td> <td>{{yifuDanjia}}</td> <td> <input v-model="yifu" /> </td> <td> {{yifuTotal}} </td> </tr> <tr> <td>裤子</td> <td>{{kuziDanjia}}</td> <td> <input v-model="kuzi" /> </td> <td> {{kuziTotal}} </td> </tr> <tr> <td>总价</td> <td colspan="3">{{total}}</td> </tr> </table> </div> </body> <script type="text/javascript"> // 绑定边界 ES6具体体现 new Vue({ el: '#xw', data() { //定义所需属性值 return { maoziDanjia: 10, yifuDanjia: 30, kuziDanjia: 20, maozi: 1, yifu: 1, kuzi: 1, km: 2, m: 2000 }; }, computed: { maoziTotal() { return this.maoziDanjia * this.maozi; }, yifuTotal() { return this.yifuDanjia * this.yifu; }, kuziTotal() { return this.kuziDanjia * this.kuzi; }, total() { return this.maoziTotal + this.yifuTotal + this.kuziTotal; } } }) </script> </html>
四、监听器
监听属性 watch,我们可以通过 watch 来响应数据的变化
语法:watch:{}
示例: 米和厘米的单位换算
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>计算属性</title> <script src="js/vue&jquery.js"></script> </head> <body> <!-- 定义边界 --> <div id="xw"> <p>监听属性</p> 米:<input v-model="m" /> 厘米:<input v-model="cm" /> </div> </body> <script type="text/javascript"> // 绑定边界 ES6具体体现 new Vue({ el: '#xw', data() { return { m: 2, cm: 200 }; }, watch: { // v指的是m变量 m: function(v) { this.cm = parseInt(v) * 100; }, // v指的是km变量 cm: function(v) { this.m = parseInt(v) / 100; } } }) </script> </html>
五、排座案例
<!DOCTYPE html> <html> <head> <title>排座</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h2>排座</h2> <input type="text" v-model="seatInput1"> <input type="text" v-model="seatInput2"> <input type="text" v-model="seatInput3"> <hr> <h3>用户:</h3> <ul> <!-- 遍历过滤器传来的值 --> <li v-for="user in filteredUsers" :key="user.id">{{ user.name }}</li> </ul> <hr> </div> <script> new Vue({ el: '#app', data: { seatInput1: '', seatInput2: '', seatInput3: '', users: [{ id: 1, name: '老王' }, { id: 2, name: '老六' }, { id: 3, name: '老八' }, { id: 4, name: '老聂' }, { id: 5, name: '老五' } ] }, /* 定义一个filteredUsers计算属性 */ computed: { /* 使用filter方法来过滤users数组中的元素。filter方法接受一个回调函数作为参数,该回调函数会对数组中的每个元素进行判断,并返回一个新的数组,其中包含满足条件的元素。 */ filteredUsers() { return this.users.filter( /* 使用=>箭头函数的语法来定义一个匿名函数。这个匿名函数接受一个参数user,表示users数组中的每个元素。 */ user => { /* 使用逻辑运算符&&来判断user.name是否不等于seatInput1、seatInput2和seatInput3的值。如果满足这个条件,说明user.name不等于任何一个输入框的值,那么这个元素就会被保留在过滤后的数组中。 */ return user.name !== this.seatInput1 && user.name !== this.seatInput2 && user.name !== this.seatInput3 }); } } }); </script> </body> </html>
小结:计算属性和监听属性的区别
计算属性:是一种依赖于其他属性计算得出的属性。它的值是根据其依赖的属性动态计算而来的,并且会进行缓存,只有在依赖的属性发生变化时才会重新计算。计算属性适用于需要根据其他属性进行复杂计算或处理的场景。通过使用计算属性,可以将复杂的逻辑封装起来,使代码更加清晰和可维护。
监听属性:是一种用于监听指定属性变化并执行相应操作的属性。当监听的属性发生变化时,可以执行指定的回调函数来响应变化。监听属性适用于需要在属性变化时执行异步或开销较大的操作的场景。通过使用监听属性,可以实时监测属性的变化并执行相应的操作,例如发送网络请求或执行复杂的计算。
计算属性适用于根据其他属性进行计算得出结果的场景,而监听属性适用于需要实时监测属性变化并执行相应操作的场景。两者的区别在于计算属性是根据其他属性进行计算得出结果,而监听属性是在属性变化时执行相应操作。