首页 > 其他分享 >手撕Vue-实现事件相关指令

手撕Vue-实现事件相关指令

时间:2023-10-21 16:56:44浏览次数:28  
标签:Vue methods value 指令 事件 click myFn name

经过上一篇文章的学习,实现了界面驱动数据更新,接下来实现一下其它相关的指令,比如事件相关的指令,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 的时候,就会弹出一个提示框,说明事件注册成功了。

image-20231021102245038

事件注册成功了是没问题,但是这个事件执行的内容,是自己的,并不是通过 v-on 绑定的,所以我们需要将这个事件执行的内容改为通过 v-on 绑定的,这个时候就需要用到之前的 methods 对象了,我们需要通过 methods 对象来获取到对应的方法,然后将这个方法执行。

接下来要改造一下创建 Nue 实例的时候,将 methods 保存起来,改造一下 Nue 的构造函数,以后在根据对应的方法名称,获取到对应的方法, 再执行即可,代码如下:

this.$methods = options.methods;

image-20231021103538146

改造完毕之后,我们就可以在工具类当中的 on 方法当中,通过 methods 对象获取到对应的方法,然后执行即可,代码如下:

on: function (node, value, vm, type) {
    node.addEventListener(type, (e) => {
        vm.$methods[value](e);
    });
}

这个时候我们在页面上点击 div 的时候,就会弹出一个提示框,说明事件注册成功了,并且事件执行的内容也是通过 v-on 绑定的。

image-20231021163138741

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

image-20231021164157119

这个时候就需要将 myFn 的 this 改为 Nue 的实例,这个时候就需要用到 call 方法了,代码如下:

node.addEventListener(type, (e) => {
    vm.$methods[value].call(vm, e);
});

call 方法的第一个参数是改变 this 的指向,第二个参数是传递的参数,这个时候我们在 myFn 方法中打印一下 this,发现已经是 Nue 的实例了。

image-20231021164018995

到此为止,v-on 指令的实现已经完成了。

标签:Vue,methods,value,指令,事件,click,myFn,name
From: https://www.cnblogs.com/BNTang/p/17779199.html

相关文章

  • uniCloud cms 自媒体资讯新闻文章应用系统 uniapp+uniCloud+AntDesignVue Life cms
    介绍LifeCMS是uniCloud+uni-app云端一体全套CMS/自媒体/资讯/新闻/文章应用系统,前台包含注册、登录(账号密码登录、短信登录、微信手机号快捷登录、微信一键登录、App手机一键登录、Apple登录)、文章列表、文章详情、搜索、广告、分享、评论、回复、点赞、收藏、用户中心、意见......
  • Vue进阶(幺玖玖):vue 输入框中按enter键实现搜索或表单提交
    在前端项目开发过程中,为优化用户体验,可考虑在用户输入查询条件后按回车键实现搜索效果。实现方法如下:el-input监听键盘按下状态得用@keyup.enter.native,如果是非el-input组件,可以直接用@keyup.enter。<[email protected]="search"v-model='form.searchAttr'></el......
  • vue实现点击复制功能(无需安装库)
     1.标签<buttonv-copy="text">复制文本</button>text是要复制的内容,在data函数中 2.在main.js中注册copy指令Vue.directive('copy',{bind:function(el,binding){el.$copy=function(){consttextarea=document.createElement('text......
  • VUE
    在body标签中编写视图       ......
  • [Vue]键盘事件
    1.Vue中常用的按键别名:   回车=>enter   删除=>delete(捕获“删除”和“退格”键)   退出=>esc   空格=>space   换行=>tab(特殊,必须配合keydown使用)   上=>up   下=>down   左=>left  右=>right2.Vue未提供别名的按键,可以使用按键原始的key值去......
  • React学习笔记14-dangerousSetinnerHtml指令
    1.使用场景dangerouslySetInnerHTML指令能将字符串当做html解析相当于vue中的v-html指令一般我们用来渲染富文本返回的html文本2.使用方法{this.state.tolist.map((item,index)=>{return(<spandangerouslySetInnerHTML={{__html:item}}ke......
  • FreeRTOS入门教程(事件组概念和函数使用)
    (文章目录)前言本篇文章将带大家学习什么是事件组以及如何使用事件组。一、事件组概念事件组通常是由一组位(bits)组成的数据结构,其中每一位都对应着某个特定的事件。每个位可以被设置或清除,表示相应的事件发生或未发生。这种位的组合形成了一个类似于二进制数的集合,每个位都代......
  • 基于Vue.js和Spring Boot的口罩自助售卖系统:设计、实现与技术深度解析
    本文介绍了一种基于Vue.js和SpringBoot的口罩自助售卖系统的设计与实现。该系统通过前端Vue.js框架和后端SpringBoot框架的结合,实现了用户注册登录、口罩浏览购买、订单管理等功能。通过详细的代码示例和技术深度的解析,读者能够全面了解系统的设计思路和实现方法。1.引言随着全......
  • 详解vue大文件视频切片上传的处理方法
    前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟后端配合做了一个切片的功能,接下来就详细的给大家介绍一下vue大文件视频切片上传的处理方法,需要的朋友可以参考下 前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟......
  • SpringBoot Vue3打造企业级一体化SaaS系统[最新版完结]
    点击下载:SpringBoot+Vue3打造企业级一体化SaaS系统     提取码:3ixbSpringBoot和Vue3是目前十分盛行的JavaWeb开发技术栈。SpringBoot能够快速构建Web应用程序,并提供许多有用的功用,如自动配置、快速开发、高效性能、易于部署等。Vue3是一种盛行的前端框架,它能够协助开发......