vue 自定义指令

Vue本身推崇数据驱动视图的理念,但并非所有情况都适合。自定义指令就是一种有效的补充和扩展。
解决:可复用的原生DOM的操作,集成第三方插件(jQ庞大的插件系统改造成支持vue)。

举两个实际的例子:

图片的懒加载,默认在图片加载之前给容器设置一个随机色,然后图片加载完以后赋值给容器的背景图片(或者给容器里面的img的src赋值)

    <style>
        .imgwraps{
            height: 200px;
            width: 200px;
            background-position: center center;
        }
    </style>

    <div id="app">
        <div class="imgwraps" v-for="item in lists" v-img="item.url">
            <!-- <img src="" alt=""> -->
        </div>    
    </div>
<script>
Vue.directive('img',{ inserted:function(el,binding){ var color=Math.floor(Math.random()*1000000); // var target=el.getElementsByTagName('img')[0]; el.style.background='#'+color; var img= new Image(); img.src=binding.value; img.onload=function(){ el.style.backgroundImage="url("+ binding.value +")"; // target.src=binding.value; } } }) new Vue({ el:'#app', data:{ lists:[ {url:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502715114297&di=840f123ee136494fc0512601f4ae4e14&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D4e3e0e04b4096b6395145613645aed31%2Ff7246b600c338744af80e6575b0fd9f9d72aa050.jpg'}, {url:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502715142264&di=b1e6cee1f9d4ed8b4227ad93ee3260c9&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F12%2F29%2F68%2F12558PICryv.jpg'}, {url:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502715160553&di=65bf398e977d41d0d0b7e02e8400b846&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D5552aa402f2dd42a4b0409e86b5231c0%2F2934349b033b5bb54b92dfd73cd3d539b600bc56.jpg'} ] } }) </script>

 

用自定义指令实现一个常见的 tip 提示弹框的功能,鼠标移入元素,可以在元素的上下左右显示 tip,鼠标移出则隐藏 tip

    <style>
        li{
            list-style: none;
            width: 100px;
            height: 100px;
            border:1px solid #eee;
            position: relative;
        }
        li:hover{
            background: red;
        }
        .tips{
            position: absolute;
            width: 100px;
            height: 50px;
            background: #000;
            color: #fff;
            text-align: center;
        }
        .tips.left{
            left: 130px;
            top: 25px;
        }
        .tips.right{
            right: 130px;
            top: 25px;
        }
        .tips.top{
            left: 50%;
            margin-left: -50px;
            top: -75px;
        }
        .tips.bottom{
            left: 50%;
            margin-left: -50px;
            bottom: -75px;
        }
        .tips:after{
            position: absolute;
            border:10px solid transparent;
            content: "";
        }
        .left:after{
            border-right-color: #000;
            left: -20px;
            top: 50%;
            margin-top: -10px;
        }
        .right:after{
            border-left-color: #000;
            right: -20px;
            top: 50%;
            margin-top: -10px;
        }
        .bottom:after{
            border-bottom-color: #000;
            top: -20px;
            left: 50%;
            margin-left: -10px;
        }
        .top:after{
            border-top-color: #000;
            bottom: -20px;
            left: 50%;
            margin-left: -10px;
        }</style>

    <div id="app">
        <ul>
            <!-- 可支持设置top,bottom,left,right四个方向 -->
            <li v-mytip.top="mes">sss</li>
        </ul>   
    </div>

    <script>
        Vue.directive('mytip', {
          bind: function (el, binding, vnode) {
              var flag=false;
              el.onmouseover=function(){
                  if (!flag) {
                      var newEle=document.createElement("div");
                      newEle.id="tip";
                      newEle.className='tips '+Object.keys(binding.modifiers);
                      newEle.innerHTML=binding.expression;
                      el.append(newEle);
                      flag=true;
                  }
              }
              el.onmouseout=function(){
                document.getElementById('tip').remove();
                flag=false;
            }
         }
     })
   
new Vue({ el:'#app', data:{ mes:'hahahahah' } }) </script>

 

posted @ 2017-08-14 18:25  HAPPY海贝  阅读(1239)  评论(0编辑  收藏  举报