zoukankan      html  css  js  c++  java
  • 第4章:自定义指令与过渡

      五,自定义指令

      分类:全局指令,局部指令

      1.自定义全局指令

      用法

    // 注册
    Vue.directive('my-directive', {
      bind: function () {},
      inserted: function () {},
      update: function () {},
      componentUpdated: function () {},
      unbind: function () {}
    })
    
    // 注册 (指令函数)
    Vue.directive('my-directive', function () {
      // 这里将会被 `bind` 和 `update` 调用
    })
    
    // getter,返回已注册的指令
    var myDirective = Vue.directive('my-directive')
    

      解析:自定义指令允许用户自定义指令,在指令内定义函数分别代表

      bind:指令第一次绑定元素调用,只调用一次可执行初始化操作

      inserted:元素插入DOM时调用

      update:元素更新时调用

      componentUpdated:被绑定元素完成一次更新周期调用

      unbind:元素解绑时调用

      示例day02/08.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>自定义指令</title>
    	<script src="js/vue.js"></script>
    </head>
    <body>
    	<div id="itany">
            // 定义指令使用hello使用的时候需要加前缀v-
            <h3 v-hello>{{msg}}</h3>
            <button @click="change">更新数据</button>
            <!-- <h3 v-world>{{msg}}</h3> -->
        </div>
        <script>
            // 自定义全局指令
            // 使用指令时必须在指令名称前加v-,即v-指令名称
            Vue.directive('hello',{
                bind: function () { // 常用
                    alert('指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
                },
                inserted: function () {
                    alert('被绑定元素插入到DOM时调用');
                },
                update: function () {
                    alert('被绑定元素所在模板更新时调用');
                }, // 下面两个不常用
                componentUpdated: function () {
                    alert('被绑定元素所在模板完成一次更新周期时调用');
                },
                unbind: function () { 
                    alert('指令与元素解绑是调用,只调用一次');
                }
            });
            // 钩子函数的参数
            // Vue.directive('world',{
            //     bind(el,binding){
            //         console.log(el)  // el指令所绑定的元素,DOM对象
            //         el.style.color='red'
            //         console.log(binding)               
            //     }
            // });
    		var vm=new Vue({
    			el:'#itany',
    			data:{  
    				msg:'welcome to itany'
                    },
                methods:{
                    change(){
                        this.msg='欢迎来到南京网博'
                    }
                }
               });
              
    	</script>
    </body>
    </html>
    

      页面显示

     

     

     

     

     

       钩子函数的参数

      指令钩子函数会被传入以下参数

    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 钩子中可用。
    

      示例08.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>自定义指令</title>
    	<script src="js/vue.js"></script>
    </head>
    <body>
    	<div id="itany">
            <!-- 定义指令使用hello使用的时候需要加前缀v- -->
            <!-- <h3 v-hello>{{msg}}</h3> -->
            <button @click="change">更新数据</button>
            <h3 v-world="name">{{msg}}</h3>
        </div>
        <script>
            // 自定义全局指令
            // 使用指令时必须在指令名称前加v-,即v-指令名称
            Vue.directive('hello',{
                bind: function () { // 常用
                    alert('指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
                },
                inserted: function () {
                    alert('被绑定元素插入到DOM时调用');
                },
                update: function () {
                    alert('被绑定元素所在模板更新时调用');
                }, // 下面两个不常用
                componentUpdated: function () {
                    alert('被绑定元素所在模板完成一次更新周期时调用');
                },
                unbind: function () { 
                    alert('指令与元素解绑是调用,只调用一次');
                }
            });
            // 钩子函数的参数
            Vue.directive('world',{
                bind(el,binding){
                    console.log(el)  // el指令所绑定的元素,DOM对象
                    el.style.color='red' // 可以对这个DOM对象进行操作例如加样式
                    console.log(binding)  // binding一个对象             
                }
            });
    		var vm=new Vue({
    			el:'#itany',
    			data:{  
    				msg:'welcome to itany',
                    name:'alice'
                    },
                methods:{
                    change(){
                        this.msg='欢迎来到南京网博'
                    }
                }
               });
              
    	</script>
    </body>
    </html>
    

      页面显示

       简化也可以注册一个函数,在bind和update

      注册指令函数,bind和update会被调用

      示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>自定义指令</title>
    	<script src="js/vue.js"></script>
    </head>
    <body>
    	<div id="itany">
            <!-- 定义指令使用hello使用的时候需要加前缀v- -->
            <!-- <h3 v-hello>{{msg}}</h3> -->
            <button @click="change">更新数据</button>
            <h3 v-wbs>{{msg}}</h3>
        </div>
        <script>
            // 自定义全局指令
            // 使用指令时必须在指令名称前加v-,即v-指令名称
            Vue.directive('hello',{
                bind: function () { // 常用
                    alert('指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
                },
                inserted: function () {
                    alert('被绑定元素插入到DOM时调用');
                },
                update: function () {
                    alert('被绑定元素所在模板更新时调用');
                }, // 下面两个不常用
                componentUpdated: function () {
                    alert('被绑定元素所在模板完成一次更新周期时调用');
                },
                unbind: function () { 
                    alert('指令与元素解绑是调用,只调用一次');
                }
            });
            // 钩子函数的参数
            Vue.directive('world',{
                bind(el,binding){
                    console.log(el)  // el指令所绑定的元素,DOM对象
                    el.style.color='red' // 可以对这个DOM对象进行操作例如加样式
                    console.log(binding)  // binding一个对象             
                }
            });
            //传入一个简单的函数,bind和update时调用
    		Vue.directive('wbs',function(){
    			alert('wbs17022');
    		});
    
    		var vm=new Vue({
    			el:'#itany',
    			data:{  
    				msg:'welcome to itany',
                    name:'alice'
                    },
                methods:{
                    change(){
                        this.msg='欢迎来到南京网博'
                    }
                }
               });
              
    	</script>
    </body>
    </html>
    

      页面显示

      在绑定和更新数据的时候调用函数

     

       2,自定义局部指令

      在vue实例内部定义

      示例:页面刷新获得焦点

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>自定义指令</title>
    	<script src="js/vue.js"></script>
    </head>
    <body>
    	<div id="itany">
            <!-- 定义指令使用hello使用的时候需要加前缀v- -->
            <!-- <h3 v-hello>{{msg}}</h3> -->
            <button @click="change">更新数据</button>
            <!-- <h3 v-wbs>{{msg}}</h3> -->
            <input type="text" v-model="msg" v-focus> 
        </div>
        <script>
            // 自定义全局指令
            // 使用指令时必须在指令名称前加v-,即v-指令名称
            Vue.directive('hello',{
                bind: function () { // 常用
                    alert('指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
                },
                inserted: function () {
                    alert('被绑定元素插入到DOM时调用');
                },
                update: function () {
                    alert('被绑定元素所在模板更新时调用');
                }, // 下面两个不常用
                componentUpdated: function () {
                    alert('被绑定元素所在模板完成一次更新周期时调用');
                },
                unbind: function () { 
                    alert('指令与元素解绑是调用,只调用一次');
                }
            });
            // 钩子函数的参数
            Vue.directive('world',{
                bind(el,binding){
                    console.log(el)  // el指令所绑定的元素,DOM对象
                    el.style.color='red' // 可以对这个DOM对象进行操作例如加样式
                    console.log(binding)  // binding一个对象             
                }
            });
            //传入一个简单的函数,bind和update时调用
    		Vue.directive('wbs',function(){
    			alert('wbs17022');
    		});
    
    		var vm=new Vue({
    			el:'#itany',
    			data:{  
    				msg:'welcome to itany',
                    name:'alice'
                    },
                methods:{
                    change(){
                        this.msg='欢迎来到南京网博'
                    }
                },
                directives:{ // 自定义指令
                    //当被绑定元素插入到DOM中时获取焦点
                    focus:{
                        inserted(el){
                            el.focus();
                        }
                    }
                }
               });
              
    	</script>
    </body>
    </html>
    

      3,练习

      拖动页面中的元素,使其移动,松开鼠标不移动

      onmouseover onmouseout  

      09.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>练习:自定义指令</title>
    	<script src="js/vue.js"></script>
    	<style>
    		#itany div{
    			 100px;
    			height: 100px;
    			position:absolute;
    		}
    		#itany .hello{
    			background-color:red;
    			top:0;
    			left:0;
    		}
    		#itany .world{
    			background-color:blue;
    			top:0;
    			right:0;
    		}
    
    	</style>
    </head>
    <body>
    	<div id="itany">
    		<div class="hello" v-drag>itany</div>
    		<div class="world" v-drag>网博</div>
    	</div>
    
    	<script>
    		Vue.directive('drag',function(el){
    			el.onmousedown=function(e){
    				//获取鼠标点击处分别与div左边和上边的距离:鼠标位置-div位置
    				var disX=e.clientX-el.offsetLeft;
    				var disY=e.clientY-el.offsetTop;
    				// console.log(disX,disY);
    
    				//包含在onmousedown里面,表示点击后才移动,为防止鼠标移出div,使用document.onmousemove
    				document.onmousemove=function(e){
    					//获取移动后div的位置:鼠标位置-disX/disY
    					var l=e.clientX-disX;
    					var t=e.clientY-disY;
    					el.style.left=l+'px';
    					el.style.top=t+'px';
    				}
    
    				//停止移动
    				document.onmouseup=function(e){
    					document.onmousemove=null;
    					document.onmouseup=null;
    				}
    
    			}
    		});
    
    		var vm=new Vue({
    			el:'#itany',
    			data:{
    				msg:'welcome to itany',
    				username:'alice'
    			},
    			methods:{
    				change(){
    					this.msg='欢迎来到南京网博'
    				}
    			}
    		});
    	</script>
    	
    </body>
    </html>
    

      页面显示

       六,动画(过渡)

      1.简介

      Vue在插入,更新或者移除DOM时,提供多种不同方式的应用过滤效果

      本质上还是使用CSS3动画:transition,animation

      2.基本用法

      使用transition组件,将要执行动画的元素包含在该组件内

        <transtion></transtion>

      示例,演示淡入淡出效果,网页上的一个标签正常显示与不显示的效果是立即生效的,没有渐渐的过程下面演示动画效果

      day02/10.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>动画</title>
    	<script src="js/vue.js"></script>
    	<style>
    		 p{
    			 300px;
    			height: 300px;
                background-color: red;
    		}
            .fade-enter-active,.fade-leave-active{
                transition:all 1s ease;
            }
            .fade-enter-active{
                opacity: 1;
                 300px;
                height: 300px;
            }
            .fade-leave-active{
                opacity: 0;
                 0px;
                height: 0px;
            }
            .fade-enter{
                opacity: 0;
                 50px;
                height: 50px;
            }
    	</style>
    </head>
    <body>
    	<div id="itany">
            <button @click="flag=!flag">点我</button>
            <transition name="fade">
                <p v-show="flag">网博</p>
            </transition>
            
    	</div>
    
    	<script>
    
    		var vm=new Vue({
    			el:'#itany',
                data:{
                    flag:false
                }
    		});
    	</script>
    	
    </body>
    </html>
    

      3,钩子函数

      解析:需要演示效果的<p>标签包含在标签<transition>内,这个标签自定义名称fade,然后在样式里定义过渡的类名状态来实现动画效果

      在进入/离开的过渡中,会有 6 个 class 切换。

    1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

    2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

    3. v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

    4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

    5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

    6. v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

      代码解析

       页面显示

       注意:fade-enter要放在最后位置,否则动画效果不实现

      可以在 attribute 中声明 JavaScript 钩子,在动画执行的各个过程绑定一些方法

      示例 day02/10.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>动画</title>
    	<script src="js/vue.js"></script>
    	<style>
    		 p{
    			 300px;
    			height: 300px;
                background-color: red;
    		}
            .fade-enter-active,.fade-leave-active{
                transition:all 1s ease;
            }
            .fade-enter-active{
                opacity: 1;
                 300px;
                height: 300px;
            }
            .fade-leave-active{
                opacity: 0;
                 0px;
                height: 0px;
            }
            .fade-enter{
                opacity: 0;
                 50px;
                height: 50px;
            }
    	</style>
    </head>
    <body>
    	<div id="itany">
            <button @click="flag=!flag">点我</button>
            <transition name="fade"
                @before-enter="beforeEnter"
    			@enter="enter"
    			@after-enter="afterEnter"
    			@before-leave="beforeLeave"
    			@leave="leave"
    			@after-leave="afterLeave"
            >
                <p v-show="flag">网博</p>
            </transition>
            
    	</div>
    
    	<script>
    
    		var vm=new Vue({
    			el:'#itany',
                data:{
                    flag:false
                },
                methods:{
                    beforeEnter(){
                        alert('动画进入之前');
                    },
                    enter(){
                        alert('动画进入');
                    },
                    afterEnter(){
                        alert('动画进入之后');
                    },
                    beforeLeave(){
    					alert('动画即将之前');
    				},
    				leave(){
    					alert('动画离开');
    				},
    				afterLeave(el){
    					alert('动画离开之后');
    					// el.style.background='red';
    				}
    
                }
    		});
    	</script>
    	
    </body>
    </html>
    

      页面显示

       省略其他几张截图

      本次使用alert只是演示执行的过程,有什么用呢,这几个钩子函数传递参数el可以对这个DOM执行一些样式等操作

      例如想要进入之后显示为蓝色

    afterEnter(el){
                        alert('动画进入之后');
                        el.style.background='blue';
    },
    

      4,结合第三方动画库animate..css一起使用

      示例day02/11.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>动画</title>
    	<link rel="stylesheet" href="css/animate.css">
    	<script src="js/vue.js"></script>
    	<style>
    		p{
    			 300px;
    			height: 300px;
    			background-color:red;
    			margin:0 auto;
    		}
    	</style>
    </head>
    <body>
    	<div id="itany">
    		<button @click="flag=!flag">点我</button>
    		
    		<transition enter-active-class="animated fadeInLeft" leave-active-class="animated fadeOutRight">
    			<p v-show="flag">网博</p>
    		</transition>
    	</div>
    
    	<script>
    		var vm=new Vue({
    			el:'#itany',
    			data:{
    				flag:false
    			}
    		});
    	</script>
    	
    </body>
    </html>
    

      页面显示

       注意:需要引入animate.css样式,需要加入初始样式animated否则不生效

      可以在https://www.dowebok.com/demo/2014/98/ 查看anmiated演示效果

       5,多元素动画

      多元素动画需要使用标签<transition-group>,还需要给内部的每一个元素使用关键字:key指定唯一的key

      示例day02/12.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>多元素动画</title>
    	<link rel="stylesheet" href="css/animate.css">
    	<script src="js/vue.js"></script>
    	<style>
    		p{
    			 100px;
    			height: 100px;
    			background-color:red;
    			margin:20px auto;
    		}
    	</style>
    </head>
    <body>
    	<div id="itany">
    		<button @click="flag=!flag">点我</button>
    		
    		<transition-group enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
    			<p v-show="flag" :key="1">itany</p>
    			<p v-show="flag" :key="2">网博</p>
    		</transition-group>
    	</div>
    
    	<script>
    		var vm=new Vue({
    			el:'#itany',
    			data:{
    				flag:false
    			}
    		});
    	</script>
    	
    </body>
    </html>
    

      页面显示

      6,练习

      要求在输入框输入字符,然后根据字符显示元素

      day02/13.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>练习:多元素动画</title>
    	<link rel="stylesheet" href="css/animate.css">
    	<script src="js/vue.js"></script>
    	<style>
    		p{
    			 100px;
    			height: 100px;
    			background-color:red;
    			margin:20px auto;
    		}
    	</style>
    </head>
    <body>
    	<div id="itany">
    		<input type="text" v-model="name">
    		
    		<transition-group enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
    			<p v-for="(v,k) in arr2" :key="k">
    				{{v}}
    			</p>
    		</transition-group>
    	</div>
    
    	<script>
    		var vm=new Vue({
    			el:'#itany',
    			data:{
    				flag:true,
    				arr:['tom','jack','mike','alice','alex','mark'],
    				name:''
    			},
    			computed:{
    				arr2:function(){
    					var temp=[];
    					this.arr.forEach(val => {
    						if(val.includes(this.name)){
    							temp.push(val);
    						}
    					});
    					return temp;
    				}
    			}
    		});
    	</script>
    	
    </body>
    </html>
    

      解析:  

      定义一个计算属性arr2,输入框绑定的元素是name,如果输入框的字符出现在arr列表中,则把这个字符投入temp列表中,最后返回temp列表就是包含输入框字符的所有arr里面的元素的一个列表,arr2是计算属性,依赖于返回的temp,然后显示包含输入框字符的所有arr列表里面的元素。

      页面显示

  • 相关阅读:
    PHP新建文件并写入内容demo
    PHP输出结果demo
    网站顶部图标使用分析
    .htaccess文件的创建 / 联动天下空间伪静态(isapi_rewrite)配置方法
    【原创】网站底部竖线布局对比/研究
    JS判断访问设备终端PC/iPad/iPhone/android 和浏览器IE/Opera/Firefox/webKit
    我的blog风格
    2020.11.17 近日复健情况
    南风又起,锦字题予往昔(写给校刊《我们大多数》)
    【对拍大法好!!】
  • 原文地址:https://www.cnblogs.com/minseo/p/15693035.html
Copyright © 2011-2022 走看看