过滤器
- 自定义私有过滤器
可以在 new Vue({filters:{}})中的filters中注册一个私有过滤器
定义格式:
new Vue({
el:'#app',
filters:{
'过滤器名称':function(管道符号|左边参数的值,参数1,参数2,....) {
return 对管道符号|左边参数的值做处理以后的值
})
}
});
Vue1.0 使用写法:
<span>{{ msg | 过滤器id '参数1' '参数2' .... }}</span>
Vue2.0 使用写法:
<span>{{ msg | 过滤器id('参数1' '参数2' ....) }}</span>
- 自定义全局过滤器
可以用全局方法 Vue.filter() 注册一个全局自定义过滤器,它接收两个参数:过滤器 ID 和过滤器函数。过滤器函数以值为参数,返回转换后的值
定义格式:
Vue.filter('过滤器名称', function (管道符号|左边参数的值,其他参数1,其他参数2,....) {
return 对管道符号|左边参数的值做处理以后的值
})
Vue1.0 使用:
<span>{{ msg | 过滤器名称 '参数1' '参数2' .... }}</span>
Vue2.0 使用:
<span>{{ msg | 过滤器名称('参数1' '参数2' ....) }}</span>
注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
数组处理
- 在 Vue 中,直接修改对象属性的值无法触发响应式。当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变
动态数组响应式数据
Vue.set(vm.items,indexOfItem,newValue);
vm.$set(vm.items,indexOfItem,newValue);
- 参数一--------要处理的数组;
- 参数二--------要处理的数组的索引(如果是对象表示要处理的对象的属性名)
- 参数三--------新的值
按键修饰符
在监听键盘事件时,我们经常需要监测常见的键值。 Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
<!-- -当点击enter 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<!--当点击enter或者space时 时调用 `vm.alertMe()` -->
<input type="text" v-on:keyup.enter.space="alertMe" >
.enter
.tab
.delete (捕获 “删除” 和 “退格” 键)
.esc
.space
.up
.down
.left
.right
1.0.8+ 支持单字母按键别名
在Vue2.0 中默认的按键修饰符是存储在 Vue.config.keyCodes中
// 例如在Vue2.0版本中扩展一个f1的按键修饰符写法:
Vue.config.keyCodes.f1 = 112
在1.0.17+ 中默认的按键修饰符是存储在Vue.directive('on').keyCodes中
// 例如在Vue1.0中扩展一个f1的按键修饰符写法:
Vue.directive('on').keyCodes.f1 = 112
自定义全局指令
定义指令:
//不需要增加v-前缀
Vue.directive('指令名称',{
inserted:function(el,binding){
el //代表使用这个指令的元素对象
binding //一个对象,包含指令名称,指令绑定的值等信息
}
});
//使用指令(当做一个元素的属性使用):指令名称前必须加上V-前缀
<input type="text" v-指令ID />
定义指令:
//定义一个 v-focus的属性自定义指令
Vue.directive('focus',{
inserted:function(el,binding){
el.focus(); //实现文本框的自动获取焦点
console.log(binding.value) //打印hello
}
});
使用指令:
<input type="text" v-focus="'hello'" />
自定义私有指令
定义私有指令:
//不需要增加v-前缀
directives:{
'指令名称':{
bind:function(el,binding){
el.style.color = binding.value;
}
}
}
//使用指令(当做一个元素的属性使用):指令名称前必须加上V-前缀
<input type="text" v-指令ID />
定义指令:
//定义一个 v-focus的属性自定义指令
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
使用指令:
<input type="text" v-focus />
函数简写
'font-weight': function (el, binding) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
el.style.fontWeight = binding.value;
}
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置(和样式有关的操作可以在bind中初始化)。
inserted:被绑定元素插入父节点时调用,触发一次 (仅保证父节点存在,但不一定已被插入文档中)(和js行为有关的操作最好的inserted中执行)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 ,可能会触发多次。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
指令钩子函数会被传入以下参数:
el:指令所绑定的元素,是一个原生的js对象(DOM对象)可以用来直接操作 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 钩子中可用。
计算属性
- 模板中放入太多的逻辑会让模板过重且难以维护 使用计算属性可以让模板更加的简洁
- 计算属性是基于它们的响应式依赖进行缓存的
- computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
<div id="app">
<span>{{reverse}}</span>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: 'hello'
},
//定义计算属性
computed: {
//方法中必须要返回数据,否则调用reverse时拿不到数据
//计算属性是基于它们的响应式依赖进行缓存的,当msg的值没有变化时,调用reverse不会重新进行计算取值,而是会在缓存中之前取计算好的值,不像方法每次都要重新计算,节省性能
reverse: function () {
return this.msg.split('').reverse().join('');
}
},
});
</script>
侦听器
- 使用watch来响应数据的变化
- 一般用于异步或者开销较大的操作
- watch 中的属性 一定是data 中 已经存在的数据
- 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听
<div id="app">
用户名:<input type="text" v-model.lazy="uname">
<span>{{tip}}</span>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
uname: '',
tip: ''
},
methods: {
checkName: function () {
setTimeout(() => {
if (this.uname == 'admin') {
this.tip = '用户名已存在';
} else {
this.tip = '验证通过';
}
}, 2000);
}
},
watch: {
uname: function () {
this.checkName();
this.tip = '验证中...';
}
},
});
过渡 & 动画
概述
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:
- 在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
CSS 过渡
过渡的类名
在进入/离开的过渡中,会有 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 被删除),在过渡/动画完成之后移除。
可以在transition元素中定义name属性,修改v-前缀,定义不同的动画.
<style>
.show-enter,
.show-leave-to {
padding-left: 100px;
}
.show-enter-active,
.show-leave-active {
transition: all 3s ease;
}
.show-enter-to,
.show-leave {
padding-left: 0px;
}
</style>
<div id="app">
<button @click="toggle">隐藏/显示</button><br>
//1.使用<transition>元素将需要被动画控制的元素包裹起来
<transition name="show">
<span v-if="isShow">hello vue</span>
</transition>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
isShow: false
},
methods: {
toggle: function () {
this.isShow = !this.isShow;
}
}
});
</script>
CSS 动画
自定义过渡的类名
enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)
<!-- 引入css动画 -->
<link rel="stylesheet" href="animate.css">
<div id="app">
<button @click="toggle">隐藏/显示</button><br>
<transition name="show"
<!-- 设置进入的动画 -->
enter-active-class="animated tada"
<!-- 设置离开的动画 -->
leave-active-class="animated bounceOutRight"
//必须要先设置animated,再设置动画名称,或者可以在元素中直接设置class="animated"
//设置动画的时间,可以通过设置transition的:duration分别设置进入和离开的时间:duration="{enter:200,leave:400}"
:duration="200">
<div style="width: 400px" v-if="isShow">hello vue</div>
</transition>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
isShow: false
},
methods: {
toggle: function () {
this.isShow = !this.isShow;
}
}
});
</script>
动画钩子函数
1、过渡动画进入
before-enter 过渡动画进入之前,一般在这个方法中定义目标元素的初始位置
enter 过渡动画进入中,在这个方法中定义目标元素的结束位置
after-enter 过渡动画结束后,通常在这个方法里面重置初始值
enter-cancelled 取消过渡动画时被调用
2、过渡动画离开
before-leave 动画离开之前触发
leave 过渡动画进入中触发
after-leave 过渡动画离开结束后
leave-cancelled 取消过渡动画时被调用
在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"
>
<!-- ... -->
</transition>
在Vue实例的methods中设置函数
methods: {
// --------
// 进入中
// --------
//el:动画要操作的DOM对象
beforeEnter: function (el) {// 动画进入之前的回调函数
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function (el, done) {// 动画进入完成时候的回调函数
// ...
done()//done()实际上调用的就是afterEnter()
},
afterEnter: function (el) {// 动画进入完成之后的回调函数
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
列表过渡动画
<style>
li {
border: 1px dashed black;
margin: 5px;
padding: 10px;
width: 100%;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateY(50px);
}
.v-enter-active,
.v-leave-active {
transition: all 1s ease;
}
//v-move特性会在元素改变定位的过程中产生作用,和v-leave-active配合使用可以让列表的过渡更加平缓柔和
.v-move {
transition: all 1s ease;
}
.v-leave-active {
position: absolute;
}
</style>
<div id="app">
<div>
<label for="">
ID:
<input type="text" v-model="id">
</label>
<label for="">
姓名:
<input type="text" v-model="name">
</label>
<input type="button" value="添加" @click="add">
</div>
//v-for循环的列表需要使用<transition-group>包裹才能实现过渡效果
//appear属性让整个列表在页面加载时有一个入场的过渡效果
//tag属性表示让transition-group最终在页面中渲染成哪一种标签,默认为span
<transition-group appear tag="ul">
//必须配置:key属性
<li v-for="(item,index) in list" :key="item.id" @click="del(index)">
{{item.id}} -- {{item.name}}
</li>
</transition-group>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
id: "",
name: "",
list: [{
id: 1,
name: "关羽"
},
{
id: 2,
name: "刘备"
},
{
id: 3,
name: "张飞"
},
{
id: 4,
name: "赵云"
}
]
},
methods: {
add: function () {
this.list.push({id: this.id,name: this.name
});
},
del: function (index) {
this.list.splice(index, 1);
}
},
});
</script>