一、VUE概述
1. Vue.js 是什么?
- Vue.js 是简单小巧,渐进式,功能强大的技术栈
2. Vue.js 的模式
- MVVM模式,视图层和数据层的双向绑定,让我们无需再去关心DOM操作的事情,更过的精力放在数据和业务逻辑上去
3. Vue.js 环境搭建
- script 引入 src(如:
<script src="../lib/vue.js" type="text/javascript"></script>
) - vue 脚手架工具 vue-cli 搭建
4.Vue.js 的优点
- 低耦合。视图(View)可以独立于 Model 变化和修改,一个 ViewModel 可以绑定到不同的 "View" 上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候 View 也可以不变。
- 可重用性。可以把一些视图逻辑放在一个 ViewModel 里面,让很多 view 重用这段视图逻辑。
- 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
- 可测试。界面素来是比较难于测试的,而现在测试可以针对 ViewModel 来写。
- 易用、灵活、高效。
二、VUE的指令学习
1.text+html+cloak+插值表达式学习
指令: 插值表达式: 语法:{{要插入的值}},此时相当于占位符,到时候{{关键字}}会被替换成 Model中的数据 bug点: 当网速较慢时,Vue初始化未完成时,插值表达式不能被解析,会直接显示 出来,加载完毕之后又会被替换成真实结果,造成闪烁(Vue的加载代码写在 HTML元素之后时会出现该bug) v-cloak指令: 语法:把它当作HTML元素的一个属性使用 示例: <p v-cloak>{{msg1}}</p> 特点: 当Vue加载完毕后,v-cloak属性会自动消失 使用: 添加如下CSS样式:让所有带v-cloak属性的元素隐藏,Vue加载完成后显示 实现,解决插值表达式闪烁的问题 [v-cloak]{ display: none; } v-text: 语法:<p v-text="msg1"></p> 作用:和插值表达式一样,用于给HTML元素添加文本 区别: 1.v-text不会存在闪烁问题 2.v-text会将Model中的数据完全替换到HTML元素中(覆盖) 3.插值表达式只会将Model中的数据替换到插值表达式中(占位符内容的替换) 相同点: 1.插值表达式和v-text都可以给HTML元素显示文本 2.插值表达式和v-text都不会解析要添加文本中的HTML标签(原样显示) v-html: 和v-text的唯一区别:给HTML添加内容时会解析内容中的HTML实例演示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-cloak、v-text、v-html指令以及插值表达式的学习</title> <style> [v-cloak]{ display: none; } </style> </head> <body> <h1>v-cloak、v-text、v-html指令以及插值表达式的学习</h1> <div id="app"> <p v-cloak>{{msg1}}</p> <p>{{msg1}}</p> <p v-text="msg1"></p> <p v-text="msg2"></p> <p>{{msg2}}</p> <p v-html="msg2"></p> </div> <script src="../lib/vue.js" type="text/javascript"></script> <script type="text/javascript"> //vue应用对象 var vm = new Vue({ ////绑定属性 el:"#app", data:{ msg1:"Hello", msg2:"<p style='color:red'>我是一个p标签</p>" } }); </script> </body> </html>
编辑测试的结果:
2.bind+on指令的学习
v-bind: 语法:在HTML元素的属性目前加上绑定标识,此时HTML的该属性的值就会根据属性值的名字从Model中获取数据 示例: <label>用户名:<input type="text" name="username" v-bind:value="msg" /></label> var vm = new Vue({ el:"#app", data:{ msg:"我是来自Model中的内容!", name:"李师师" } }); 注意: 1.【v-bind:】用于绑定HTML元素属性的值 2.【v-bind:】可以简写为: 3.Vue框架会把使用了v-bind:标识的HTML的属性的值当作一个Javascript表达式来使用 只要表达式合法,就能执行(当然,数据必须时字面量或来自于Model中) 如: :value="msg+'你好'" :value="msg+name"v-on: 语法:在HTML的事件属性(不带on)前加上绑定标识,此时HTML触发此事件时,会执行事件中绑定的代码 示例: <button v-on:click="sayHello(name)">点击下显示你好</button> <button @click="sayHello(name)">点击下显示你好</button> var vm = new Vue({ el:"#app", data:{ msg:"我是来自Model中的内容!", name:"李师师" }, methods:{ sayHello:function (name) { alert("你好!"+name); } } }); 注意: 1.常见的web网页的事件都支持绑定 2.事件名字不带on 3.事件触发的方法必须在methods中定义 4.v-on标识的属性会被Vue解析为特定JavaScript,只要内容符合JavaScript规范 都能正确执行(比如传入参数) 4.【v-on:】等价于【@】实例演示:
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>v-bind、v-on指令的学习</title> <script src="../lib/vue.js" type="text/javascript"></script> </head> <body> <h1>v-bind、v-on指令的学习</h1> <div id="app"> <label>用户名:<input type="text" name="username" v-bind:value="msg" /></label> <hr/> <label>用户名:<input type="text" name="username" :value="msg" /></label> <hr/> <label>用户名:<input type="text" name="username" :value="msg+'你好'"></label> <hr/> <label>用户名:<input type="text" name="username" :value="msg+name"></label> <button v-on:click="sayHello(name)">点击下显示你好</button> <button @click="sayHello(name)">点击下显示你好</button> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{
msg:"我是一个练习长达两年半的练习生!",name:"菜徐坤"
}, methods:{ sayHello:function (name) { alert("你好!"+name); } } }); </script> </body>
测试结果:
点击按钮
3.VUE中的事件修饰符
1.事件默认是会冒泡的(点击内部元素,会逐层向外扩散,相同的事件就会被触发---冒泡) 阻止方式:给需要阻止冒泡的事件加上stop修饰 特点:事件到了加了stop修饰的元素时就会被阻断 2.阻止元素的默认事件 元素默认会执行它的默认事件 默认事件: 2.1:超链接的跳转 2.2:表单的提交 阻止方式:给需要阻止默认事件的事件绑定加上prevent修饰 3.使用事件捕获模式处理事件(触发事件的顺序和事件冒泡刚好相反) 特点:加了capture事件修饰的容器先捕获到事件,然后按照冒泡顺序 触发,当然如果其它元素也设置了capture事件修饰,则按照修饰顺序来 使用方式:给需要使用捕获机制处理的事件绑定加入修饰符capture 4.事件源是自身时才触发事件 使用方式:给元素绑定的事件中加入self修饰,此时只有事件源是元素本身时 才会触发事件 特点: 1.能阻止事件冒泡 2.只能阻止自身的事件不被触发,而其子元素和父元素依然满足冒泡行为 或捕获机制 3.这是stop和self之间的一个差距 5.限定事件有效次数为1 使用方式:给元素绑定的事件加入once修饰,表示此事件只会执行一次 特点:绑定事件只执行一次,那么意味着事件的所有修饰也会在事件无效后消失 比如:事件冒泡和默认行为实例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue中的事件修饰符</title> <script src="../lib/vue.js" type="text/javascript"></script> <style type="text/css"> div[id]{ box-sizing: border-box; } #outer{ width: 400px; height: 400px; background-color: yellow; padding: 100px; } #inner{ width: 200px; height: 200px; background-color: red; padding: 50px; } #content{ width: 100px; height: 100px; background-color: deeppink; } </style> </head> <body> <h1>Vue中的事件修饰符</h1> <div id="app"> <!--阻止事件冒泡--> <!--<div id="outer" @click="outerClick()"> <div id="inner" @click.stop="innerClick()"> <div id="content" @click="contentClick()"></div> </div> </div>--> <!--阻止默认事件--> <hr/> <a href="https://www.baidu.com" @click.prevent="aClick">点击跳转到百度</a> <hr/> <form action="https://www.baidu.com"> <button @click.prevent="btnClick">点击提交表单</button> </form> <!--使用捕获机制处理绑定事件--> <!--<div id="outer" @click.capture="outerClick()"> <div id="inner" @click.capture="innerClick()"> <div id="content" @click.capture="contentClick()"></div> </div> </div>--> <!--使用self表示自身触发--> <div id="outer" @click="outerClick()"> <div id="inner" @click.self="innerClick()"> <div id="content" @click="contentClick()"></div> </div> </div> <!--阻止默认事件--> <hr/> <a href="https://www.baidu.com" @click.prevent.once="aClick">点击跳转到百度</a> <hr/> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{}, methods:{ contentClick(){ console.log("content被点击了..."); }, innerClick(){ console.log("inner被点击了..."); }, outerClick(){ console.log("outer被点击了..."); }, aClick(){ console.log("a被点击了..."); }, btnClick(){ console.log("btn被点击了..."); } } }); </script> </body> </html>
测试结果:
4.双向数据绑定以及实现简易计算器
v-mode:唯一的一个实现双向数据绑定的指令 语法: <input type="text" v-model="num1" /> data:{ num1:'0', num2:'0' } 适用元素:表单元素,其它元素不能使用v-model指令 input系列(可以输入内容的)、select、textarea 双向绑定: model层数据的改变会影响view层HTML结果 HTML中表单元素值的改变会写入对应的model层的数据中 实例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue中的双向数据绑定指令v-mode</title> <script src="../lib/vue.js" type="text/javascript"></script> </head> <body> <div class="box"> <h1>Vue中的双向数据绑定指令v-mode</h1> <label>单价:<input type="text" v-model="price"></label><br/> <label>数量:<input type="text" v-model="num"></label><br/> <button @click="calc()">点击计算总价</button><br/> <label>总价:<span style="color:deeppink" v-text="sum"></span></label> <hr/> <h1>使用v-mode双向数据绑定实现建议计算器</h1> <label>操作数1:<input type="text" v-model="num1" /></label> <select v-model="opr"> <option value="+">+</option> <option value="-">-</option> <option value="*">x</option> <option value="/">/</option> </select> <label>操作数1:<input type="text" v-model="num2" /></label> <button @click="doCalc()">=</button> <span style="font-size: 20px;color:deeppink" v-text="result"></span> </div> <script type="text/javascript"> var vm2 = new Vue({ el:".box", data:{ price:12, num:1, sum:12, num1:'0', num2:'0', opr:'+', result:0 }, methods:{ calc(){ this.sum = this.price*this.num; }, doCalc(){ //标准的switch分支根据计算类型不同得到不同结果 /*switch(this.opr){ case "+": this.result = parseInt(this.num1)+parseInt(this.num2); break; case "-": this.result = parseInt(this.num1)-parseInt(this.num2); break; case "*": this.result = parseInt(this.num1)*parseInt(this.num2); break; case "/": this.result = parseInt(this.num1)/parseInt(this.num2); break; }*/ //使用eval计算获取结果 this.result = eval("parseInt(this.num1)"+this.opr+"parseInt(this.num2)"); } } }); </script> </body> </html>
测试结果:
5.Vue给行内元素绑定上样式属性
Vue绑定元素样式: Vue实现行内样式: 方式1:传入JavaScript对象{样式名字1:值1,样式名字2:值2...} 方式2:传入一个Vue中的Model层的一个属性值 方式3:传入一个Vue中的Model层的多个属性值组成的数组 Vue实现class样式: 方式1:直接传入单个class的名字 :class="'color'" 方式2:传入class名字组成的数组 :class="['color','fontSize']" 方式3:使用三目表达式实现样式的逻辑加入 :class="['color','fontSize',false?'active':'']" :class="['color','fontSize',5>3?'active':'']" :class="['color','fontSize',flag===false?'active':'']" 方式4:数组中嵌套对象 :class="['color','fontSize',{active:false}]" 方式5:整个class的值就使用数组 :class="{color:true,fontSize:false,space:true,style:true,active:false} 方式6:从Vue的Model中获取class值 :class="[classInBox01,classInBox02]" 【注意】 1.JavaScript的对象中,属性可以不使用引号(单双) 2.当属性包含字符-的时候,必须使用引号,否则会报错 3.使用vue绑定class值时,class的值必须使用引号引起来,否则会当作变量从Model中查找 4.使用vue绑定class值时,如果值为对象,则不能加引号实例代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用Vue给元素绑定样式属性</title> <script src="../lib/vue.js" type="text/javascript"></script> <style type="text/css"> .color{ color: deeppink; } .fontSize{ font-size: 30px; } .space{ letter-spacing: 0.5em; } .style{ font-style: italic; } .active{ background-color: yellow; } </style> </head> <body> <div id="app"> <h1 v-bind:style="{color:'red','font-size':'20px'}">我是一个H1标题,它会发生很多变化喔~</h1> <h1 v-bind:style="innerStyle01">我是一个H1标题,它会发生很多变化喔~</h1> <h1 v-bind:style="[innerStyle01,innerStyle02]">我是一个H1标题,它会发生很多变化喔~</h1> <hr/> <h1 :class="'color'">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class='"color"'>我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="['color','fontSize']">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="['color','fontSize',false?'active':'']">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="['color','fontSize',5>3?'active':'']">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="['color','fontSize',flag===false?'active':'']">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="['color','fontSize',{active:false}]">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="{color:true,fontSize:false,space:true,style:true,active:false}">我是一个H1标题,它会发生很多变化喔~</h1> <h1 :class="[classInBox01,classInBox02]">我是一个H1标题,它会发生很多变化喔~</h1> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ innerStyle01:{color:'red','font-size':'20px'}, innerStyle02:{"letter-spacing":"1em"}, flag:true, classInBox01:{color:true,fontSize:false}, classInBox02:{space:true,style:true,active:false} } }); </script> </body> </html>
测试结果:
6.VUE中的for指令
1.使用v-for指令遍历简单数组 <p v-for="name in names">{{name}}</p> <p v-for="name,index in names" v-text="name+'---'+index"></p>2.使用v-for指令遍历对象数组 <p v-for="user in users">id:{{user.id}}---name:{{user.name}}</p>3.使用v-for指令遍历对象属性值 <p v-for="value,key in cqCity">{{key+'--'+value}}</p>4.使用v-for指令遍历数字(作用就是标准的for循环次数遍历) <p v-for="num,index in 12" v-text="num+'---'+index"></p>【注意】 1.遍历得到的值可以使用【插值表达式、v-text、v-html】显示 2.不管遍历何种数据类型,都可以得到值和索引 3.遍历对象属性和值时可以得到【值、属性名字、索引】 4.值的赋值顺序是:值、【键名】、索引 5.一次遍历中,多个结果之间使用,分割即可对应赋值(value,key,index) 6.遍历过程中接受值的变量名字可以任意 7.遍历数字时数字是从1开始,不能是负数(因为该功能是固定次数遍历) 8.在组件中使用数据时,一定要用key唯一绑定数据(保证对UI组件的操作不会因为其它组件的变化而发生变化) 注意: 1.key必须是基本数据类型(string/number) 报错:Avoid using non-primitive value as key, use string/number value instead. 2.key的数据值一定不要重复 报错:Duplicate keys detected: '3'. This may cause an update error. 技巧:一般使用对象中的值唯一属性(主键)作为key,比如id 语法: <p v-for="user in users" :key="user.id"> <label><input type="checkbox"/>{{user.id}}---{{user.name}}</label> </p>【知识点】 1.如果组件的属性的值是一个变量,则必须使用v-bind:或者:进行属性值的绑定 2.数组的push()方法用于向数组末尾加入元素,数组的unshift()方法用于向数组最前面加入元素 this.users.push({id:this.id,name:this.name,age:this.age}); this.users.unshift({id:this.id,name:this.name,age:this.age}); 3.在遍历对象数组并结合组件(表单元素)一起使用时,一定要指定唯一的key属性,进行组件和数据 的唯一关联,避免被其它操作(指非本元素)影响
实例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue中的for指令</title> <script src="../lib/vue.js" type="text/javascript"></script> </head> <body> <div id="app"> <h1>Vue中的for指令</h1> <p v-for="name in names">{{name}}</p> <hr/> <p v-for="name,index in names" v-text="name+'---'+index"></p> <hr/> <p v-for="user in users" v-text="user"></p> <hr/> <p v-for="user in users">id:{{user.id}}---name:{{user.name}}---age:{{user.age}}</p> <hr/> <p v-for="value,key in cqCity">{{key+'--'+value}}</p> <hr/> <p v-for="num in 12" v-text="num"></p> <hr/> <p v-for="num,index in 12" v-text="num+'---'+index"></p> <h1>Vue中的for指令实现数据绑定</h1> <label>id:<input type="text" v-model="id"/></label> <label>name:<input type="text" v-model="name"/></label> <label>age:<input type="text" v-model="age"/></label> <label><button @click="add()">添加人员信息</button></label> <p v-for="user in users" :key="user.id"> <label><input type="checkbox"/>{{user.id}}---{{user.name}}---{{user.age}}</label> </p> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ names:["陈斯","杨晓露","徐子雁","冉春嫦","冷芹","冉维","彭丽敏","王超群","彭前"], users:[ {id:1,name:"胡歌",age:32}, {id:2,name:"袁弘",age:33}, {id:3,name:"霍建华",age:35} ], cqCity:{no:"渝",level:"市",area:["渝北区","渝中区","江北区","沙坪坝区","江北区"]}, id:'', name:'', age:'' }, methods:{ add(){ //this.users.push({id:this.id,name:this.name,age:this.age}); this.users.unshift({id:this.id,name:this.name,age:this.age}); } } }); </script> </body> </html>
测试结果:
7.VUE的if和show指令
v-if和v-show指令: v-if和v-show的区别? 1.v-if切换元素状态的具体操作是(创建元素--删除元素) 比较消耗创建性能 2.v-show切换元素状态的具体操作是(修改css的display样式) 比较消耗渲染性能 使用技巧: 如果该元素会经常显示/隐藏,则使用v-show 如果该元素默认情况下不会显示(大多数时候不会显示),则使用v-if 代码技巧: 如果使用vue绑定的方法只有一句代码,则可以直接写在绑定结果中 <button @click="flag=!flag">控制元素的显示隐藏</button>
实例:
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Vue中的if和show指令</title> <script src="../lib/vue.js" type="text/javascript"></script> </head> <body> <h1>使用vue中的v-if和v-show指令实现元素的显示和隐藏</h1> <div id="app"> <button v-on:click="toggle()">控制元素的显示隐藏</button> <button @click="flag=!flag">控制元素的显示隐藏</button> <p v-if="flag">我是使用v-if控制的p标签</p> <p v-show="flag">我是使用v-show控制的p标签</p> </div> <script type="text/javascript"> var vm = new Vue({ el:"#app", data:{ flag:true }, methods:{ toggle(){ this.flag = !this.flag; } } }); </script> </body> </html>
测试结果:
可见点击后,原按钮下的文本信息被隐藏
8.使用Vue和bootstrap模拟数据表的操作
数组方法: 回调中的返回值不能阻止循环(必须循环完成才能得到最后结果) forEach()---返回void,在回调内部可以做任何操作 filter()----返回过滤后的数组 回调中的返回值可以阻止继续循环(查到了结果直接结束循环) findIndex()-返回整数(内部回调函数最终没有返回true时,则返回-1,否则返回回调过程中的下标) some()------返回boolean(就是回调中的return语句的结果) 元素操作: splice(startIndex,count,...newElements):删除从startIndex下标处开始的count个元素 还可以添加新元素newElements,返回新的数组 push(newElements):在数组末尾添加新的元素newElements,返回新数组的长度 unshift(newElements):在数组的最前方添加新的元素newElements,返回新数组的长度字符串方法: 其它类型数据->字符串 var dataStr = String(其它类型数据); var dataStr = 对象.toString(); var dataStr = 对象+''; 模板字符串: 使用飘号 `` 包裹占位模板-> var dateStr = `${year}-${month}-${dayNow}` 此时模板中的${year}等会被解析成对应变量的值 如 year month dayNow 字符串填充: padStart(length,padContent)--在字符串的起始位置填充内容padContent,直至字符串长度为length padEnd(length,padContent)----在字符串的结束位置填充内容padContent,直至字符串长度为length自定义过滤器: Vue全局过滤器: 1.必须定义在创建Vue对象之前(Javascript的边解析边执行原理) 2.定义之后在整张页面中可以使用(一个页面一个Window,一个Window下只有一个Vue) 3.定义方式 参数1:固定(需要被过滤处理的数据) 参数2...参数n:过滤器被调用时传递的参数 Vue.filter("过滤器名字",function(data,param1,param2...){ }); 4.调用方式 <h1>{{msg|v-过滤器名字(参数值1,参数值2...)|过滤器2...|过滤器n...}}</h1> Vue具体对象(特定作用域)过滤器: 1.定义在一个Vue对象中 2.定义方式 var vm = new Vue({ el:"#app1", data:{}, methods:{}, filters:{ 过滤器名字:function(data,param1,param2...){ }或 过滤器名字(data,param1,param2...){ } } }); 【注意】 1.全局过滤器一定要定义在使用Vue之前 2.Vue的过滤器执行原理 渲染内容 -- 交给第一个处理器 -- 得到结果 -- 交给第二个处理器 -- 得到结果 .... 得到结果--渲染按键修饰符:(用于修饰键盘事件,当按键匹配时触发) 系统内置: .enter、.tab、.delete (捕获“删除”和“退格”键)、.esc、.space .up、.down、.left、.right 使用方式: <p @keyup.enter="add()">在p标签上按下回车键</p> <p @keyup.13="add()">在p标签上按下回车键</p> 原理: 把事件绑定后的修饰keyCode拿到Vue内部事件对象event的keyCode进行比较,匹配则触发 系统把常见的按键的keyCode和别名进行了对应(13--enter等) 自定义按键修饰: Vue.config.keyCodes.别名=特定keyCode; 【注意】 1.自定义的按键修饰应该写在使用Vue之前 2.按键修饰是可以串联的 如 <p @keyup.enter.down="add()">在p标签上按下回车键</p> 表示按下 回车键和下键 都会触发自定义指令:https://cn.vuejs.org/v2/guide/custom-directive.html#ad 系统内置: v-cloak、v-text、v-html、v-bind、v-on、v-for、v-if、v-show、v-model 自定义: 全局: 1.必须定义在使用Vue之前(边解析边执行原理) 2.定义方式 参数1:指令名字 参数2:各声明周期函数组成的对象(周期函数可选重写,并不一定需要全部重写) bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置 inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中) update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前 指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用 unbind:只调用一次,指令与元素解绑时调用 生命周期函数的参数说明: el:指令所绑定的元素,可以用来直接操作 DOM 。 binding:一个对象,包含以下属性(def、name、rawName、value、expression、modifiers) vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。 oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。 Vue.directive("指令名字",{ bind:function (el, f, vnode) {}, inserted:function (el, binding, vnode, oldVnode) {}, update:function (el, ref, vnode) {}, componentUpdated:function (el, binding, vnode) {}, unbind:function (el, binding, vnode, oldVnode, isDestroy) {} }); 局部: 定义方式: var vm = new Vue({ el:"#app", data:{}, methods:{}, filters:{}, directives:{ 指令名字1:{ bind:function(){}, inserted:function(){}, update:function(){}, componentUpdated:function(){}, unbind:function(){} }, 指令名字2:{} .... } }); 简易定义方式: Vue.directive("指令名字",function(el,binding,vnode,oldVnode){ 此时function中的代码会作用到bind和inserted钩子函数上 }); 【注意】 1.自定义的指令,Vue系统会自动给名字加上v- 2.调用指令时,一定要加上v-,如果你的指令名字是以v-开始,则最终调用是v-v-指令名字 3.自定义的指令,需要指定其对应的钩子函数(如不指定,则使用默认实现) 4.自定义指令时,常关注的钩子函数(bind、inserted)(因此自定义指令的简写方式默认就是实现该钩子函数)Vue数据查看工具:vue Devtools 安装:浏览器在线安装插件vue Devtools或者本地安装插件vue Devtools 使用: 1.该插件只能在使用了vue.js的站点上使用 2.该插件需要打开审查元素进行使用 3.进入审查元素时,选择vue菜单项即可 4.左侧的一个Root代表一个vue实例对象(一个作用域空间)
示例:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>使用vue和Bootstrap模拟数据表的操作</title> 6 <link href="../lib/bootstrap.css" rel="stylesheet" type="text/css" /> 7 <script src="../lib/vue.js" type="text/javascript"></script> 8 </head> 9 <body> 10 11 <h1>使用vue和Bootstrap模拟数据表的操作</h1> 12 <div id="app"> 13 <div class="panel panel-primary"> 14 <div class="panel-heading"> 15 <h3 class="panel-title">汽车品牌</h3> 16 </div> 17 <div class="panel-body form-inline"> 18 <label @keyup.enter="add()"> 19 Id: 20 <input type="text" class="form-control" v-model="id" /> 21 </label> 22 <label> 23 Name: 24 <input type="text" class="form-control" v-model="name" v-go/> 25 </label> 26 <label> 27 CTime: 28 <input type="text" class="form-control" v-model="cTime" @keyup.f2.13="add()"/> 29 </label> 30 <button class="btn btn-primary" @click="add()">添加</button> 31 <label> 32 Keywords: 33 <input type="text" class="form-control" v-model="keywords" v-focus/> 34 </label> 35 </div> 36 </div> 37 <table class="table table-bordered table-hover table-responsive table-striped"> 38 <thead> 39 <tr> 40 <th>Id</th> 41 <th>Name</th> 42 <th>CTime</th> 43 <th>Operation</th> 44 </tr> 45 </thead> 46 <!--绑定固定数据--> 47 <!--<tbody> 48 <tr v-for="car in cars" :key="car.id"> 49 <td>{{car.id}}</td> 50 <td>{{car.name}}</td> 51 <td>{{car.cTime}}</td> 52 <td><a href="#" @click.prevent="del(car.id)">删除</a></td> 53 </tr> 54 </tbody>--> 55 56 <!--绑定动态搜索数据--> 57 <tbody> 58 <tr v-for="car in search(keywords)" :key="car.id"> 59 <td>{{car.id}}</td> 60 <td>{{car.name}}</td> 61 <td>{{car.cTime|dateFormat()}}</td> 62 <td><a href="#" @click.prevent="del(car.id)">删除</a></td> 63 </tr> 64 </tbody> 65 </table> 66 </div> 67 <script type="text/javascript"> 68 //创建全局时间格式化过滤器 69 Vue.filter("dateFormat",function (data,pattern) { 70 //console.log(this,data,pattern); 71 var date = new Date(data); 72 var year = String(date.getFullYear()).padStart(2,'0'); 73 var month = String(date.getMonth()+1).padStart(2,'0'); 74 var dayNow = String(date.getDate()).padStart(2,'0'); 75 var hour = String(date.getHours()).padStart(2,'0'); 76 var minute = String(date.getMinutes()).padStart(2,'0'); 77 var seconds = String(date.getSeconds()).padStart(2,'0'); 78 if(pattern&&pattern.toLowerCase()==="yyyy-mm-dd"){ 79 return year+"-"+month+"-"+dayNow; 80 }else{ 81 return `${year}-${month}-${dayNow} ${hour}:${minute}:${seconds}`; 82 } 83 }); 84 //配置按键修饰符 85 Vue.config.keyCodes.f2=113; 86 //定义全局指令 87 //bind: function bind (el, ref, vnode) 88 Vue.directive("focus",{ 89 bind:function (el,data,vNode) { 90 console.log(el,data,vNode); 91 //el.focus(); 92 }, 93 inserted:function (el,ref,vNode) { 94 el.focus(); 95 }, 96 update:function () { 97 98 }, 99 componentUpdated:function () { 100 101 }, 102 unbind:function () { 103 104 } 105 }); 106 var vm = new Vue({ 107 el:"#app", 108 data:{ 109 id:'', 110 name:'', 111 cTime:'', 112 keywords:'', 113 cars:[ 114 {id:1,name:"兰博基尼",cTime:new Date()}, 115 {id:2,name:"保时捷",cTime:new Date()}, 116 {id:3,name:"玛莎拉蒂",cTime:new Date()}, 117 ] 118 }, 119 methods:{ 120 add(){ 121 var newCar = {id:this.id,name:this.name,cTime:this.cTime}; 122 this.cars.push(newCar); 123 this.id = this.name = this.cTime = ''; 124 }, 125 del(id){ 126 //步骤1:拿到id 127 //步骤2:根据id值删除数据 128 //真实数据库:发送请求即可 129 //模拟数据:根据对象的id值,从数组中查找出该id值对应的对象的索引 130 //步骤3:执行删除操作 131 //真实数据库:发送请求删除 132 //模拟数据:从数组中移出 133 //方法声明:some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; 134 //this.doDel1(id); 135 //this.doDel2(id); 箭头函数 136 this.doDel3(id); 137 }, 138 doDel1(id){ 139 var _this = this; 140 var isOk = this.cars.some(function (car,index,callObj) { 141 //callObj:每次调用some方法的数组 142 //this:Window对象 143 console.log(callObj,this); 144 if(car.id === id){ 145 console.log(car); 146 //splice(start: number, deleteCount: number, ...items: T[]): T[]; 147 _this.cars.splice(index,1).unshift(); 148 return true; 149 } 150 }); 151 }, 152 doDel2(id){ 153 var isOk = this.cars.some((car,index,callObj)=>{ 154 console.log(callObj,this); 155 if(car.id===id){ 156 this.cars.splice(index,1); 157 return true; 158 } 159 }); 160 }, 161 doDel3(id){ 162 //findIndex(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): number; 163 //返回找到的索引,找不到返回-1 164 var index = this.cars.findIndex((car,index,callObj)=>{ 165 if(car.id===id){ 166 return true; 167 } 168 }); 169 console.log(index); 170 if(index!==-1){this.cars.splice(index,1);} 171 }, 172 search(keywords){//执行过滤搜索 173 /*var newCars = []; 174 //forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; 175 this.cars.forEach((car,index,callObj)=>{ 176 if(car.name.indexOf(keywords)!==-1){ 177 newCars.push(car); 178 } 179 }); 180 return newCars; 181 //console.log(keywords);*/ 182 183 //filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; 184 var newCars = this.cars.filter((car,index,callObj)=>{ 185 //includes(searchString: string, position?: number): boolean; 186 if(car.name.includes(keywords)){ 187 return car; 188 } 189 }); 190 return newCars; 191 } 192 }, 193 filters:{}, 194 directives:{ 195 go(el,ref,vNode){ 196 console.log(el,ref,vNode); 197 } 198 } 199 }); 200 </script> 201 </body> 202 </html>
测试结果:
9.在vue中自定义过滤器
自定义过滤器: Vue全局过滤器: 1.必须定义在创建Vue对象之前(Javascript的边解析边执行原理) 2.定义之后在整张页面中可以使用(一个页面一个Window,一个Window下只有一个Vue) 3.定义方式 参数1:固定(需要被过滤处理的数据) 参数2...参数n:过滤器被调用时传递的参数 Vue.filter("过滤器名字",function(data,param1,param2...){ }); 4.调用方式 <h1>{{msg|v-过滤器名字(参数值1,参数值2...)|过滤器2...|过滤器n...}}</h1> Vue具体对象(特定作用域)过滤器: 1.定义在一个Vue对象中 2.定义方式 var vm = new Vue({ el:"#app1", data:{}, methods:{}, filters:{ 过滤器名字:function(data,param1,param2...){ }或 过滤器名字(data,param1,param2...){ } } }); 【注意】 1.全局过滤器一定要定义在使用Vue之前 2.Vue的过滤器执行原理 渲染内容 -- 交给第一个处理器 -- 得到结果 -- 交给第二个处理器 -- 得到结果 .... 得到结果--渲染
示例:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>在Vue中自定义过滤器</title> 6 <script src="../lib/vue.js" type="text/javascript"></script> 7 </head> 8 <body> 9 <h1>在Vue中自定义过滤器</h1> 10 <div id="app1"> 11 <h4>{{msg|replaceWords('我','他')|addStartInfo('----')}}</h4> 12 </div> 13 <hr/> 14 <div id="app2"> 15 <h4>{{msg|replaceWords('你','我')|addStartInfo('----')|addEndInfo('~~~~~')}}</h4> 16 </div> 17 <script type="text/javascript"> 18 //定义全局过滤器 19 Vue.filter("replaceWords",function (data,oldWorld,newWorld) { 20 var reg = new RegExp(oldWorld,"g"); 21 return data.replace(reg,newWorld); 22 }); 23 Vue.filter("addEndInfo",function (data,endInfo) { 24 return data.concat(endInfo); 25 }); 26 var vm1 = new Vue({ 27 el:"#app1", 28 data:{ 29 msg:"我是你的爱人,我是对你最好的人,我好伤心,你从未关心我!" 30 }, 31 methods:{ 32 33 }, 34 filters:{ 35 addStartInfo(data,startInfo){ 36 return startInfo.concat(data); 37 } 38 } 39 }); 40 var vm2 = new Vue({ 41 el:"#app2", 42 data:{ 43 msg:"我是你的爱人,我是对你最好的人,我好伤心,你从未关心我!" 44 }, 45 methods:{ 46 47 } 48 }); 49 </script> 50 </body> 51 </html>
测试结果:
10.VUE中自定义指令
自定义指令:https://cn.vuejs.org/v2/guide/custom-directive.html#ad 系统内置: v-cloak、v-text、v-html、v-bind、v-on、v-for、v-if、v-show、v-model 自定义: 全局: 1.必须定义在使用Vue之前(边解析边执行原理) 2.定义方式 参数1:指令名字 参数2:各声明周期函数组成的对象(周期函数可选重写,并不一定需要全部重写) bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置 inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中) update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前 指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用 unbind:只调用一次,指令与元素解绑时调用 生命周期函数的参数说明: el:指令所绑定的元素,可以用来直接操作 DOM 。 binding:一个对象,包含以下属性(def、name、rawName、value、expression、modifiers) vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。 oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。 Vue.directive("指令名字",{ bind:function (el, f, vnode) {}, inserted:function (el, binding, vnode, oldVnode) {}, update:function (el, ref, vnode) {}, componentUpdated:function (el, binding, vnode) {}, unbind:function (el, binding, vnode, oldVnode, isDestroy) {} }); 局部: 定义方式: var vm = new Vue({ el:"#app", data:{}, methods:{}, filters:{}, directives:{ 指令名字1:{ bind:function(){}, inserted:function(){}, update:function(){}, componentUpdated:function(){}, unbind:function(){} }, 指令名字2:{} .... } }); 简易定义方式: Vue.directive("指令名字",function(el,binding,vnode,oldVnode){ 此时function中的代码会作用到bind和inserted钩子函数上 }); 【注意】 1.自定义的指令,Vue系统会自动给名字加上v- 2.调用指令时,一定要加上v-,如果你的指令名字是以v-开始,则最终调用是v-v-指令名字 3.自定义的指令,需要指定其对应的钩子函数(如不指定,则使用默认实现) 4.自定义指令时,常关注的钩子函数(bind、inserted)(因此自定义指令的简写方式默认就是实现该钩子函数) 5.bind和inserted执行时机详讲 Vue.directive("color",{ bind:function (el,binding) { //css样式可以在bind中设置 el.style.color=binding.value; //获取指令传递过来的数据(可以是任意数据类型) }, inserted:function (el,binding) { //JavaScript效果等需要在inserted中设置 el.focus(); } });示例:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Vue中自定义指令详细测试</title> 6 <script src="../lib/vue.js" type="text/javascript"></script> 7 </head> 8 <body> 9 <div id="app"> 10 <input v-color="'blue'" value="我是一个h1啊~" /> 11 <br> 12 <input v-color="'red'" value="我是一个h1啊~" /> 13 </div> 14 <script type="text/javascript"> 15 /*Vue.directive("color",function (el,binding,vnode,oldVnode,isDistory) { 16 console.log(this,el,binding,vnode,oldVnode,isDistory); 17 el.style.color=binding.value; 18 });*/ 19 Vue.directive("color",{ 20 bind:function (el,binding) { 21 //css样式可以在bind中设置 22 el.style.color=binding.value; //获取指令传递过来的数据(可以是任意数据类型) 23 }, 24 inserted:function (el,binding) { 25 //JavaScript效果等需要在inserted中设置 26 el.focus(); 27 } 28 }); 29 var vm = new Vue({ 30 el:"#app", 31 data:{}, 32 methods:{}, 33 filters:{}, 34 directives:{} 35 }); 36 </script> 37 </body> 38 </html>
测试结果:
以上十种指令就是VUE的基本指令,熟练掌握以上指令,合理使用,我觉得最大的便捷之处就在于,前端功能和后端功能很明显的分离,对于工作分工,明确各自职责是十分有利,同时前端可模拟进行一些数据操作,为操作真实数据提供了一些安全保障。
来源:https://www.cnblogs.com/longinfo/p/11310729.html