2020.7.12:Array:forEach some filter findIndex includes、String:includes replace padStart padEnd、Vue.filter、vue按键修饰符、vue.directive钩子函数、bind和updata函数缩写、Vue-source使用、Vue生命周期、过渡动画和animate.css动画、钩子函数动画、列表动画
# 今日学习内容
## forEach some filter findIndex includes 这些都属于数组的新方法
1. forEach 遍历数组
arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
2. some:返回布尔值
arr.some(callback(element[, index[, array]])[, thisArg])
3. filter:如果没找到,则返回 -1,过滤
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
4. finIndex:返回索引,否则返回 -1
arr.findIndex(callback[, thisArg])
5. includes:返回布尔值,表示包含
arr.includes(valueToFind[, fromIndex])
## String includes replace padStart padEnd 方法
1. includes:返回布尔值,表示包含
str.includes(searchString[, position])
2. replace:替换字符串参数
str.replace(regexp|substr, newSubStr|function) 被替换的参数(正则 或 字符串),要替换的参数(字符串 或 函数)
3. padStart:补位字符串,添补首位。例如:年月日 2020-07-03 04:05:09 第一位的0
String.prototype.padStart(maxLength, fillString='') 补位的长度,填充的内容
4. padEnd: 补位字符串,添补末位。
String.prototype.padEnd(maxLength, fillString='') 补位的长度,填充的内容
## Vue.filter 的使用
过滤器调用时候的格式 {{name | 过滤器的名称}} 注意:过滤器可以多次调用

<td>{{ item.ctime | dataFormat() }}</td> Vue.filter('dataFormat', function (dateStr, pattern="") { // 根据给定的时间字符串,得到特定的时间 var dt = new Date(dateStr); var y = dt.getFullYear(); var m = dt.getMonth(); var d = dt.getDate(); // return y + '-' + m + '-' + d; // return `${y}-${m}-${d}`; if (pattern.toLowerCase() === 'yyyy-mm-dd') { return `${y}-${m}-${d}`; } else { var hh = dt.getHours(); var mm = dt.getMinutes(); var ss = dt.getSeconds(); return `${y}-${m}-${d} ${hh}:${mm}:${ss}`; } })
## Vue 按键修饰符:@keyup.enter="add";

1. 自带的: .enter .tab .delete .esc .space .up .down .left .right @keyup.enter="add"; 2. 自定义: Vue.config.keyCodes.f2 = 113; @keyup.f2="add";
## Vue.directive (指令) 的使用 自定义属性

1 Vue.directive('focus', { 2 bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次 3 // 注意:在每个函数中,第一个参数,永远是 el ,表示被绑定了指令的那个元素,这个 el 参数是一个原生的 js 对象 4 // 在元素 刚绑定了指令的时候,还没有插入到 DOM 中去,这时候,调用 focus 方法没有作用 5 // 因为,一个元素,只有插入 DOM 之后,才能获取焦点 6 // el.focus(); 7 }, 8 inserted: function (el) { // inserted 表示元素 插入到 DOM 中的时候,会执行 inserted 函数【触发一次】 9 el.focus(); 10 }, 11 updated: function () { } // 当 vNode 更新的时候,会执行 updated ,可能会触发多次 12 }); 13 14 15 v-focus 16 17 18 钩子函数 19 一个指令定义对象可以提供如下几个钩子函数 (均为可选): 20 21 bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 22 23 inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 24 25 update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 26 27 我们会在稍后讨论渲染函数时介绍更多 VNodes 的细节。 28 29 componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 30 31 unbind:只调用一次,指令与元素解绑时调用。 32 33 接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

钩子函数参数 指令钩子函数会被传入以下参数: el:指令所绑定的元素,可以用来直接操作 DOM。 binding:一个对象,包含以下 property: name:指令名,不包括 v- 前缀。 value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。 oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。 expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。 arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。 modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。 vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。 oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。 除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。
### bind 和 update 函数简写

在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写: Vue.directive('color-swatch', function (el, binding) { el.style.backgroundColor = binding.value })
## Vue-source 的使用:现在推荐使用 axios

<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script> methods: { getInfo() { // 发起 get 请求 // 当发起 get 请求之后,通过 .then 来设置成功的回调函数 this.$http.get('https://autumnfish.cn/api/joke/list?num=6') .then(function (result) { // 通过 result.body 拿到服务器返回的成功的数据 console.log(result.data); }) }, postInfo() { // 发起 post 请求 application/x-wwww-form-urlencoded // 手动发起的 post 请求,默认没有表单格式,所以,有的服务器处理不了 // 通过 post 方法的第三个参数,设置 提交的内容类型 为 普通表单数据格式 this.$http.post('https://autumnfish.cn/api/user/reg', { emulateJSON: true }, {}).then(result => { console.log(result); }) }, jsonpInfo() { this.$http.jsonp('http://vue.studyit.io/api/jsonp').then(result => { console.log(result.body); }) } },
## Vue 生命周期

1. 创建期间的生命周期函数: 1. beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性 2. created:实例已经在内存中创建 OK ,此时 data 和 methods 已经创建 OK ,此时还没有开始编译模板 3. beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中 4. mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示 2. 运行期间的生命周期函数: 1. beforeUpdate:状态更新之前执行此函数,此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染 DOM 节点 2. updated:实例更新完毕之后调用此函数,此时 data 中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了 3. 销毁期间的生命周期函数: 1. beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用 2. destroyed:Vue 实例销毁后调用。调用后,Vue 实例只是的所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 beforeCrate(){}; created(){}; beforeMount(){}; mount(){}; beforeUpdate(){}; updated(){}; beforeDestroy(){}; destroyed(){};
## Vue 动画历程
### Vue (transition ) 过渡类名动画

<style type="text/css"> /* v-enter [这是一个时间点] 是进入之前,元素的起始状态,此时还没有开始进入 */ /* v-leave-to [这是一个时间点] 是动画离开之后,离开的终止状态,此时,元素 动画已经结束 */ .v-enter, .v-leave-to { opacity: 0; transform: translateX(150px); } /* v-enter-active [入场动画的时间段] */ /* v-leave-active [离场动画的时间段] */ .v-enter-active, .v-leave-active { transition: all 0.8s ease; } </style> <body> <div id="app"> <input type="button" value="toggle" @click="flag=!flag"> <!-- 需求:点击按钮,让 h3 显示,再点击,让 h3 隐藏 --> <!-- 1. 使用 transition 元素,把需要被动画控制的元素,包裹起来 --> <!-- transition 元素,是 Vue 官方提供的 --> <transition> <h3 v-show="flag">这是一个h3</h3> </transition> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: "#app", data: { flag: false }, methods: { }, }) </script> </body>
### Vue (transition ) 修改v-前缀动画

<style type="text/css"> /* v-enter [这是一个时间点] 是进入之前,元素的起始状态,此时还没有开始进入 */ /* v-leave-to [这是一个时间点] 是动画离开之后,离开的终止状态,此时,元素 动画已经结束 */ .v-enter, .v-leave-to { opacity: 0; transform: translateX(150px); } /* v-enter-active [入场动画的时间段] */ /* v-leave-active [离场动画的时间段] */ .v-enter-active, .v-leave-active { transition: all 0.8s ease; } .my-enter, .my-leave-to { opacity: 0; transform: translateY(70px); } .my-enter-active, .my-leave-active { transition: all 0.8s ease; } </style> <body> <div id="app"> <input type="button" value="toggle" @click="flag=!flag"> <!-- 需求:点击按钮,让 h3 显示,再点击,让 h3 隐藏 --> <!-- 1. 使用 transition 元素,把需要被动画控制的元素,包裹起来 --> <!-- transition 元素,是 Vue 官方提供的 --> <transition> <h3 v-show="flag">这是一个h3</h3> </transition> <hr> <input type="button" value="toggle2" @click="flag2=!flag2"> <!-- 需求:点击按钮,让 h3 显示,再点击,让 h3 隐藏 --> <!-- 1. 使用 transition 元素,把需要被动画控制的元素,包裹起来 --> <!-- transition 元素,是 Vue 官方提供的 --> <transition name="my"> <h6 v-show="flag2">这是一个h6</h6> </transition> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: "#app", data: { flag: false, flag2: false }, methods: { }, }) </script> </body>
### Vue + animate.css 的使用:注意:animate.css 3.5.1 支持 Vue,4.0 亲测与 Vue 有兼容性问题,导致 animate 不起作用

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css" /> <body> <div id="app"> <input type="button" value="toggle" @click="flag=!flag"> <!-- 需求:点击按钮,让 h3 显示,再点击,让 h3 隐藏 --> <transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut" :duration="200"> <h3 v-show="flag">这是一个h3</h3> </transition> <!-- <transition enter-active-class="bounceIn" leave-active-class="bounceOut"> <h3 v-show="flag" class="animated">这是一个h3</h3> </transition> --> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: "#app", data: { flag: false }, methods: { }, }) </script> </body>
### Vue (通过 transition 标签的 v-on: 属性)钩子函数模拟小球动画

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script> --> <!-- <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> --> <style type="text/css"> .ball { width: 15px; height: 15px; border-radius: 50%; background-color: red; } </style> </head> <body> <div id="app"> <input type="button" value="加入购物车" @click="flag=!flag"> <!-- 1. 使用 transition 元素把小球包裹起来 --> <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:enter-cancelled="enterCancelled" v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" v-on:leave-cancelled="leaveCancelled"> <div class="ball" v-show="flag"></div> </transition> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: "#app", data: { flag: false }, methods: { // 注意:动画钩子函数的第一个参数:el,表示 要执行动画的那个 DOM 元素,是个原生的 JS 对象 // 大家可以认为 el 是通过 document.getElementById('') 方式获取到的原生 JS DOM 对象 beforeEnter(el) { // beforeEnter 表示动画入场之前,此时,动画尚未开始,可以在 beforeEnter 中,设置元素开始动画之前的起始样式 // 设置小球开始动画之前的,起始位置 el.style.transform = "translate(0,0)"; }, enter(el, done) { // 这句话,没有实际的作用,但是如果不写,出不来动画效果 // 可以认为 el.offsetWidth 会强制动画刷新 el.offsetWidth; // el.offsetHeight; // el.offsetLeft; // el.offsetTop; // enter,表示动画开始之后的样式,这里,可以设置小球完成动画之后的结束状态 el.style.transform = "translate(150px,450px)"; el.style.transition = 'all 1s ease '; // 这里的 done ,其实就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用 done(); }, afterEnter(el) { // 动画完成之后,会调用 afterEnter // console.log('ok'); this.flag = !this.flag; }, enterCancelled(el) { }, beforeLeave(el) { }, leave(el) { }, afterLeave(el) { }, leaveCancelled(el) { }, }, }) </script> </body> </html>
### Vue 列表动画:通过 transitionGroup 标签

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script> --> <style type="text/css"> li { border: 1px dashed #999; margin: 5px; line-height: 35px; padding-left: 5px; font-size: 12px; width: 100%; } li:hover { background-color: hotpink; transition: all 0.8s ease; } .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } .v-enter-active, .v-leave-active { transition: all 0.6s ease; } /* 下面的 v-move 和 v-leave-active 配合使用,能够实现列表后续的元素,渐渐飘上来的效果 */ .v-move { transition: all 0.6s ease; } .v-leave-active { position: absolute; } </style> </head> <body> <div id="app"> <div> <label> Id: <input type="text" v-model="id"> </label> <label> Name: <input type="text" v-model="name"> </label> <input type="button" value="添加" @click='add'> </div> <!-- <ul> --> <!-- 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用 transitionGroup --> <!-- 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性 --> <!-- 给 transition-group 添加 appear 属性,实现页面刚展示出来的入场时候的效果 --> <!-- 通过为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认渲染为 span 标签 --> <transition-group appear tag="ul"> <li v-for="(item,i) in list" :key="item.id" @click="del(i)"> {{item.id}} --- {{item.name}} </li> </transition-group> <!-- </ul> --> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: "#app", data: { id: '', name: '', list: [ { id: 1, name: '赵高' }, { id: 2, name: '秦桧' }, { id: 3, name: '严嵩' }, { id: 4, name: '魏忠贤' }, ] }, methods: { add() { this.list.push({ id: this.id, name: this.name }); this.id = this.name = ''; }, del(i) { this.list.splice(i, 1); } }, }) </script> </body> </html>