Vue.js 其他指令

1.ref标识

通过给HTML标签或者组件标签设定ref属性,根据他的属性值来访问这个HTML元素或者组件
语法:this.$refs.属性值

//为p标签设置ref属性
<div id="app">
    <p ref="p1">期待你脚踏祥云</p>
    <button @click="test">点我</button>
</div>
//根据ref属性值来访问这个元素
methods: {
    test() {
        console.log(this.$refs.p1.innerText)
    }
}

2.v-cloak

在vue实例渲染HTML模版之前,页面中的{{msg}}这种语法就会原模原样的输出,例如

<body>
    <div id="app">
        <p>{{msg}}</p>
    </div>
</body>

</html>
<script>
    //模拟网速慢的情形,延时创建vue实例
    setTimeout(() => {
        var vm = new Vue({
            el: '#app',
            data: {
                msg:"今天周末"
            },
        })
    }, 1000);
</script>

解决办法一:为标签设置v-cloak属性
原理:当vue对模版渲染完毕后会移除元素标签内vue指令,可以利用这个特性,结合css的属性选择器来隐藏未解析的标签

//css属性选择器
<style>
    [v-cloak]{
        display: none;
    }
</style>
//为元素添加v-cloak属性,当元素未渲染时处于隐藏状态,渲染完毕后就正常展示
<body>
    <div id="app">
        <!-- 模版编译完成之后会自动的那个移除 v-cloak 属性-->
        <p v-cloak>{{msg}}</p>
    </div>
</body>

</html>
<script>
    //模拟网速慢的情形,延时创建vue实例
    setTimeout(() => {
        var vm = new Vue({
            el: '#app',
            data: {
                msg:"今天周末"
            },
        })
    }, 1000);
</script>

解决办法二:使用v-text指令
在vue对模版渲染之前,v-text指令不会影响页面的展示


<body>
    <div id="app">
        <p v-text="msg"></p>
    </div>
</body>

3.自定义指令

(1)全局注册
语法:Vue.directive(指令名称,回调函数)
回调函数有2个参数 el和binding
el:指令所绑定的元素,可以用来直接操作 DOM
binding:包含指令相关信息的对象,binding.value就是指令绑定的值

Vue.directive('upper-text',function(el,binding){
    el.innerText = binding.value.toUpperCase();
})

(2)局部注册:只能在该组件中使用
组件中接受一个 directives 的选项

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

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

<!-- 自动获取焦点 -->
<input type="text" v-focus>

(3)如果注册的自定义指令名含有 - 等字符,可以用 '' 包裹起来

directives:{
    'lower-text':function(el,binding){
        el.innerText = binding.value.toLowerCase();
    }
}

(4)自定义指令的使用

<!-- msg的值为 good -->
<p v-html="msg"></p>
<!-- 使用插件的自定义指令 -->
<p v-upper-text="msg"></p>

渲染结果:

<p>good</p>
<p>GOOD</p>

(5)钩子函数
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。

Vue.directive('focus', {
    // 当被绑定的元素插入到 DOM 中时……
    inserted: function (el) {
        // 聚焦元素
        el.focus()
    }
})

(6)实例:文本滚动指令
思路:将当前文本放入子容器中,动态计算子容器与父容器的宽度差异,调用js定时器动态修改子容器的位置

<script>
    Vue.directive('scroll',{
        // 当被绑定的元素插入到 DOM 中时……
        inserted: function (el,binding) {
            //创建容器装载文本
            var content_box = document.createElement('div')
            content_box.style.display = 'inline-block'
            //不允许换行
            content_box.style.whiteSpace = 'nowrap'
            content_box.innerHTML = binding.value
            //将文本容器添加到元素中
            el.appendChild(content_box)
            //判定内容是否溢出
            if(el.scrollWidth - el.offsetWidth > 0){
                //隐藏溢出的内容
                el.style.overflow = 'hidden'

                var now_position = 0 //当前位置 默认0
                var direction = 'left' //移动方向 默认向左移动
                var target = el.offsetWidth - el.scrollWidth //负数
                var rest = 20 //动画暂停时间
                //使用定时器实时修改位移
                setInterval(()=>{
                    //只有rest小于0才执行动画
                    if(rest <= 0){
                        if(direction == 'left'){
                            now_position--
                        }else{
                            now_position++
                        }
                        //如果左移到底 则返回
                        if(now_position < target){
                            direction = 'right' 
                        }
                        //如果右移到底 则返回 并暂停动画
                        if(now_position > 0){
                            direction = 'left'
                            //暂停动画
                            rest = 20
                        }
                        //更新位置
                        content_box.style.transform = `translateX(${now_position}px)`
                    }
                    rest--
                },100)
            }
        }
    })
    new Vue({
        el:"#app",
        data:{
            msg:"床前明月光,疑是地上霜"
        }
    })
</script>

使用

<body>
    <div id="app">
        <div style="border:1px solid red;width:100px;margin:20px auto;" v-scroll="msg">
        </div>
    </div>
</body>

posted @ 2019-11-09 11:12  ---空白---  阅读(208)  评论(0编辑  收藏  举报