vue中的自定义指令以及模拟v-text、v-html、v-on

本文介绍了如何在Vue中注册自定义指令,包括全局和局部注册方式,并详细讲解了自定义指令的参数说明及钩子函数。通过自定义指令实现了v-text和v-html的功能,同时也探讨了模拟v-on点击事件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注册自定义指令的方式

注册v-focus自动聚焦指令:

<div id="app">

    <input type="text" v-focus="msg">

</div>

1. 全局注册

Vue.directive("focus", {
        // Vue会对html代码进行解析
        // 解析之后,会将解析后的内容重新渲染到页面中
        // inserted函数,就会在当前指令所在的元素,被插入到页面中的时候执行
        inserted: function (el) {
          // el 函数中接收的形参el,其实就是当前指令所在的元素

          el.focus()
          // console.log(el);
        }
      })

2. 局部注册

在创建Vue实例的时候,参数对象添加directives属性,在属性中注册指令即可!

全局注册所有的vue实例都能用

局部注册,只能在当前的vue实例中使用

const vm = new Vue({
        el: "#app",
        data: {
          msg: "<h1>hello world</h1>"
        },
        directives: {
          focus: {
            inserted(el){
              el.focus();
            }
          }
        }
      });

自定义指令的钩子函数:

 directives: {
          focus: {

            // 当vue要对当前指令所在的元素进行解析的时候执行
            bind(el){
              console.log("bind 钩子函数被执行了")
            },
            // 当当前指令所在的元素被插入到页面中的时候,会执行的函数
            inserted(el){
              console.log("inserted 钩子函数被执行了")
              // el.focus();
            },
            // 当当前指令绑定的数据,发生改变的时候,会执行update函数
            update(el){
              console.log("update 钩子函数被执行了")
            },
            // 当数据改变完成,元素更新完毕之后,会执行componentUpdated
            componentUpdated(el){
              console.log("componentUpdated 钩子函数被执行了")
            },
            // 当指令被卸载的时候
            unbind(el){
              console.log("unbind 钩子函数被执行了")
            }
          }
        }

 

自定义指令的参数说明:

指令的使用语法:

v-bind:src="msg"

v-on:click="clickHandler"

v-on:click.stop=""

一个指令完整的写法:

指令名称:指令参数.修饰符="表达式"

 

在自定义指令中的钩子函数里,我们可以拿到和当前指令相关的所有的信息

指令名称:指令参数.修饰符="表达式"

<div id="app">

<input type="text" v-focus:shuaige.dashuaige.gaofushuai="msg">

</div>

Vue.directive("focus", {
        bind(el, binding){
          console.log(el);
          console.log(binding);

          // binding可以用来获取当前指令的所有的信息
          // name: 获取的是当前指令的名称
          // rawName: 带v的指令名称名称
          // expression: 等号后面的表达式
          // value: 这个是表达式的值
          // arg: 获取到的就是指令的参数 冒号后面的内容
          // modifiers: 指令的修饰符,这是一个对象,修饰符都会被作为属性存储到这个对象中,属性值是true
        }
      })

通过自定义指令来模拟v-text和v-html的功能

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">

        <div v-mytext="msg"></div>
        <div v-myhtml="msg"></div>
        
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>

      Vue.directive("mytext", {
        bind(el, binding){
          // 需求,就是将msg的值,赋值给当前元素的innerText属性

          // msg的值: binding.value
          // 当前元素: el
          el.innerText = binding.value;
        },
        update(el, binding){
          el.innerText = binding.value;
        }
      })

      Vue.directive("myhtml", {
        bind(el, binding){
          // 需求,就是将msg的值,赋值给当前元素的innerText属性

          // msg的值: binding.value
          // 当前元素: el
          el.innerHTML = binding.value;
        },
        update(el, binding){
          el.innerHTML = binding.value;
        }
      })

      const vm = new Vue({
        el: "#app",
        data: {
          msg: "<h1>hello world</h1>"
        }
      });
    </script>
  </body>
</html>

自定义指令的简写形式:

Vue.directive("mytext", function(el, binding){
        el.innerText = binding.value;
      })

 

模拟v-on指令:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #parent{
      width: 200px;
      height: 200px;
      background-color:pink;
    }

    #child{
      width: 100px;
      height: 100px;
      background-color:hotpink;
    }
  </style>
</head>
<body>
  <div id="app">
    
    <div id="parent" v-myon:click.capture="parentClickHandler">
      <div id="child" v-myon:click.stop="childClickHandler"></div>
    </div>

  </div>

  <script src="./node_modules/vue/dist/vue.js"></script>

  <script>

    //1. 注册一个指令 v-myon
    Vue.directive("myon", {
      bind(el, binding){
        // 为当前元素注册指定类型的事件,事件处理函数为=后面的表达式代表的内容

        // 当前元素: el
        // 指定类型的事件: binding.arg
        // 事件处理函数: binding.value
        // capture: binding.modifiers.capture
        // stop: binding.modifiers.stop

        // el.addEventListener(事件名称, 事件处理函数, isCapture)


        // el.addEventListener(事件名称, 事件处理函数, isCapture)

        // el.addEventListener(binding.arg, function(e){
        //   binding.value(e);

        //   if(binding.modifiers.stop){
        //     e.stopPropagation();
        //   }
        // })


        el.addEventListener(binding.arg, function(e){
          binding.value(e)

          // if(binding.modifiers.stop){
          //   e.stopPropagation();
          // }
        }, binding.modifiers.capture)

      }
    })

    const vm = new Vue({
      el: "#app",
      methods: {
        childClickHandler(){
          alert("子元素被点击了")
        },
        parentClickHandler(){
          alert("父元素被点击了")
        }
      }
    })
  </script>
</body>
</html>

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值