2018.7.13vue知识小结
1 //配置是否允许vue-devtools检查代码,方便调试,生产环境中需要设置为false 2 Vue.config.devtools=false; 3 Vue.config.productionTip=false; //阻止vue启动时生成生产消息
for循环
1 <ul> 2 普通循环 3 <li v-for="value in arr">{{value}}</li> 4 <li v-for="value in user">{{value}}</li> 5 6 键值循环 7 <li v-for="(v,k) in arr">{{k}}={{v}}</li> 8 <li v-for="(v,k) in user">{{k}}={{v}}</li> 9 10 可以直接循环包含重复数据的集合,可以通过指定:key属性绑定唯一key,当更新元素时可重用元素,提高效率,类似于vue1.0中track-by 11 <li v-for="(v,k) in arr2" :key="k">{{v}}</li> 12 13 <li v-for="(user,index) in users"> 14 {{index+1}},{{user.id}},{{user.name}},{{user.age}} 15 </li> 16 </ul>
通过表单给table添加行:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>练习:用户管理</title> 6 <script src="js/vue.js"></script> 7 <link rel="stylesheet" href="bootstrap/bootstrap.min.css"> 8 <script src="bootstrap/jquery.min.js"></script> 9 <script src="bootstrap/bootstrap.min.js"></script> 10 <body> 11 <div class="contaienr"> 12 <h2 class="text-center">添加用户</h2> 13 <form class="form-horizontal"> 14 <div class="form-group"> 15 <label for="name" class="control-label col-sm-2 col-sm-offset-2">姓名</label> 16 <div class="col-sm-6"> 17 <input class="form-control" id="name" placeholder="请输入姓名" v-model="user.name"> 18 </div> 19 </div> 20 <div class="form-group"> 21 <label for="age" class="control-label col-sm-2 col-sm-offset-2">年 龄:</label> 22 <div class="col-sm-6"> 23 <input type="text" class="form-control" id="age" v-model="user.age" placeholder="请输入年龄"> 24 </div> 25 </div> 26 <div class="form-group"> 27 <label for="email" class="control-label col-sm-2 col-sm-offset-2">邮 箱:</label> 28 <div class="col-sm-6"> 29 <input type="text" class="form-control" id="email" v-model="user.email" placeholder="请输入邮箱"> 30 </div> 31 </div> 32 <div class="form-group text-center"> 33 <input type="button" class="btn btn-primary" value="重置" @click="addUser"> 34 <input type="reset" class="btn btn-primary" value="添加" > 35 </div> 36 </form> 37 <hr> 38 <!--表格--> 39 <table class="table table-bordered table-hover"> 40 <caption class="h3 text-center text-info">用户列表</caption> 41 <thead> 42 <tr> 43 <th class="text-center">序号</th> 44 <th class="text-center">姓名</th> 45 <th class="text-center">年龄</th> 46 <th class="text-center">邮箱</th> 47 <th class="text-center">操作</th> 48 </tr> 49 </thead> 50 <tbody> 51 <tr v-for="(user,index) in users" class="text-center"> 52 <td>{{index+1}}</td> 53 <td>{{user.name}}</td> 54 <td>{{user.age}}</td> 55 <td>{{user.email}}</td> 56 <td> 57 <button class="btn btn-danger btn-sm" @click="nowIndex=index" data-toggle="modal" data-target="#del">删除</button> 58 </td> 59 </tr> 60 <tr> 61 <td colspan="5" class="text-right"> 62 <button class="btn btn-danger btn-sm" data-toggle="modal" data-target="#del" v-on:click="nowIndex=-1" data-toggle="modal" data-target="#del">删除所有</button> 63 </td> 64 </tr> 65 </tbody> 66 </table> 67 68 69 <!-- 模态框,弹出框 --> 70 <div class="modal fade" id="del"> 71 <div class="modal-dialog"> 72 <div class="modal-content"> 73 <div class="modal-header"> 74 <button class="close" data-dismiss="modal"> 75 <span>×</span> 76 </button> 77 <h4 class="modal-title" v-show="nowIndex!==-1">确认要删除用户:{{users[nowIndex]?users[nowIndex].name:''}} 吗?</h4> 78 <h4 class="modal-title" v-show="nowIndex===-1">确认要删除所有用户吗?</h4> 79 </div> 80 <div class="modal-body text-center"> 81 <button class="btn btn-primary" data-dismiss="modal">取消</button> 82 <button class="btn btn-primary" data-dismiss="modal" @click="deleteUser">确认</button> 83 </div> 84 </div> 85 </div> 86 </div> 87 </div> 88 </body> 89 </html> 90 <script> 91 let vm=new Vue({ 92 el:'.contaienr', 93 data:{ 94 users:[ 95 {name:'tom',age:24,email:'tom@itany.com'}, 96 {name:'jack',age:23,email:'jack@sina.com'} 97 ], 98 user:{}, 99 nowIndex:-1, 100 }, 101 methods:{ 102 addUser(){ 103 this.users.push(this.user) 104 this.user={} 105 }, 106 deleteUser(){ 107 if(this.nowIndex=-1){ 108 this.users=[]; 109 }else{ 110 this.users.splice(this.nowIndex,1); //从指定索引位置开始删除,删除一个 111 112 } 113 } 114 } 115 }) 116 </script>
自定义一个全局过滤器:
1 <body> 2 <div id="itany"> 3 <h3>{{3 | addZero}}</h3> 4 <h3>{{30 | addZero}}</h3> 5 </div> 6 </body> 7 </html> 8 <script> 9 Vue.filter('addZero',function(date){ 10 return date<10?'0'+date:date; 11 }) 12 new Vue({ 13 el:'#itany', 14 data:{ 15 date:'', 16 } 17 }) 18 //页面返回值:03||30 19 </script>
自定义全局格式化日期的过滤器:
1 <body> 2 <div id="itany"> 3 <h3>{{date | date}}</h3> 4 </div> 5 </body> 6 </html> 7 <script> 8 Vue.filter('date',function(date){ 9 let d=new Date(date) 10 return d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate()+' '+d.getHours()+':'+d.getMinutes()+':'+d.getSeconds(); 11 //2018-7-13 17:22:14 12 }) 13 new Vue({ 14 el:'#itany', 15 data:{ 16 date:Date.now(), 17 } 18 }) 19 </script>
自定义四舍五入局部过滤器:
1 <body> 2 <div id="itany"> 3 <h3>{{12.345678 | number(2)}}</h3> 4 </div> 5 </body> 6 </html> 7 <script> 8 9 new Vue({ 10 el:'#itany', 11 data:{ 12 data:'', 13 }, 14 filters:{ 15 number:(data,n)=>{ 16 return data.toFixed(n)//12.35 17 } 18 } 19 }) 20 </script>
讲义内容:
1 + 是一个构建用户界面的框架 2 + 是一个轻量级MVVM(Model-View-ViewModel)框架,和angular、react类似,其实就是所谓的数据双向绑定 3 + 数据驱动+组件化的前端开发(核心思想) 4 + 通过简单的API实现**响应式的数据绑定**和**组合的视图组件** 5 + 更容易上手、小巧 6 ## 二、起步 7 ### 1. 下载核心库vue.js 8 bower info vue 9 npm init --yes 10 cnpm install vue --save 11 vue2.0和1.0相比,最大的变化就是引入了Virtual DOM(虚拟DOM),页面更新效率更高,速度更快 12 ### 2. Hello World(对比angular) 13 #### 2.2 vue实现 14 js: 15 new Vue({ 16 el:'#itany', //指定关联的选择器 17 data:{ //存储数据 18 msg:'Hello World', 19 name:'tom' 20 } 21 }); 22 html: 23 <div id="itany"> 24 {{msg}} 25 </div> 26 27 ### 3. 安装vue-devtools插件,便于在chrome中调试vue 28 直接将vue-devtools解压缩,然后将文件夹中的chrome拖放到扩展程序中 29 30 //配置是否允许vue-devtools检查代码,方便调试,生产环境中需要设置为false 31 Vue.config.devtools=false; 32 Vue.config.productionTip=false; //阻止vue启动时生成生产消息 33 34 ## 三、 常用指令 35 ### 1. 什么是指令? 36 用来扩展html标签的功能 37 ### 2. vue中常用的指令 38 + v-model 39 双向数据绑定,一般用于表单元素 40 + v-for 41 对数组或对象进行循环操作,使用的是v-for,不是v-repeat 42 注:在vue1.0中提供了隐式变量,如$index、$key 43 在vue2.0中去除了隐式变量,已被废除 44 + v-on 45 用来绑定事件,用法:v-on:事件="函数" 46 + v-show/v-if 47 用来显示或隐藏元素,v-show是通过display实现,v-if是每次删除后再重新创建,与angular中类似 48 ## 五、 事件和属性 49 ### 1. 事件 50 #### 1.1 事件简写 51 v-on:click="" 52 简写方式 @click="" 53 #### 1.2 事件对象$event 54 包含事件相关信息,如事件源、事件类型、偏移量 55 target、type、offsetx 56 #### 1.3 事件冒泡 57 阻止事件冒泡: 58 a)原生js方式,依赖于事件对象 59 b)vue方式,不依赖于事件对象 60 @click.stop 61 #### 1.4 事件默认行为 62 阻止默认行为: 63 a)原生js方式,依赖于事件对象 64 #### 1.5 键盘事件 65 回车:@keydown.13 或@keydown.enter 66 上:@keydown.38 或@keydown.up 67 默认没有@keydown.a/b/c...事件,可以自定义键盘事件,也称为自定义键码或自定义键位别名 68 #### 1.6 事件修饰符 69 .stop - 调用 event.stopPropagation()。 70 .prevent - 调用 event.preventDefault()。 71 .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。 72 .native - 监听组件根元素的原生事件。 73 .once - 只触发一次回调。 74 ### 2. 属性 75 #### 2.1 属性绑定和属性的简写 76 v-bind 用于属性绑定, v-bind:属性="" 77 属性的简写: 78 v-bind:src="" 简写为 :src="" 79 #### 2.2 class和style属性 80 绑定class和style属性时语法比较复杂: 81 ## 六、 模板 82 ### 1. 简介 83 Vue.js使用基于HTML的模板语法,可以将DOM绑定到Vue实例中的数据 84 模板就是{{}},用来进行数据绑定,显示在页面中 85 也称为Mustache语法 86 ### 2. 数据绑定的方式 87 a.双向绑定 88 v-model 89 b.单向绑定 90 方式1:使用两对大括号{{}},可能会出现闪烁的问题,可以使用v-cloak解决 91 方式2:使用v-text、v-html 92 ### 3. 其他指令 93 v-once 数据只绑定一次 94 v-pre 不编译,直接原样显示 95 ## 七、 过滤器 96 ### 1. 简介 97 用来过滤模型数据,在显示之前进行数据处理和筛选 98 语法:{{ data | filter1(参数) | filter2(参数)}} 99 ### 2. 关于内置过滤器 100 vue1.0中内置许多过滤器,如: 101 currency、uppercase、lowercase 102 limitBy 103 orderBy 104 filterBy 105 vue2.0中已经删除了所有内置过滤器,全部被废除 106 如何解决: 107 a.使用第三方工具库,如lodash、date-fns日期格式化、accounting.js货币格式化等 108 b.使用自定义过滤器
各种请求封装:
1 methods:{ 2 send(){ 3 axios({ 4 method:'get', 5 url:'user.jsonaaa' 6 }).then(function(resp){ 7 console.log(resp.data); 8 }).catch(resp => { 9 // console.log(resp); 10 console.log('请求失败:'+resp.status+','+resp.statusText); 11 }); 12 }, 13 sendGet(){ 14 // axios.get('server.php?name=tom&age=23') 15 axios.get('server.php',{ 16 params:{ 17 name:'alice', 18 age:19 19 } 20 }) 21 .then(resp => { 22 console.log(resp.data); 23 }).catch(err => { 24 console.log('请求失败:'+err.status+','+err.statusText); 25 }); 26 }, 27 sendPost(){//post请求传参数的时候,需要改变样式; 28 // axios.post('server.php',{ 29 // name:'alice', 30 // age:19 31 // }) 32 // axios.post('server.php','name=alice&age=20&') //方式1 33 axios.post('server.php',this.user,{ 34 transformRequest:[ 35 function(data){ 36 let params=''; 37 for(let index in data){ 38 params+=index+'='+data[index]+'&'; 39 } 40 return params; 41 } 42 ] 43 }) 44 .then(resp => { 45 console.log(resp.data); 46 }).catch(err => { 47 console.log('请求失败:'+err.status+','+err.statusText); 48 }); 49 }, 50 getUserById(uid){ 51 axios.get(`https://api.github.com/users/${uid}`) 52 .then(resp => { 53 // console.log(resp.data); 54 this.user=resp.data; 55 }); 56 }, 57 sendJSONP(){ 58 //https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word=a 59 this.$http.jsonp('https://sug.so.360.cn/suggest',{ 60 params:{ 61 word:'a' 62 } 63 }).then(resp => { 64 console.log(resp.data.s); 65 }); 66 }, 67 sendJSONP2(){ 68 //https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&json=1&p=3&sid=1420_21118_17001_21931_23632_22072&req=2&csor=1&cb=jQuery110208075694879886905_1498805938134&_=1498805938138 69 this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{ 70 params:{ 71 wd:'a' 72 }, 73 jsonp:'cb' //百度使用的jsonp参数名为cb,所以需要修改 74 }).then(resp => { 75 console.log(resp.data.s); 76 }); 77 } 78 }
组件的生命周期:
1 beforeCreate(){ 2 alert('组件实例刚刚创建,还未进行数据观测和事件配置'); 3 }, 4 created(){ //常用!!! 5 alert('实例已经创建完成,并且已经进行数据观测和事件配置'); 6 }, 7 beforeMount(){ 8 alert('模板编译之前,还没挂载'); 9 }, 10 mounted(){ //常用!!! 11 alert('模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示'); 12 }, 13 beforeUpdate(){ 14 alert('组件更新之前'); 15 }, 16 updated(){ 17 alert('组件更新之后'); 18 }, 19 beforeDestroy(){ 20 alert('组件销毁之前'); 21 }, 22 destroyed(){ 23 alert('组件销毁之后'); 24 }
vue的属性:
1 /*var vm=new Vue({ 2 // el:'#itany', 3 data:{ 4 msg:'welcome to itany' 5 }, 6 name:'tom', 7 age:24, 8 show:function(){ 9 console.log('show'); 10 } 11 });*/ 12 13 /** 14 * 属性 15 */ 16 //vm.属性名 获取data中的属性 17 // console.log(vm.msg); 18 19 //vm.$el 获取vue实例关联的元素 20 // console.log(vm.$el); //DOM对象 21 // vm.$el.style.color='red'; 22 23 //vm.$data //获取数据对象data 24 // console.log(vm.$data); 25 // console.log(vm.$data.msg); 26 27 //vm.$options //获取自定义属性 28 // console.log(vm.$options.name); 29 // console.log(vm.$options.age); 30 // vm.$options.show(); 31 32 //vm.$refs 获取所有添加ref属性的元素 33 // console.log(vm.$refs); 34 // console.log(vm.$refs.hello); //DOM对象 35 // vm.$refs.hello.style.color='blue';
// this.$set(this.user,'age',18); //通过vue实例的$set方法为对象添加属性,可以实时监视
局部属性watch:
1 watch:{ //方式2:使用vue实例提供的watch选项 2 age:(newValue,oldValue) => { 3 console.log('age被修改啦,原值:'+oldValue+',新值:'+newValue); 4 }, 5 user:{ 6 handler:(newValue,oldValue) => { 7 console.log('user被修改啦,原值:'+oldValue.name+',新值:'+newValue.name); 8 }, 9 deep:true //深度监视,当对象中的属性发生变化时也会监视 10 } 11 }
全局watch:
1 //方式1:使用vue实例提供的$watch()方法 2 vm.$watch('name',function(newValue,oldValue){ 3 console.log('name被修改啦,原值:'+oldValue+',新值:'+newValue); 4 });
父子组件之间的数据传递:
<body> <div id="itany"> <my-hello></my-hello> </div> <template id="hello"> <div> <h3>我是hello父组件</h3> <h3>访问自己的数据:{{msg}},{{name}},{{age}},{{user.username}}</h3> <h3>访问子组件的数据:{{sex}},{{height}}</h3> <hr> <my-world :message="msg" :name="name" :age="age" @e-world="getData"></my-world> </div> </template> <template id="world"> <div> <h4>我是world子组件</h4> <h4>访问父组件中的数据:{{message}},{{name}},{{age}},{{user.username}}</h4> <h4>访问自己的数据:{{sex}},{{height}}</h4> <button @click="send">将子组件的数据向上传递给父组件</button> </div> </template> <script> var vm=new Vue({ //根组件 el:'#itany', components:{ 'my-hello':{ //父组件 methods:{ getData(sex,height){ this.sex=sex; this.height=height; } }, data(){ return { msg:'网博', name:'tom', age:23, user:{id:9527,username:'唐伯虎'}, sex:'', height:'' } }, template:'#hello', components:{ 'my-world':{ //子组件 data(){ return { sex:'male', height:180.5 } }, template:'#world', // props:['message','name','age','user'] //简单的字符串数组 props:{ //也可以是对象,允许配置高级设置,如类型判断、数据校验、设置默认值 message:String, name:{ type:String, required:true }, age:{ type:Number, default:18, validator:function(value){ return value>=0; } }, user:{ type:Object, default:function(){ //对象或数组的默认值必须使用函数的形式来返回 return {id:3306,username:'秋香'}; } } }, methods:{ send(){ // console.log(this); //此处的this表示当前子组件实例 this.$emit('e-world',this.sex,this.height); //使用$emit()触发一个事件,发送数据 } } } } } } }); </script> </body>
reduce()方法:
1 array.reduce(function(total, currentValue, currentIndex, arr), initialValue) 4 function(total,currentValue, index,arr) 必需。用于执行每个数组元素的函数。 7 total 必需。初始值, 或者计算结束后的返回值。 8 currentValue 必需。当前元素 9 currentIndex 可选。当前元素的索引 10 arr 可选。当前元素所属的数组对象。 11 initialValue 可选。传递给函数的初始值
购物车代码:
1 <body> 2 <div id="app" class="container"> 3 <h2 class="text-center">购物车</h2> 4 <table class="table table-bordered table-hover table-condensed"> 5 <thead> 6 <tr> 7 <th class="text-center">商品编号</th> 8 <th class="text-center">商品名称</th> 9 <th class="text-center">购买数量</th> 10 <th class="text-center">商品单价</th> 11 <th class="text-center">商品总价</th> 12 <th class="text-center">操作</th> 13 </tr> 14 </thead> 15 <tbody> 16 <tr v-for="(item,index) in commodities" class="text-center"> 17 <td>{{item.id}}</td> 18 <td>{{item.name}}</td> 19 <td> 20 <button class="btn btn-primary" @click="subtract(index)">-</button> 21 <input type="text" v-model="item.quantity"> 22 <button class="btn btn-primary" @click="add(index)">+</button> 23 </td> 24 <td>{{item.price | filterMoney}}</td> 25 <td>{{item.price*item.quantity | filterMoney}}</td> 26 <td> 27 <button class="btn btn-danger" @click="remove(index)">移除</button> 28 </td> 29 </tr> 30 <tr> 31 <td colspan="2">总数量:{{totalNum}}</td> 32 <td colspan="2">总金额:{{totalMoney | filterMoney}}</td> 33 <td colspan="2"> 34 <button class="btn btn-danger" @click="empty()">清空购物车</button> 35 </td> 36 </tr> 37 <tr v-show="commodities.length===0"> 38 <td colspan="6" class="text-center text-muted"> 39 <p>您的购物车空空如也....</p> 40 </td> 41 </tr> 42 </tbody> 43 </table> 44 </div> 45 <script src="js/vue.js"></script> 46 <script> 47 new Vue({ 48 el:'#app', 49 data:{ 50 commodities: [ 51 {id: 1001,name: 'iphone5s',quantity: 3,price: 4000}, 52 {id: 1005,name: 'iphone6',quantity: 9,price: 5000}, 53 {id: 2001,name: 'imac',quantity: 4,price: 7000}, 54 {id: 2004,name: 'ipad',quantity: 5,price: 2000} 55 ] 56 }, 57 computed:{ 58 totalNun:function(){ 59 var sum=0; 60 this.commodities.forEach(function(item){ 61 sum_=item.quantity; 62 }) 63 return sum; 64 }, 65 totalMoney:function(){ 66 return this.commodities.reduce(function(pre,cur,index,array){ 67 return pre+cur.price*cur.quantity 68 },0) 69 }, 70 }, 71 filters:{ 72 filterMoney:function(value){ 73 return '$'+value; 74 } 75 }, 76 methods:{ 77 add:function(index){ 78 this.commodities[index].quantity++ 79 }, 80 substract:function(index){ 81 var item=this.commodies[index]; 82 if(item.quantity==1){ 83 if(confirm(`确定要删除商品:${item.name} 吗?`)){ 84 this.commodities.aplice(index,1); 85 } 86 return; 87 } 88 item.quantity--; 89 }, 90 remove:function(index){ 91 if (confirm(`确定要删除商品:${this.commodities[index].name} 吗?`)) { 92 this.commodities.splice(index, 1) 93 } 94 }, 95 empty:function(){ 96 this.commodities=[]; 97 } 98 } 99 }) 100 </script> 101 </body>
一辈子很短,努力的做好两件事就好;第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;