过渡其实就是一个淡入淡出的效果。Vue在元素显示与隐藏的过渡中,提供了 6 个 class 来切换:
<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>
// ...
methods: {
beforeEnter: function (el) {
},
enter: function (el, done) {
},
afterEnter: function (el) {
},
enterCancelled: function (el) {
},
beforeLeave: function (el) {
},
leave: function (el, done) {
},
afterLeave: function (el) {
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
}
}
已经写了一个综合的案例了,若拆开可能对这部分内容还是不明白,所以直接拿了个完整的案例来学习:
例子(来源):
<div id = "databinding">
<button v-on:click = "show = !show">点我</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show">菜鸟教程 -- 学的不仅是技术,更是梦想!!!</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
el: '#databinding',
data: {
show: false
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'left'
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
Velocity(el, { fontSize: '1em' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
})
</script>
这个案例虽然很小,但仔细看看还是能学到很多知识的:
源代码:
<!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>
<style>
#app {
width: 600px;
margin: 10px auto;
}
.tb {
border-collapse: collapse;
width: 100%;
}
.tb th {
background-color: #0094ff;
color: white;
}
.tb td,
.tb th {
padding: 5px;
border: 1px solid black;
text-align: center;
}
.add {
padding: 5px;
border: 1px solid black;
margin-bottom: 10px;
}
.del li{
list-style: none;
padding: 10px;
text-align: center;
}
.del{
position: absolute;
top:45%;
left: 45%;
width: 300px;
border: 1px solid rgba(0,0,0,0.1);
transition: all 0.5s;
}
</style>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<div class="add">
编号: <input id="id" v-focus type="text" v-model="id">
品牌名称: <input v-model="name" type="text">
<button @click="add">添加</button>
</div>
<div>
<table class="tb">
<tr>
<th>编号</th>
<th>品牌名称</th>
<th>创立时间</th>
<th>操作</th>
</tr>
<tr v-if="list.length <= 0">
<td colspan="4">没有品牌数据</td>
</tr>
<!--加入: key="index" 时候必须把所有参数写完整 -->
<tr v-for="(item,key,index) in list" :key="index">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.ctime | dateFrm("/")}}</td>
<!-- 使用vue来注册事件时,我们在dom元素中是看不到的 -->
<td><a href="javascript:void(0)" @click="del(item.id)">删除</a></td>
</tr>
</table>
</div>
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter ="afterEnter"
@before-leave="beforeLeave"
@leave="leave"
@after-leave ="afterLeave"
>
<div class="del" v-show="isshow">
<ul>
<li>您确定要删除当前数据吗</li>
<li>
<button @click="delById">确定</button>
<button @click="showClose">关闭</button>
</li>
</ul>
</div>
</transition>
</div>
</body>
</html>
<script>
// 使用全局过滤器(公有过滤器)
Vue.filter("dateFrm", function (time,spliceStr) {
// return "2017-11-16";
var date = new Date(time);
//得到年
var year = date.getFullYear();
// 得到月
var month = date.getMonth() + 1;
// 得到日
var day = date.getDate();
return year + spliceStr + month + spliceStr + day;
});
// 先将自定义指令定义好
// directive有两个参数
//参数一: 自定义指令 v-focus
//参数二: 对象,对象中可以添加很多方法
// 添加一个inserted方法:而这个方法中又有两个参数:
//参数一:el 当前使用自定义指令的对象
//参数二:obj 是指它(v-color="color" )后面设置的表达式
//{expression:"color",value:"red",}
Vue.directive("focus", {
inserted: function (el, obj) {
// console.log(el);
el.focus();
}
});
var vm = new Vue({
el: "#app",
data: {
//delId:"",// 用来将要删除数据的id进行保存
isshow:false,
color: "green",
id: 0,
name: '',
list: [
{ "id": 1, "name": "淘宝", "ctime": Date() },
{ "id": 2, "name": "京东", "ctime": Date() }
]
},
// mounted(){
// this.getFocus()
// },
methods: {
add: function () {
//将id和namepush到list数组中
this.list.push({ "id": this.id, "name": this.name, "ctime": Date() });
},
del: function (id) {
this.isshow = true;
// 将得到的id保存到delId里面
this.delId = id;
},
beforeEnter:function(el) {
el.style.left = "100%";
},
enter:function(el,done) {
el.offsetHeight;
el.style.left = "35%";
},
afterEnter:function(el){
},
beforeLeave:function(el){
el.style.left = "35%";
},
leave:function(el,done){
el.offsetHeight;
el.style.left = "100%";
setTimeout(function(){
done();
},500);
},
afterLeave:function(el){
},
showClose:function(el){
this.isshow = false;
},
delById:function() {
_this = this;
// 根据DelId删除对应的数据
var index = this.list.findIndex(function(item){
return item.id ==_this.delId;
});
this.list.splice(index,1);
// 关闭删除框
this.isshow = false;
}
}
});
</script>
默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。
案例:文本框自动获取焦点即当刷新后光标仍在文本框内,不需要点击文本框就可以输入
<div id="app">
<p>页面载入时,input 元素自动获取焦点:</p>
<input v-focus>
</div>
// // 注册一个全局自定义指令 v-focus
// Vue.directive('focus', {
// // 当绑定元素插入到 DOM 中。
// inserted: function (el) {
// // 聚焦元素
// el.focus()
// }
// })
// // 创建根实例
// new Vue({
// el: '#app'
// })
// 注册一个局部自定义指令 v-focus
new Vue({
el: '#app',
directives: {
// 注册一个局部的自定义指令 v-focus
focus: {
// 指令的定义
inserted: function (el) {
// 聚焦元素
el.focus()
}
}
}
})
钩子函数
指令定义函数提供了几个钩子函数(可选):
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次, 指令与元素解绑时调用。
钩子函数参数
钩子函数的参数有:
el: 指令所绑定的元素,可以用来直接操作 DOM 。
binding: 一个对象,包含以下属性:
name: 指令名,不包括 v- 前缀。
value: 指令的绑定值, 例如: v-my-directive=“1 + 1”, value 的值是 2。
oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression: 绑定值的表达式或变量名。 例如 v-my-directive=“1 + 1” , expression 的值是 “1 + 1”。
arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”。
modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
vnode: Vue 编译生成的虚拟节点。
oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
钩子函数案例:
<!-- 钩子函数参数的应用 -->
<div id="app1" v-red:hello.age.big="message">
</div>
//创建指令v-red
Vue.directive('red', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '
' +
'value: ' + s(binding.value) + '
' +
'expression: ' + s(binding.expression) + '
' +
'argument: ' + s(binding.arg) + '
' +
'modifiers: ' + s(binding.modifiers) + '
' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app1',
data: {
message: '清风无虑skr'
}
})
总结:由于时间原因今天的许多文本介绍都是在官网的介绍,我就不再详细的介绍了,案例也没写太多,后面我将写一个关于vue过渡动画以及自定义指令的综合案例,到时候再和大家详细分享下。