Vue - day2
day2
自定义指令
Vue.directive('指令id',{
bind:function(el,binding){} // 指令绑定到元素上,调用,只执行一次 (样式有关的操作)
inserted:function(el,binding){} // 被绑定元素插入父节点时调用,触发一次 (行为有关的操作)
updated:function(el,binding){} // 当Vnode(组件)更新的时候,调用,触发多次
})
参数说明
1.指令id可由程序员自行定义,注意和系统指令名称有所区别,例如:
focus,在某个元素上具体使用的时候请在 指令id前面再加上v-,例如 <input v-focus>
2.第二个参数是一个对象,一个指令定义对象可以提供如下几个钩子函数 (均为可选):
-
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
-
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
-
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
钩子函数参数:
- el:指令所绑定的元素,可以用来直接操作 DOM 。
- binding:一个对象,包含以下属性:
- 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 钩子中可用。
Ps:自定义私有指令 directives vue中私有的带
s
,全局的不带
函数简写
在很多时候,你可能想在 bind
和 update
时触发相同行为,而不关心其它的钩子。比如这样写:
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
ref
ref的作用类似于document.getElementByID,在vue中想要获取一个dom对象或者组件对象,则只需要 在此元素上添加一个 ref="自定义名称" ,再使用 this.$refs.自定义名称即可获取
过滤器
- "2018-01-25T02:10:02.945Z" => 2018-01-25
- 概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。
- 过滤器只可以用在两个地方:mustache 插值和 v-bind 表达式。
- 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;
一.私有过滤器
- 定义方式
可以在 new Vue({filters:{}})中的 filters 中注册一个私有过滤器
定义格式:
new Vue({
el:'#app',
filters:{
'过滤器名称':function(管道符号|左边对象的值,参数1,参数2,....) {
return 处理以后的值
})
}
});
Vue2.0 调用过滤器传参写法:
<span>{{ msg | 过滤器名称('参数1','参数2' ....) }}</span>
- (应用示例)自定义私有过滤器实现日期格式化
1、 定义私有的日期格式化过滤器:
new Vue({
el:'#app',
data:{
time:new Date()
},
filters:{
//定义在 VM中的filters对象中的所有过滤器都是私有过滤器
datefmt:function(input,splicchar){
var date = new Date(input);
var year = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
var fmtStr = year+splicchar+m +splicchar+d;
return fmtStr; //返回输出结果
}
}
});
2、使用
<div id="app">
{{ time | datefmt('-') }} //Vue2.0传参写法
</div>
二.全局过滤器
-
定义全局过滤器的语法
Vue.filter('过滤器的名称', function(originVal){ /* 对数据进行处理的过程,在这个 function 中,最后必须 return 一个处理的结果 */ return 一个处理的结果 })
-
使用全局过滤器的语法
<span>{{ dt | 过滤器名称('参数1','参数2' ....) }}</span>
-
使用过滤器的注意事项:
- 如果想拿管道符前面的值,通过 function 的第一个形参来拿
- 过滤器中,一定要返回一个处理的结果,否则就是一个无效的过滤器
- 在调用过滤器的时候,直接通过 () 调用就能传参; 从过滤器处理函数的第二个形参开始接收传递过来的参数
- 可以 多次 使用
|
管道符 一次调用多个过滤器
vue实例的生命周期
什么是生命周期(每个实例的一辈子)
概念:每一个Vue实例创建、运行、销毁的过程,就是生命周期;在实例的生命周期中,总是伴随着各种事件,这些事件就是生命周期函数;
生命周期钩子:就是生命周期事件的别名而已;
生命周期钩子 = 生命周期函数 = 生命周期事件
主要的生命周期函数分类
- 创建期间的生命周期函数:(特点:每个实例一辈子只执行一次)
- beforeCreate:创建之前,此时 data 和 methods 尚未初始化
- created(第一个重要的函数,此时,data 和 methods 已经创建好了,可以被访问了)
- beforeMount:挂载模板结构之前,此时,页面还没有被渲染到浏览器中;
- mounted(第二个重要的函数,此时,页面刚刚被渲染出来;如果要操作DOM元素,最好在这个阶段)
- 运行期间的生命周期函数:(特点:按需被调用 至少0次,最多N次)
- beforeUpdate:数据是最新的,页面是旧的
- updated:页面和数据都是最新的
- 销毁期间的生命周期函数:(特点:每个实例一辈子只执行一次)
- beforeDestroy:销毁之前,实例还正常可用
- destroyed:销毁之后,实例已经不工作了
不要在选项属性或回调上使用箭头函数,因为箭头函数是和父级上下文绑定在一起的,this 不会是如你所预期的 Vue 实例,经常导致
Uncaught TypeError: Cannot read property of undefined
或Uncaught TypeError: this.myMethod is not a function
之类的错误。
computed
计算属性出现的目的是解决模板中放入过多的逻辑会让模板过重且难以维护的问题;计算属性是基于它们的依赖进行缓存的
computed: {
fullName: function () {
console.log(this.firstName + this.lastName)
return this.firstName + this.lastName
}
}
watch
侦听器(watch)用来观察和响应 Vue 实例上的数据变动
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
注意:通常情况下用computed,当需要在数据变化时执行异步或开销较大的操作时,用watch
数组的新方法
- forEach
- some
- filter
- findIndex
字符串方法(ES6)
- includes('包含的字符串') -> 包含返回: true 否则返回: false
axios(基于 promise 的 HTTP 库)
-
之前的学习中,如何发起数据请求?
- 最开始自己 new XHR
- 使用Jquery中提供的工具函数 .post(url地址, function(){}), $.get(url地址, 处理函数)
- axios发起请求;只支持get和post请求,无法发起JSONP请求;如果涉及到 JSONP请求,可以让后端启用 cors 跨域资源共享即可;
-
常见的数据请求类型?
- get请求
- post请求
- jsonp请求
-
在Vue中,可以使用vue-resource或axios发起数据请求
- vue-resource(一个使用 XMLHttpRequest 或者 JSONP处理请求的vue插件)支持 get, post, jsonp请求【官方不推荐使用!】
- 使用
axios.get()
和axios.post()
发起请求
get请求示例
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 或者
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
post请求示例
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
过渡和动画
概述
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:
- 在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
单元素/组件的过渡
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
- 条件渲染 (使用 v-if)
- 条件展示 (使用 v-show)
- 动态组件
- 组件根节点
当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:
-
自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
-
如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
-
如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)
过渡的类名
在进入/离开的过渡中,会有 6 个 class 切换。
-
v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
-
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
-
v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
-
v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
-
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
-
v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
1.transition结合css实现过渡
1.把需要添加动画的元素,使用v-if或v-show进行控制
2.把需要添加动画的元素,使用Vue提供的元素 <transition></transition>
包裹起来
3.添加两组类:
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(100px);
}
.v-enter-active,
.v-leave-active{
transition: all 0.5s ease;
}
<transition name='my'></transition>
自定义v-
为my-
2.transition结合animate.css实现过渡
<!-- 引入animate.css文件 -->
<link rel="stylesheet" href="./animate.css">
<!-- 2.0 在想要进行动画的元素上使用 <transition>组件包住
transition:
在transition 这个标签中有两个属性:
1. enter-active-class:控制动画的进入
2. leave-active-class:控制动画的离开
上面两个属性中的值写法注意点:
1. 两个属性中均要编写 animate.css中定义好的一个类 animated
2. 在两个属性中分别取animate.css中控制的动画样式即可(按需获取)
-->
<transition
enter-active-class="animated fadeInRight"
leave-active-class="animated fadeOutRight"
>
<span v-if="isshow">hello 黑马</span>
</transition>
// 或者
<transition
enter-active-class="fadeInRight"
leave-active-class="fadeOutRight"
:duration='200' //:duration='{ enter:200, leave:200 }'分别设置入场,离场的时间为 200ms
>
<span v-if="isshow" class='animated'>hello 黑马</span>
</transition>
3.JavaScript 钩子函数实现动画
-
过渡动画进入
- before-enter 过渡动画进入之前,一般在这个方法中定义目标元素的初始位置
- enter 过渡动画进入中,在这个方法中定义目标元素的结束位置
- after-enter 过渡动画结束后,通常在这个方法里面重置初始值
- enter-cancelled 取消过渡动画时被调用
-
过渡动画离开
- before-leave 动画离开之前触发
- leave 过渡动画进入中触发
- after-leave 过渡动画离开结束后
- leave-cancelled 取消过渡动画时被调用
可以在属性中声明 JavaScript 钩子
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-bind:css="false"
>
<!-- ... -->
</transition>
.
// ...
methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// el: 原生 DOM 对象
// ...
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
enter: function (el, done) {
// 这句话没有实际作用,不写,动画不出效果
// 可以认为`el.offsetWidth` 会强制动画刷新
el.offsetWidth
// ...
done() // done其实就是afterEnter这个函数的引用,可以立即完成过渡
},
afterEnter: function (el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// ...
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
}
}
注意:
- 当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
- 推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
- 钩子函数 可以实现半场动画,前两种不可以实现
使用 transition-group 实现列表动画
-
在实现列表过渡的时候, 如果需要过渡的元素, 是通过
v-for
循环渲染出来的, 不能使用transition
包裹, 需要使用transitionGroup
-
要为
v-for
创建的元素设置动画, 必须为每一个 元素 设置 :key 属性
css
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(100px);
}
.v-enter-active,
.v-leave-active{
transition: all 0.5s ease;
}
页面
<transition-group tag="ul" name="">
<li v-for="(item,index) in list" :key='index'> {{item.name}} </li>
</transition-group>
<transition-group appear> 添加
appear
属性, 实现页面刚展示出来时候,入场效果
<transition-group tag="ul"> 设置
tag
属性, 指定transition-group
渲染为指定元素,默认为span
标签
实现列表删除动画效果
下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续元素, 渐变效果
.v-move {
transition: all 0.5s ease;
}
.v-leave-active{
position: absolute;
}
^_^