vue实现简单动画小案例(详解)

过渡

过渡其实就是一个淡入淡出的效果。Vue在元素显示与隐藏的过渡中,提供了 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 被删除),在过渡/动画完成之后移除。

JavaScript 钩子

<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过渡动画以及自定义指令的综合案例,到时候再和大家详细分享下。

你可能感兴趣的:(vue,vue,javascript,前端,vue.js)