Vue3源码系列 - 指令源码及魔改自定义指令标识【绝对干货】

本文概览

  1. 自定义指令部分相关源码
  2. 指令为啥用的是 v- 而不是其他标识
  3. 魔改 v- 成其他标识

1.自定义指令部分相关源码

位于 createAppAPI 函数闭包里面的 directive 函数

directive(name, directive) {
  {
    // 判断是否和内置指令重名
    validateDirectiveName(name);
  }
  if (!directive) {
    return context.directives[name];
  }
  if (context.directives[name]) {
    warn$1(`Directive "${name}" has already been registered in target app.`);
  }
  context.directives[name] = directive;
  return app;
}

注册一个全局指令

    // 注册全局指令
    app.directive('color', {
      mounted(el, binding, vnode) {
        console.log(binding)
        el.style.color = binding.value;
      }
    });

输出 binding
在这里插入图片描述

然后在源码里找到这个对象,位于 new Tokenizer() 里面的ondirname函数
在这里插入图片描述

搜索ondirname函数的调用链,找到 class Tokenizer 里面的 stateInDirName 函数
在这里插入图片描述

继续搜索 stateInDirName 函数的调用链,位于 class Tokenizer 类里面的 parse 函数
这里的 【case 13:】 是不是很突兀?????接着往下看就对了
在这里插入图片描述

2.指令为啥用的是 v- 而不是其他标识

我们继续搜索 this.state = 13 找到 handleAttrStart 函数
在这里插入图片描述
c === 118 ???啥意思?---------- 不好意思 unicode编码 118 刚好是 v

peek() {
  // index 下一个字符的unicode编码
  return this.buffer.charCodeAt(this.index + 1);
}

this.peek() === 45???啥意思?---------- 不好意思 unicode编码 45 刚好是 -
那么,组合起来是不是就是 v-,到这里你悟没有!!!!

3.魔改 v- 成其他标识

字的unicode编码为 25105,将 handleAttrStart 函数修改如下:

handleAttrStart(c) {
  // 我 unicode码 25105
  if (c === 25105 && this.peek() === 45) {
  // if (c === 118 && this.peek() === 45) {
    this.state = 13;
    this.sectionStart = this.index;
  } else if (c === 46 || c === 58 || c === 64 || c === 35) {
    this.cbs.ondirname(this.index, this.index + 1);
    this.state = 14;
    this.sectionStart = this.index + 1;
  } else {
    this.state = 12;
    this.sectionStart = this.index;
  }
}

html

<body>
  <div id="app">
    <span 我-color="'red'" >{{msg}}</span>
  </div>
  <script>
    const { createApp, ref } = Vue
    let rootComponent = {
      setup() {
        const msg = ref("createApp.directive() 自定义指令")
        return {
          msg,
        }
      },
    }
    let app = createApp(rootComponent)
    // 注册全局指令
    app.directive('color', {
      mounted(el, binding) {
        console.log(binding)
        el.style.color = binding.value;
      }
    });
    app.mount("#app")
  </script>
</body>

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d72b28e0cbc248619f5296a0bfd8b039.png
指令成功渲染

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值