自定义指令的介绍与案例

自定义指令分为全局指令 和局部指令
自定义指令

官方api 文档里有这么一句话:对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

1.全局指令

举例1:让指定文本框自动获取焦点

如果我们想实现这个例子,原生js的写法是:

//原生js写法:网页一打开,就让指定的输入框自动获取焦点
document.getElementById('search').focus()

但我们不建议这样做。我们可以通过Vue中的自定义指令来实现这个例子。
1.1 定义
所谓全局指令,是指可以在多个vue实例中使用的指令。

注册全局指令时,指令名不要用大写字母,且不要加v-,但是使用时一定要加前缀v-。格式如下:

 Vue.directive('指令名',{定义对象})

定义对象中有5个钩子函数:bind,inserted,update,componentUpdated,unbind。

(1)使用Vue.directive()自定义全局指令:

//自定义全局指令 v-focus:让文本框自动获取焦点
    //参数1:指令的名称。注意,在定义的时候,指令的名称前面,不需要加 v- 前缀;但是:在`调用`的时候,必须在指令名称前 加上 v- 前缀
    //参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
    Vue.directive('focus', {
    	//在每个函数中,第一个参数,永远是 el ,表示被绑定了指令的那个 dom 元素,这个el 参数,是一个原生的 JS 对象,所以 Vue 自定义指令可以用来直接和 DOM 打交道
        bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,【只执行一次】
            // 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用, 因为,一个元素,只有插入DOM之后,才能获取焦点
            // el.focus()
        },
        inserted: function (el) {  // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
            el.focus()
            // 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
        },
        updated: function (el) {  // 当VNode更新的时候,会执行 updated, 【可能会触发多次】

        }
    })

上方的代码中,如果我们把el.focus()这行代码写在bind方法里,是没有效果的(但不会报错)。没有效果是因为,在执行到bind方法的时候,元素还没有插入到dom中去。

由此可以看看出:bind、inserted、updated这三个钩子函数的执行时机不同,且执行的次数有区别。
(2)在指定的文本框上加v-指令名:

<input type="text" id="search" v-model="keywords" v-focus>

1.2 传参

举例2:设置DOM元素的color样式

参考举例1中的写法,我们可能会这样给DOM元素设置样式:

<div id="app">
    搜索框:
    <input type="text" id="search" v-model="name" v-color>
</div>

<script>
    //自定义全局指令 v-color:设置DOM元素的color属性
    Vue.directive('color', {
        bind: function (el) {
            el.style.color = 'red';
        },
    })
    new Vue({
        el: '#app',
        data: {
            name: ''
        }
    })
</script>

如上方代码所示,我们自定义了一个指令v-color,然后在input标签中用上了这个指令,就给元素设置了color属性。但是这个代码有个弊端是:color的属性值在定义指令的时候,被写死了。如何完善呢?我们可以在DOM元素中传参。

//自定义全局指令 v-color:设置DOM元素的color属性
Vue.directive('color', {
    // 只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
    // 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
    // 意思是说,我们可以把样式的代码写到bind中去(即使这个时候,dom元素还没有被创建)
    bind: function (el, binding) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,【只执行一次】

        console.log(binding.name); //打印结果:color
        console.log(binding.value); //打印结果:green

        el.style.color = binding.value// 通过bining拿到v-color中传递过来的值
    },
})

上方代码中,bind方法里传递的第二个参数binding,可以拿到DOM元素中v-color里填的值。注意,v-color="‘green’",这里面写的是字符串常量;如果去掉单引号,就成了变量,不是我们想要的。
1.3 简写格式

在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如上面的代码中,我们可以写成简写形式:

   Vue.directive('color', function (el, binding) { //注意,这个function等同于把代码写到了 bind 和 update 中去
            el.style.color = binding.value
        })

2.私有指令

2.1 定义方式

自定义私有指令:在某一个 vue 对象内部自定义的指令称之为私有指令。这种指令只有在当前vue对象的el指定的监管区域有用。

代码举例:(设置文字的font-weight属性)

<div id="app">
    <span v-fontweight="600">hello,word</span>
</div>
<script>
    new Vue({
        el: '#app',
        //自定义私有指令
        directives: {
            'fontweight': {
                bind: function (el, binding) {
                    el.style.fontWeight = binding.value;
                }
            }
        }
    })
</script>

注意, el.style.fontWeight设置属性值,至少要600,否则看不到加粗的效果。
2.2 简写格式

//自定义私有指令(简写形式)
directives: {
    'fontweight': function (el, binding) { //注意,这个function等同于把代码写到了 bind 和 update 中去
        el.style.fontWeight = binding.value;
    }
}

3.钩子函数

钩子函数说白了也就是生命周期,即当一个指令绑定到一个元素上时,这个指令内部有5个生命周期事件函数。接下来创建一个案例来看看这几个钩子函数的触发情况:

Vue 提供了自定义指令的5个钩子函数:

  • bind:当指令绑定在 HTML 元素上时触发,只执行一次。在这里可以进行一次性的初始化设置
  • inserted:被绑定的元素,插入到父节点的 DOM 中时调用(仅保证父节点存在)。
  • update:组件更新时调用。当指令绑定的元素状态/样式、内容(这里指元素绑定的 vue 数据) 发生改变时触发
  • componentUpdated:组件与子组件更新时调用。
  • unbind:当指令绑定的元素从 dom 中删除时触发,只执行一次。

案例:优化图片加载
代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="vue.js"></script>
    <style>
        img {
            width: 275px;
            height: 152px;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- //先不要设置src的属性 -->
        <img v-imgload="item" v-for="item in imgList">
        <!-- <img :src="item" alt="" v-for="(item,index) in imgList"> -->
    </div>
    <script>
        Vue.directive("imgload", (el, binding) => {
            //先设置元素的背景色
            el.style.backgroundColor = "#ff6700";
            // el.src = "holder.js/275x152";
            //等待图片加载完成后,修改图片的地址
            var img = new Image();
            //用创建好的img对象 去加载图片
            img.src = binding.value;
            //用创建好的img对象,去加载图片
            img.onload = () => {
                // el.style.backgroundColor = "";
                //只要图片加载过,再次请求图片的时候,就会直接从缓存中获取。
                el.src = binding.value;
            }
        })
        var vm = new Vue({
            el: "#app",
            data: {
                imgList: ["https://pic.3gbizhi.com/2021/1227/20211227082808899.jpg.278.154.jpg", "https://pic.3gbizhi.com/2021/1203/20211203075609486.jpg.278.154.jpg", "https://pic.3gbizhi.com/2021/1203/20211203075604804.jpg.278.154.jpg", "https://pic.3gbizhi.com/2021/1203/20211203075607171.jpg.278.154.jpg", "https://pic.3gbizhi.com/2021/1208/20211208022355980.jpg.278.154.jpg"
                ]
            },
            methods: {

            },
        })
    </script>
</body>

</html>
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
常用的自定义指令Vue包括: 1. v-longpress:用于实现长按功能,可以在长按某个元素时触发相应的事件。 2. v-focus:用于使元素自动获取焦点,可以在页面加载完成后自动定位到指定的元素上。 3. v-resize:用于监测元素的尺寸变化,可以在元素大小改变时触发相应的事件。 4. v-debounce:用于防抖功能,可以控制事件的触发频率,确保在一定时间内只触发一次事件。 5. v-throttle:用于节流功能,可以控制事件的触发频率,确保在一定时间内只触发一次事件,适用于需要控制事件频率的场景。 6. v-copy:用于实现点击复制功能,可以在点击元素时将指定的文本内容复制到剪贴板中。 7. v-drag:用于实现DOM元素的拖拽功能,可以使元素可以通过鼠标拖动来改变位置。 8. v-autofocus:用于自动聚焦input元素,可以在页面加载完成后自动将光标定位到指定的input元素上。 这些自定义指令可以通过在Vue中注册并在模板中使用,给予开发者更多灵活的操作和功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [进阶 vue自定义指令 vue中常用自定义指令以及应用场景,案例书写](https://blog.csdn.net/qq_43940789/article/details/131934170)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [开箱即用,超实用的 Vue 自定义指令合集](https://blog.csdn.net/Ed7zgeE9X/article/details/117136918)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值