美文网首页二次封装组件vue
4--vue自定义指令 class.style绑定 动画

4--vue自定义指令 class.style绑定 动画

作者: Daeeman | 来源:发表于2020-03-18 19:46 被阅读0次

    1. directives-自定义指令

    a.简介

    除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:

    当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:

    // 注册一个全局自定义指令 `v-focus`
    Vue.directive('focus', {
      // 当被绑定的元素插入到 DOM 中时……
      inserted: function (el) {
        // 聚焦元素
        el.focus()
      }
    })
    

    如果想注册局部指令,组件中也接受一个 directives 的选项:

    directives: {
      focus: {
          // 指令的定义
          inserted: function (el) {
          el.focus()
        }
      }
    }
    

    然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

    <input v-focus>
    

    b. 案例

    directives ---- vue自定义指令
     作用
       1. 要操作dom时候
       2. 使用集成第三方插件时候
     定义:

            directives:{
                img:{
                inserted(el,binding){
               // el 当前指令所在的html节点
               // binding.value 指令的值
           }
        }
    }
    
    使用
        <div v-img="xxxxx">
    单词:
    
    • directives 指令
    • inserted 已插入
    • binding 绑定
    案例1-自定义指令 v-img
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">   
        <title>自定义指令</title>
        <style>
            .box{width: 180px;height: 320px;}
        </style>
    </head>
    <body>    
    <div id="app">   
        <div class="box" v-img="pics[0]"></div>
        <div class="box" v-img="pics[1]"></div>
        <div class="box" v-img="pics[2]"></div>
    </div>
    <script src="./js/vue.js"></script>
    <script>
    new Vue({
        el:"#app", 
        data:{pics:[
        "http://images.entgroup.cn/group2/M00/02/96/wKgAS13gt0WAS3CjAABoTRx_PZ8927.jpg",
        "http://images.entgroup.cn/group1/M00/05/2C/wKgASV34PqSAQliYAABmxNg1oI0829.jpg",
        "http://images.entgroup.cn/group2/M00/02/93/wKgAS12lOvCAP93oAACEwKNAR90206.jpg"]},  
        // 自定义指令 最大作用可以获取到自定义指令所在的 html 元素节点
        directives:{
            img:{
                // bind   update  inserted 当被插入到父节点
                inserted(el,binding){
                    // el 自定义指令所再的元素
                    // binding 绑定的数据  value 自定义指令的值
                    let color = Math.floor(Math.random()*1000000);
                    el.style.backgroundColor="#"+color;
                    // 加载图片
                    let img = new Image();
                    // 创造一个新的图片;
                    img.src = binding.value;
                    console.log(el,binding);
                    img.onload=function(){
                        el.style.backgroundImage=`url(${binding.value})`;
                        // 赋值背景图片
                    }
    
                }
            }
        }
    })    
    </script>    
    </body>
    </html>
    

    2. class绑定

    a. 简介
    1. 属性绑定
      :class="'red blue'"
    2. 动态绑定
      :class="{'red':flag}"
      <div :class="isActive?'yellow':'red'">111</div>
      :class="{'active':index==current}"
    3. 数组绑定
      :class="['red','em','small']"
    4. 对象绑定
    :class="classobj"
    data:{
        classobj:{
            a:true,
            b:true
        }
    }
    
    b.案例 1:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">   
        <title>class绑定</title>
        <style>
            .red{color:red;}
            .em{font-style: italic;}
            .small{font-size:12px;}   
        </style>
    </head>
    <body>    
    <div id="app">
        <!-- 在指令的值是js表达式不是字符串 -->
        <h1 :class="'red'">class是一个属性 可通过属性绑定</h1> 
        <h1 :class="{'red':flag}">class 对象方式绑定</h1>
        <h1 :class="['red','em','small']">数组的方法绑定多个</h1>
        <button @click="flag=!flag">{{flag}}</button>    
    </div>
    <script src="./js/vue.js"></script>
    <script>
    new Vue({
        el:"#app", 
        data:{
            flag:true,
            red:'red'
        }
    })    
    </script>    
    </body>
    </html>
    
    class.png
    c. 案例2-选项卡切换
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">   
        <title>选项卡案例</title>
        <style>
            .content{
                width: 300px;
                height: 300px;
                clear:both;
                border: 1px solid #ccc;
            }
            .title{
                display: inline-block;
                padding: 5px 15px;
                background-color: #ccc;
            }
            .active{color:#fff;background-color: dodgerblue;}
        </style>
    </head>
    <body>    
    <div id="app">
        <div class="title" 
        v-for="(item,index) in list" 
        :key="index"
        @click="current=index"
        :class="{'active':index==current}"
         >{{item.title}}</div>
         <!-- 当单击标题 设置current为当前的index(单击改变current) -->
         <!-- 类名active 的绑定 如果当前current与index相等 就绑定activeclass -->
        <div class="content">{{list[current].content}}</div>
        <!-- 内容根据 current值不同来显示不同内容 -->
         
    </div>
    <script src="./js/vue.js"></script>
    <script>
    new Vue({
        el:"#app", 
        data:{
            list:[
                {title:"jquery",content:"jquery内容"},
                {title:"vue",content:"vue内容"},
                {title:"react",content:"react内容"},
            ],
            current:0,//默认显示第几个div
        }
    })    
    </script>    
    </body>
    </html>
    

    3. style绑定

    动态绑定

    • 三目写法
    • 对象写法
    • 数组写法
    a.结构

    style 绑定
    对象

    <h1 :style="{fontSize:'14px',color:'red'}">style的绑定</h1> 
    
    <h1 :style="obj">对象变量方式</h1> 
    data:{
       obj:{'font-size':"48px",fontStyle:'italic',color:red}
    }
    
    b. 案例
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">   
        <title>style绑定</title>
        <style>  </style>
    </head>
    <body>    
    <div id="app">
        <h1 :style="{fontSize:'14px',color:'red'}">style的绑定</h1> 
        <div :style="'background:'+(isActive?'red':'yello')">动态三目写法</div> 
        <h1 :style="obj">对象变量方式</h1>   
    </div>
    <script src="./js/vue.js"></script>
    <script>
    new Vue({
        el:"#app", 
        data:{
            obj:{
                "font-size":"100px",
                fontStyle:'italic',
                color:'blue'
            }
        }
    })    
    </script>    
    </body>
    </html>
    

    4. 综合案例--购物车

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">   
        <title>购物车案例</title>
     
    </head>
    <body>    
    <div id="app">
       <table>
           <tr>
                <td >全选 <input type="checkbox" v-model="all" @change="checkAll"></td>
                <td>id</td>   <td>书名</td> <td>日期</td> <td>价格</td><td>数量</td>  <td>操作</td>
           </tr>
           <tr v-for="(item,index) in books" :key="index">
            <td><input type="checkbox" v-model="item.sel"></td>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>{{item.price}}</td>
            <td> 
                <button @click="item.num--">-</button>
                <input type="text" v-model.number="item.num">
                <button @click="item.num++">+</button>
            </td>
            <td> <button @click="delItem(item)">删除</button></td>
        </tr>
       </table> 
       总价格:{{total}}
    </div>
    <script src="./js/vue.js"></script>
    <script>
    new Vue({
        el:"#app", 
        data:{
            books:[
                {sel:true,id:1,name:"小红书",date:"2020/12/24",price:100,num:1},
                {sel:true,id:2,name:"小蓝书",date:"2020/12/25",price:20,num:1},
                {sel:true,id:3,name:"小绿书",date:"2020/12/26",price:80,num:1},
                {sel:true,id:4,name:"小白书",date:"2020/11/24",price:300,num:1},
                {sel:true,id:5,name:"vue精通",date:"2020/10/05",price:175,num:2}
            ],
            all:true,
        },
        computed:{
            "total":function(){
                var n=0;
                this.books.forEach(item=>{
                    if(item.sel){
                        n+=item.price*item.num;
                        // 加上每项 单价*数量
                    }              
                })
                return n;
                // 返回n;
            }
        },
        watch:{
          "books":{
              handler:function(nval){
                  this.all = this.books.every(item=>item.sel);
                //   every 每一个都返回为true,则最终返回为true,有一个返回为false最终都返回为false
                //  当books有任何变化的时候都检测全选是否为true or false
              },
              deep:true
          }  
        },
        methods:{
            delItem(item){
                var re = window.confirm("你确定要删除么");
                if(re){
                    let ind = this.books.indexOf(item);
                    this.books.splice(ind,1);
                }
            },
            checkAll(){
                this.books.forEach(item=>item.sel=this.all);
                // 当全选按钮发生改变是 ,所有的books项目的sel值都等于 all的值
            }         
        }
    })    
    </script>    
    </body>
    </html>
    
    购物车.png

    5. Vue 动画

    1.  vue它不能直接实现动画,它提供动画各阶段需要的class
    2. <transition> 组件提供class
    3. 在vue中,动画是在元素显示与隐藏的过程中,添加 class实现的
            v-if       v-else      v-show
    4. transition组件提供
    
        v-enter-active     元素整个进入的过程
        v-enter              元素进入的初始状态
        v-enter-to          元素进入的结束状态
        v-leave-active      元素整个离开的过程
        v-leave               元素的离开初始状态
        v-leave-to          元素的离开结束状态
    
    
        自定义动画名
            enter-active-class=“xxx”
            leave-active-class=“xxx”
            要引入第三方css  animate.css
    
       动画模式 mode
            in-out    先执行进入动画,再执行离开动画
            out-in    先执行离开动画,再执行进入动画
    
    5. transition-group组件
            tag            指定标签
            move-class     给正在移动中的元素添加class
            name           动画名称
    
        指定进入离开class
            enter-active-class
            leave-active-class       
    
    案例 1
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画</title>
        <script src="./js/vue.js"></script>
        <style>
            .fade-enter-active{ transition: all 2s ease;}
            /* 元素进入的整个过程 */
            .fade-leave-active{ transition: all .5s ease;}
            /* 元素离开的整个过程 */
            .fade-enter{opacity: 0;}
            /* 进入的初始状态 */
            .fade-enter-to{opacity: 1;}
            /* 进入的结束状态 */
            .fade-leave{opacity: 1;}
            /* 离开的初始状态 */
            .fade-leave-to{opacity: 0;}
            /* 离开的结束状态 */
        </style>
    </head>
    <body>
    <div id="app">
        <button @click="flag=!flag">切换</button> <br>
        <transition name="fade">
            <img src="./img/sun.jpg" v-if="flag" alt="" width="120">
        </transition>
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{flag:true}
        })
    </script>
    </body>
    </html>
    
    案例 2
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画</title>
        <script src="./js/vue.js"></script>
        <style>
            /* keyframes定义关键帧 fadeIn 动画名称 */
            @keyframes fadeIn {
                from{opacity: 0; transform:translate(-100px,0) rotate(-180deg)}
                /* 从{透明度:0,变换:位置变换(x位置-100,y位置0) 旋转变换(-180度)} */
                to{opacity: 1; transform:translate(0,0) rotate(0deg)}
            }
            @keyframes fadeOut {
                0%{opacity: 1;transform:translate(0,0) rotate(0deg)}
                100%{opacity: 0;transform:translate(100px,0) rotate(180deg)}
            }
            .fade-enter-active{ animation: fadeIn ease 1s; }
            /* 元素进入的整个过程 */
            .fade-leave-active{ animation: fadeOut ease 1s;}
            /* 元素离开的整个过程 */    
        </style>
    </head>
    <body>
    <div id="app">
        <button @click="flag=!flag">切换</button> <br>
        <transition name="fade">
            <img src="./img/sun.jpg" v-if="flag" alt="" width="120">
        </transition>
        <!-- transition是vue内置的一个组件,只要是动画都要包裹再里面  深,动态给img 再离开和进入是添加6个不同的class -->
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{flag:true}
        })
    </script>
    </body>
    </html>
    

    6. animate引入动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画</title>
        <link rel="stylesheet" href="./css/animate.min.css">
        <!-- 著名的css动画库引入 -->
        <script src="./js/vue.js"></script>
        <style>
           
        </style>
    </head>
    <body>
    <div id="app">
        <button @click="flag=!flag">切换</button> <br>
        <transition enter-active-class="slideInDown animated" leave-active-class=" hinge animated">
            <img src="./img/sun.jpg" v-if="flag" alt="" width="120">
        </transition>
        <!-- 定义进入的动画名称  定义离开的动画名称 -->
        <!-- transition是vue内置的一个组件,只要是动画都要包裹再里面  深,动态给img 再离开和进入是添加6个不同的class -->
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{flag:true}
        })
    </script>
    </body>
    </html>
    

    7. 动画模式

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动画组</title>
        <link rel="stylesheet" href="./css/animate.min.css">  
        <script src="./js/vue.js"></script>
        <style>
            .fadeOutUp{ position: absolute;}
           .move{ transition: all ease .6s;}
        </style>
    </head>
    <body>
    <div id="app">
        <input type="text" v-model="temp" placeholder="添加内容" 
        @keyup.enter="list.unshift(temp);temp=''">
        <transition-group tag="div" 
        enter-active-class="fadeInDown animated"
        leave-active-class="fadeOutUp animated"
        move-class="move"
        >
            <div v-for="(item,index) in list" :key="item">
                {{item}} <button @click="delItem(item)">x</button>
            </div>
        </transition-group>
       
         
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{ 
                temp:"",
                list:['vue','react','angular']
            },
            methods:{
                delItem(item){
                    var ind = this.list.indexOf(item);
                    this.list.splice(ind,1)
                }
            }
        })
    </script>
    </body>
    </html>
    

    相关文章

      网友评论

        本文标题:4--vue自定义指令 class.style绑定 动画

        本文链接:https://www.haomeiwen.com/subject/mqwcyhtx.html