<style> .v-enter { opacity: 0; } .v-enter-to { opacity: 1; } .v-enter-active { transition: all 2s; } .v-leave { opacity: 1; } .v-leave-to { opacity: 0; } .v-leave-active { transition: all 2s; } </style> <transition> <div class="box" v-show='isShow'></div> </transition>
如果页面中有多个元素需要添加不同的动画,那么只需要给<transition>增加name属性,同时把6个样式中的v-替换为name的值。
<style> .aa-enter { opacity: 0; } .aa-enter-to { opacity: 1; } .aa-enter-active { transition: all 5s; } .aa-leave { opacity: 1; } .aa-leave-to { opacity: 0; } .aa-leave-active { transition: all 5s; } </style> <transition name='aa'> <div class="box" v-show='isShow'></div> </transition>
2、动画库
使用:
引入css,给需要添加动画的元素用<transition>包裹起来,然后添加属性 enter-active-class、leave-active-class
<!-- enter-active-class leave-active-class 使用:引入第三库 必须添加基类+效果类名 --> <transition enter-active-class='animate__animated animate__bounce' leave-active-class = 'animate__animated animate__backOutUp' > <div class="box" v-show='isShow'></div> </transition>
3、监听
-浅监听
主要监听基本数据类型
监听的是在data中声明的变量,而且监听的名字不能更改
// 浅监听 :只能监听基础数据类型 name(newVal, oldVal) { console.log(newVal, oldVal) },
-深监听
监听引用数据类型用深监听,只能获取最新的数据,handler名称不能换
非必要情况不要使用,一旦要使用,需要把深监听转换为浅监听
弊端:使用深监听会引起页面的卡顿
obj: { handler(a) { console.log(a) }, deep: true },
百度搜索案例:
百度:http://suggestion.baidu.com/su?cb=callback&wd=123
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <input type="text" v-model='search'> <ul> <li v-for='(item,index) in arr' :key='index'>{{item}}</li> </ul> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> // 跨域;协议,域名,端口号只要有一个不一样就会出现跨域 jsonp解决 // jsonp原理:动态创建script标签,利用src属性进行跨域 // 1.动态创建script标签 // 2.给src赋值 // 3.得到数据渲染页面 // 4.回调函数(请求回来的数据) // http://suggestion.baidu.com/su?cb=aa&wd=%27abc%E2%80%99 let vm = new Vue({ el: '#app', data: { search: '', arr:[],//这是用来存储请求回来的数据 }, methods: { }, watch: { search() { // 1.动态创建script标签 var os = document.createElement('script'); // 2.赋值src os.src = 'http://suggestion.baidu.com/su?cb=aa&wd=' + this.search // 3.添加到页面 document.body.appendChild(os) } } }) // 定义回调函数 function aa(res){ console.log(res) vm.arr = res.s } </script> </html>
- 全局过滤器:vue实例的外部定义,Vue.filter(过滤器名称,回调函数)
- 局部过滤器:vue实例中增加配置项filters, 过滤器名称:function(){过滤操作}
过滤手机号
<div id="app"> <!-- | 叫做管道符 管道符前面是需要过来的属性,过滤器后面是过滤器名称--> {{tel | filterTel}} <!-- 下面的是错误的,因为是局部定义的过滤器 --> {{tel | filTel}} </div> <script> // 全局过滤器 Vue.filter(过滤器名称,回调函数) Vue.filter('filterTel',(tel)=>{ return tel.slice(0,3)+'****'+tel.slice(7) }) let vm = new Vue({ el: '#app', data: { tel:'15858589958' }, methods: { }, }) </script>
过滤价格
<div id="app"> 价格:{{price | filterPrice}} </div> <script> // 全局过滤器 Vue.filter(过滤器名称,回调函数) Vue.filter('filterPrice',(price)=>{ return price.toFixed(2) }) let vm = new Vue({ el: '#app', data: { price:29 }, methods: { }, }) </script>
过滤时间
<script> <div id="app"> 时间:{{time | filterPrice}} </div> // 全局过滤器 Vue.filter(过滤器名称,回调函数) Vue.filter('filterPrice',(time)=>{ // 获取当前时间 let data = new Date(time) // 年 let year = data.getFullYear(); // 月 let month= (data.getMonth()+1+'').padStart(2,'0'); // 日 let day = (data.getDate()+'').padStart(2,'0') // 时 let hours = data.getHours() //分 let min= data.getMinutes() // 秒 let sec = data.getSeconds() return `${year}-${month}-${day} ${hours}:${min}:${sec}` }) let vm = new Vue({ el: '#app', data: { // new Date().getTime() 获取当前时间戳 time:1609917028669 }, methods: { }, }) </script>
通过计算得出来的属性叫做计算属性,配置项(computed)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <table border="1" width='500' style="border-collapse: collapse;"> <tr> <th>ID</th> <th>姓名</th> <th>分数</th> <th>操作</th> </tr> <tr v-for='(item,index) in list' :key='item.id'> <td>{{index+1}}</td> <th>{{item.name}}</th> <th> <input type="number" v-model.number='item.score'> </th> <th> <button @click = 'del(index)'>删除</button> </th> </tr> <tr> <td>平均分</td> <td colspan="3">{{avg}}</td> </tr> </table> <button @click = 'add'>点击添加</button> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let vm = new Vue({ el: '#app', data: { list:[ { id:1, name:'张三', score:90 }, { id:2, name:'李四', score:80 }, { id:3, name:'王五', score:70 }, { id:4, name:'赵六', score:60 } ] }, methods: { // 删除数据 del(index){ this.list.splice(index,1) }, // 添加操作 add(){ this.list.push({ name:'小明', score:40 }) } }, // 计算属性 computed:{ avg(){ // 获取和 除以长度 var sum = 0; this.list.forEach(item=>{ sum+=item.score }) return (sum/this.list.length).toFixed(2) } } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div id="app" class="container"> <h3>购物车</h3> <table class="table table-bordered table-hover"> <tr> <th> <input type="checkbox" @change='checkAll' v-model='checkAlled'>全选 </th> <th>商品名称</th> <th>商品单价</th> <th>商品数量</th> <th>小计</th> <th>操作</th> </tr> <tr v-for='(item,index) in list' :key='index'> <th> <input type="checkbox" v-model='item.checked' @change='checkOne(index)'> </th> <th>{{item.name}}</th> <th>{{item.price}}</th> <th> <button class="btn btn-primary" @click = 'cut(index)'>-</button> {{item.num}} <button class="btn btn-warning" @click = 'add(index)'>+</button> </th> <th>{{item.num*item.price}}</th> <th> <button class="btn btn-danger" @click = 'del(index)'>删除</button> </th> </tr> <tr> <td>总计</td> <td colspan="5">{{total}}</td> </tr> </table> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let vm = new Vue({ el:'#app', data:{ // 全选初始状态 checkAlled:false, list:[ { name:'冰箱', price:1000, num:1, checked:false }, { name:'空调', price:2000, num:1, checked:true }, { name:'洗衣机', price:1800, num:1, checked:false },{ name:'热水器', price:1200, num:1, checked:false } ,{ name:'电饭煲', price:800, num:1, checked:false } ] }, methods: { del(index){ this.list.splice(index,1) }, // 减少 cut(index){ this.list[index].num-- if( this.list[index].num<0){ this.list[index].num=0 } }, // 增加 add(index){ this.list[index].num++ }, // 全选 checkAll(){ console.log(this.checkAll) this.list.forEach(item=>{ item.checked =this.checkAlled }) }, // 单选 checkOne(index){ this.checkAlled=this.list.every(item=>{ return item.checked }) } }, computed:{ total(){ // 定义存储总数 sum var sum=0; this.list.forEach(item=>{ if(item.checked){ sum+=item.num*item.price } }) return sum } } }) // 注意点:定义属性名和方法名不用一样 // change:直接修改checkbox的值 </script> </html>
面试题:
1、watch与computed的区别?
- watch:函数不需要调用
- computed:调用的时候不需要添加()
处理场景:
- watch:一个数据影响多个数据
- computed:一个数据受多个数据影响
- watch:属于监听,监听数据的改变
- computed:通过计算得到的属性
2、watch与methods区别?
- watch:是观察动作,自定执行
- methods:是方法,需要调用
posted on
浙公网安备 33010602011771号