手撕Vue-实现事件相关指令
经过上一篇文章的学习,实现了界面驱动数据更新,接下来实现一下其它相关的指令,比如事件相关的指令,v-on 这个指令的使用频率还是很高的,所以我们先来实现这个指令。
v-on 的作用是什么,是不是可以给某一个元素绑定一个事件。
紧接着了解了 v-on 的作用之后,我在 example.html 的结构代码当中添加了一个 div 用 v-on 绑定了一个点击事件,然后在 methods 当中添加了一个 myFn 的方法,然后在点击事件触发的时候调用了 myFn 方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue基本模板</title>
<script src="js/nue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="name"/>
<div v-on:click="myFn">我是div</div>
</div>
<script>
let vue = new Nue({
el: document.querySelector('#app'),
data: {
name: "BNTang"
},
methods: {
myFn() {
alert('myFn被执行了');
},
}
});
</script>
</body>
</html>
如上已经将基本的结构搭建完毕了,现在需要做的事情就是需要处理一下 v-on 这个指令。
首先来看我们自己编写的 Nue 源码,在创建 Nue 实例的时候, 调用了 new Compiler(this);,进入 Compiler,constructor 方法继续往下看, 在进入 this.buildTemplate(fragment);,遍历所有的节点,判断是否是一个元素时,调用了 this.buildElement(node);, 进入 buildElement 方法,可以看到之前就是在这里处理了 v-model 这个指令,现在我们需要在这里处理 v-on 这个指令。
我先将 name, value 打印到控制台,输出结果如下:
type text
v-model name
v-on:click myFn
可以得出如果我们编写的是 v-model,那么 name 就是 v-model,value 就是 name,如果编写的是 v-on:click,那么 name 就是 v-on:click,value 就是 myFn。
知道了这些信息之后就可以开展下一步了,我在将 name 按照 : 进行分割一次就会拿到的是 v-on 与 click,click 就是待会我们要注册的事件类型,在用解构的方式将 name, value 取出来,代码如下:
let [directiveName, directiveType] = name.split(':');
directiveName 就是 v-on,directiveType 就是 click。
然后再将之前的代码 name.split('-'); 改写为 directiveName.split('-');, 这个时候我们将解构出来的结果如下:
model
on
这个时候就可以在之前的工具类当中添加一个 on 方法, 来用处理 v-on,在添加 on 方法之前,改造一下根据指令名称, 调用不同的处理函数的代码,将之前的代码改写为如下:
CompilerUtil[directive](node, value, this.vm, directiveType);
多了一个 directiveType 参数,这个参数就是指令的类型,比如 v-on:click,那么 directiveType 就是 click,这个时候就可以在工具类当中添加一个 on 方法了,代码如下:
on: function (node, value, vm, type) {
node.addEventListener(type, (e) => {
alert('事件注册成功了');
});
}
这个时候我们在页面上点击 div 的时候,就会弹出一个提示框,说明事件注册成功了。

事件注册成功了是没问题,但是这个事件执行的内容,是自己的,并不是通过 v-on 绑定的,所以我们需要将这个事件执行的内容改为通过 v-on 绑定的,这个时候就需要用到之前的 methods 对象了,我们需要通过 methods 对象来获取到对应的方法,然后将这个方法执行。
接下来要改造一下创建 Nue 实例的时候,将 methods 保存起来,改造一下 Nue 的构造函数,以后在根据对应的方法名称,获取到对应的方法, 再执行即可,代码如下:
this.$methods = options.methods;

改造完毕之后,我们就可以在工具类当中的 on 方法当中,通过 methods 对象获取到对应的方法,然后执行即可,代码如下:
on: function (node, value, vm, type) {
node.addEventListener(type, (e) => {
vm.$methods[value](e);
});
}
这个时候我们在页面上点击 div 的时候,就会弹出一个提示框,说明事件注册成功了,并且事件执行的内容也是通过 v-on 绑定的。

在 myFn 方法中打印一下 this,发现并不是 Nue 的实例,而是 myFn 本身:

这个时候就需要将 myFn 的 this 改为 Nue 的实例,这个时候就需要用到 call 方法了,代码如下:
node.addEventListener(type, (e) => {
vm.$methods[value].call(vm, e);
});
call 方法的第一个参数是改变 this 的指向,第二个参数是传递的参数,这个时候我们在 myFn 方法中打印一下 this,发现已经是 Nue 的实例了。

到此为止,v-on 指令的实现已经完成了。
手撕Vue-实现事件相关指令的更多相关文章
- Vue 事件相关实例方法---on/emit/off/once
一.初始位置 平常项目中写逻辑,避免不了注册/触发各种事件 今天来研究下 Vue 中,我们平常用到的关于 on/emit/off/once 的实现原理 关于事件的方法,是在 Vue 项目下面文件中的 ...
- 手写 Vue 系列 之 Vue1.x
前言 前面我们用 12 篇文章详细讲解了 Vue2 的框架源码.接下来我们就开始手写 Vue 系列,写一个自己的 Vue 框架,用最简单的代码实现 Vue 的核心功能,进一步理解 Vue 核心原理. ...
- 移动端Tap与滑屏实战技巧总结以及Vue混合开发自定义指令
最近在忙混合开发,因交互相对复杂,所以也踩了很多坑.在此做一下总结. 1.tap事件的实际应用 在使用tap事件时,老生常谈的肯定是点透问题,大多情况下,在有滑屏交互的页面时,我们会在根节点阻止默认行 ...
- VUE:内置指令与自定义指令
VUE:内置指令与自定义指令 常用的内置指令 1)v:text 更新元素的 textContent 2)v-html 更新元素的 innerHTML 3)v-if 如果为true,当前标签才会输出到页 ...
- vue的事件绑定
vue事件有两方面内容:DOM事件 和 自定义事件. DOM事件 vue中采用DOM2级事件的处理方式,为IE9以上的浏览器服务.下面我们先来讲解一下什么是DOM2级事件吧! JS中DOM0级事件有两 ...
- 编译原理--05 用C++手撕PL/0
前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...
- vue第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)
第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件) #课程目标 掌握vue实例的相关属性和方法的含义和使用 了解vue的数据响应原理 熟悉创建组件,了解全局 ...
- 用C/C++手撕CPlus语言的集成开发环境(1)—— 语言规范 + 词法分析器
序言 之所以叫做CPlus语言,是因为原本是想起名为CMinus的,结果发现GitHub和Gitee上一堆的CMinus的编译器(想必都是开过编译原理课程并且写了个玩具级的语言编译器的大佬们吧).但是 ...
- MySQL通过bin log日志恢复数据|手撕MySQL|对线面试官
关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 作为<手撕MySQL>系列的第二篇文章,今天介绍一下MySQL的二进制日志(bin log),注意不要和MySQL的InnoDB ...
- Vue(四) 内置指令
现在介绍 Vue.js 中 更多的内置指令 基本指令 v-cloak v-cloak 不需要表达式,它会在 Vue 实例结束编译时从绑定的 HTML 元素上移除,经常和 CSS 的 display: ...
随机推荐
- ZEGO自研RTC+直播系统架构,如何支撑一场高质量直播
近年来得益于网络基础设施的进步,实时音视频(Real-Time Communication,以下简称 RTC)和直播(采用 CDN 进行内容分发)在各行业迅速落地,在疫情的催化下更是推动传统的教育.会 ...
- 提示工程101|与 AI 交谈的技巧和艺术
随着 ChatGPT 的问世,人工智能(AI)新时代也正式开启.ChatGPT 是一种语言模型.它与用户进行对话交互,以便用户输入问题或提示,模型响应,然后对话可以继续来回进行,类似于在消息传递应用程 ...
- react中常见hook的使用方式与区别
1.什么是hook?react hook是react 16.8推出的方法,能够让函数式组件像类式组件一样拥有state.ref.生命周期等属性. 2.为什么要出现hook?函数式组件是全局当中一个普通 ...
- Java 日志系列:JUL 使用和原理分析
目录 一. 简介 二.使用 三.日志级别 四.Logger 继承关系 五.配置文件 六.原理解析 一. 简介 JUL 全称 Java util Logging 是 java 原生的日志框架,使用时不需 ...
- [ABC149E] Handshake
2023-03-06 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 二分 解题思路 因为按照贡献从大到小握手一定是最优的,所以将 \(a\) ...
- 探索ChatGPT的Fine-tuning和Embeddings
1.概述 今天我们将深入探索ChatGPT的两项核心技术:Fine-tuning(微调)和Embeddings(嵌入).这些技术在现代自然语言处理领域扮演着至关重要的角色,为模型的性能提升和适应特定任 ...
- 《Web安全基础》01. 基础知识
@ 目录 1:概念名词 1.1:域名 1.2:DNS 1.3:网站开发语言 1.4:后门 1.5:Web 1.6:Web 相关安全漏洞 2:数据包 2.1:HTTP 2.2:HTTPS 2.3:请求数 ...
- 细谈商品详情API接口设计
一.引言 随着互联网技术的发展,商品详情信息的展示和交互变得越来越重要.为了提供更好的用户体验,我们需要设计一套高效.稳定且易于扩展的商品详情API接口.本文将详细探讨商品详情API接口的设计,包括接 ...
- (洛谷P4213)杜教筛
https://www.cnblogs.com/Mychael/p/8744633.html #pragma GCC optimize(3, "Ofast", "inli ...
- 【python技巧】替换文件中的某几行
[python技巧]替换文件中的某几行 1. 背景描述 最近在写一个后端项目,主要的操作就是根据用户的前端数据,在后端打开项目中的代码文件,修改对应位置的参数,因为在目前的后端项目中经常使用这个操作, ...