34.Vue自定义指令-对象式

news2024/10/5 16:26:00

33.Vue自定义指令(函数式)_vue自定义函数_未来@音律的博客-CSDN博客还有一种就是,我们去定义指令的时候,也不要去写v-前缀,定义指令的时候需要给指令起名字,那么这个指令的名字直接就叫big,而用的时候还是要规规矩矩的写v-big。像需求一这种问题,我们就使用函数的写法就能实现,需求二,我特意设置了一个细节问题,是函数实现不了的,我们就需要用对象的写法去实现。我们可以看到,当修改和v-big毫不相干的值name,都会引起big的调用,则充分说明了指令所在的模板被重新解析时,也会引起指令的重新调用。就靠big函数中收到的参数,它收到的参数中有两个比较常用,这里打印出来看一下。_vue自定义函数https://liufr.blog.csdn.net/article/details/129667146上一节我们讲了Vue自定义指令的函数式,并用它实现了第一个需求,这里我们接着实现第二个需求。

需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点

根据我们上一节所学的,fbind直接写成函数,函数会收到,指令所在的元素,以及本次绑定的信息。

<!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="../js/vue.js"></script>
</head>
<body>
    <!-- 准备好一个容器 -->
    <div id="root">
       <h2>{{name}}</h2>
       <h2>当前的n值是:<span v-text="n"></span></h2>
       <h2>放大10倍的n值是:<span v-big="n"></span></h2>
       <button @click="n++">点我n+1</button>

       <hr>
       <input type="text" v-fbind:value="n">
    </div>

</body>
<script>

    Vue.config.productionTip = false;

    new Vue({
        el:'#root',
        data:{
            name:'zhangsan',
            n:1
        },
        directives:{

            big(element,binding){
                console.log('big被调用');
                element.innerText = binding.value * 10;

            },
            fbind(element,binding){
                element.value = binding.value;
            }

        }
    })

</script>
</html>

我们来看下运行效果:

写到这里就差一个功能了,就是一进这个页面,让它能够自动获取焦点。

按理来说,我们只要调用element.focus();即可,那我们来看看效果。

<!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="../js/vue.js"></script>
</head>
<body>
    <!-- 准备好一个容器 -->
    <div id="root">
       <h2>{{name}}</h2>
       <h2>当前的n值是:<span v-text="n"></span></h2>
       <h2>放大10倍的n值是:<span v-big="n"></span></h2>
       <button @click="n++">点我n+1</button>

       <hr>
       <input type="text" v-fbind:value="n">
    </div>

</body>
<script>

    Vue.config.productionTip = false;

    new Vue({
        el:'#root',
        data:{
            name:'zhangsan',
            n:1
        },
        directives:{

            big(element,binding){
                console.log('big被调用');
                element.innerText = binding.value * 10;

            },
            fbind(element,binding){
                element.value = binding.value;
                element.focus();
            }

        }
    })

</script>
</html>

实现效果: 

我们可以看到,这个页面一进来,并没有获取焦点,但是在点击n+1以后,却又获取了焦点。这是怎么回事呢?

接下来,我们不使用Vue,用一个原生的例子,来说明这个问题。

我们先实现一个点击创建input框的例子:

<!DOCTYPE html>
<html>
    <head>

        <meta charset="UTF-8"/>
        <title></title>

    </head>

    <body>
        <button id="btn"> 点我创建一个输入框 </button>

        <script type="text/javascript">

            const btn = document.getElementById('btn');
            btn.onclick = () => {
                const input = document.createElement('input');
                document.body.appendChild(input);
            }


        </script>

    </body>



</html>

实现效果:

接下来我们实现,让这个input创建的时候,就获得焦点。还是使用刚刚的focus方法。

<!DOCTYPE html>
<html>
    <head>

        <meta charset="UTF-8"/>
        <title></title>

    </head>

    <body>
        <button id="btn"> 点我创建一个输入框 </button>

        <script type="text/javascript">

            const btn = document.getElementById('btn');
            btn.onclick = () => {
                const input = document.createElement('input');
                document.body.appendChild(input);
                input.focus();
            }


        </script>

    </body>

</html>

实现效果:

这里的focus在一开始就生效了,那为什么刚刚Vue也使用了同样的方法,却没有在一开始就获得焦点,而是要在点击了n+1以后才获得焦点呢?

这里就要注意,focus方法并不是放在哪里都可以生效的。 如果我们把focus方法放在document.body.appendChild(input);之前就不会起作用了。

<!DOCTYPE html>
<html>
    <head>

        <meta charset="UTF-8"/>
        <title></title>

    </head>

    <body>
        <button id="btn"> 点我创建一个输入框 </button>

        <script type="text/javascript">

            const btn = document.getElementById('btn');
            btn.onclick = () => {
                const input = document.createElement('input');
                input.focus();
                document.body.appendChild(input);
                
            }


        </script>

    </body>

</html>

实现效果:

这是因为,input这个元素,只有放在页面上,才能有资格让它去获取焦点。所以像input.focus()这种方法,一定要在input已经存在于页面之上才能操作。

那么再回到刚刚的问题, 这个页面一进来,并没有获取焦点,但是在点击n+1以后,却又获取了焦点。这是怎么回事呢?

代码没问题,那就是执行的时机有问题。那我们就需要分析一下fbind到底是什么时候被调用的。

我们上一节其实已经说过了。

1.指令与元素成功绑定时会被调用。

2.指令所在的模板被重新解析时

问题就出在第一条,指令与元素成功绑定时会被调用

请注意,这里说的是成功绑定,而不是成功放入页面时。Vue在干活时其实是分好几步的,像上面的例子。Vue在拿到input和fbind时,会先做一次绑定,这里绑定成功之后,仅仅代表着在内存里建立了关系,此时你的input元素并没有跑到页面上。所以此时去调用element.focus();当然是不奏效的。

那这个问题该怎么解决呢?我们怎么才能让这个input一进来就获取焦点呢?

我们就需要在Vue不仅把自定义指令与元素绑定成功了,而且也将input放入页面的时候,去调用

element.focus();,也就是说我们希望把Vue的时间点再划分的细一点。

只要我们把fbind写成一个函数,那这个功能就是无法实现的。因为一旦fbind被我们写成函数,那他就只有两个时机才会调用 

1.指令与元素成功绑定时会被调用。

2.指令所在的模板被重新解析时

所以使用函数式,我们根本就拿不到Vue将元素放入页面的时间点。那这个时候就需要使用完整的对象写法才能实现。使用了对象写法,Vue就可以帮我们在特定的时间点执行特定的函数。

一共有3个特定函数:bind(); inserted(); update();

bind:当指令与元素成功绑定时调用

inserted:当指令所在元素被插入页面时调用

update:指令所在模板被重新解析时

我们可以把这些指令都做输出,看下实际的执行顺序。

<!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="../js/vue.js"></script>
</head>
<body>
    <!-- 准备好一个容器 -->
    <div id="root">
       <h2>{{name}}</h2>
       <h2>当前的n值是:<span v-text="n"></span></h2>
       <h2>放大10倍的n值是:<span v-big="n"></span></h2>
       <button @click="n++">点我n+1</button>

       <hr>
       <input type="text" v-fbind:value="n">
    </div>

</body>
<script>

    Vue.config.productionTip = false;

    new Vue({
        el:'#root',
        data:{
            name:'zhangsan',
            n:1
        },
        directives:{

            big(element,binding){
                console.log('big被调用');
                element.innerText = binding.value * 10;

            },
            fbind:{
                //指令与元素成功绑定时
                bind(){
                    console.log('bind');
                },
                //指令所在元素被插入页面时
                inserted(){
                    console.log('inserted');
                },
                //指令所在模板被重新解析时
                update(){
                    console.log('update');
                }
            }

        }
    })

</script>
</html>

实现效果:

写到这里,我们就将完整的对象式的代码写一下

<!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="../js/vue.js"></script>
</head>
<body>
    <!-- 准备好一个容器 -->
    <div id="root">
       <h2>{{name}}</h2>
       <h2>当前的n值是:<span v-text="n"></span></h2>
       <h2>放大10倍的n值是:<span v-big="n"></span></h2>
       <button @click="n++">点我n+1</button>

       <hr>
       <input type="text" v-fbind:value="n">
    </div>

</body>
<script>

    Vue.config.productionTip = false;

    new Vue({
        el:'#root',
        data:{
            name:'zhangsan',
            n:1
        },
        directives:{

            big(element,binding){
                console.log('big被调用');
                element.innerText = binding.value * 10;

            },
            fbind:{
                //指令与元素成功绑定时
                bind(element,binding){
                    element.value = binding.value;
                },
                //指令所在元素被插入页面时
                inserted(element,binding){
                    element.focus();
                },
                //指令所在模板被重新解析时
                update(element,binding){
                    element.value = binding.value;
                    element.focus();
                }
            }

        }
    })

</script>
</html>

 实现效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/763343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程

01 / 进程退出 exit.c /*#include <stdlib.h>void exit(int status);#include <unistd.h>void _exit(int status);status参数&#xff1a;是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。 */ #include <stdio.h> #include <stdlib.…

青翼科技自主研发4路AD子卡FMC137

FMC137是一款基于VITA57.4标准规范的JESD204B接口FMC子卡模块&#xff0c;该模块可以实现4路14-bit、2GSPS/2.6GSPS/3GSPS ADC采集功能。该板卡ADC器件采用ADI公司的AD9208芯片&#xff0c;&#xff0c;与ADI公司的AD9689可以实现PIN脚兼容。该ADC与FPGA的主机接口通过16通道的…

word文档删除顽固的双横线

1. 选中双横线 2. 开始 - 字体 - 隐藏(勾选) 3. 顽固的双横线已成功删除

微信小程序用户登录及头像昵称设置教程(前后端)

目录 1.背景分析 2.具体需求分析 3.前端设计 3.1 用户登录 3.2 头像昵称填写&#xff08;个人信息界面&#xff09; 4.后端设计 4.1项目架构分析 4.2 代码分析 实体类 dao层 service层 controller层 工具类 5.nginx部署 6.效果演示 1.背景分析 众所周知&#x…

【Distributed】分布式Ceph存储系统之相关应用

文章目录 一、创建 CephFS 文件系统 MDS 接口1. 服务端操作1.1 在管理节点创建 mds 服务1.2 查看各个节点的 mds 服务1.3 创建存储池&#xff0c;启用 ceph 文件系统1.4 查看mds状态1.5 创建用户 2. 客户端操作2.1 客户端要在 public 网络内2.2 在客户端创建工作目录2.3 在 cep…

相册搜索功能再升级?iOS17隐藏小细节曝光,关键字搜索视频声音

据博主Ryan McLeod的最新推文透露&#xff0c;iOS 17已经隐藏了一些小细节&#xff0c;其中包括相册搜索功能的改进。用户现在可以通过在iOS 17的相册中输入关键字来快速查找含有特定声音的视频片段&#xff0c;从而提供更便捷的用户体验。例如&#xff0c;输入动物叫声的关键字…

朴素贝叶斯与贝叶斯网络详解

文章目录 一、背景1.1 贝叶斯方法的提出1.2 频率派与贝叶斯派的区别 二、分类问题三、基础知识3.1 条件概率3.2 联合概率3.3 贝叶斯公式4.1 贝叶斯网络介绍4.2 贝叶斯网络的基本结构4.2.1 head-to-head&#xff08;共同作用&#xff09;4.2.2 tail-to-tail&#xff08;共同原因…

【北大是如何考DFS的】【我们一起60天准备考研算法面试(大全)-第十六天 16/60】【DFS】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

马斯克宣布成立xAI——引领开放人工智能时代的新纪元

马斯克宣布成立xAI——引领开放人工智能时代的新纪元 &#x1f7e2;一、前言&#x1f7e2;二、马斯克的背景与愿景&#x1f7e2;三、xAI的潜在研究方向&#x1f7e2;四、xAI面临的挑战&#x1f7e2;五、xAI的潜在影响&#x1f7e2;六、xAI与OpenAI的异同&#x1f7e2;七、对Ope…

人脸识别轻量版

github地址 https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB 下载后测试 前提是安装了pytorch环境&#xff0c;原始测试py文件是这个&#xff0c;是需要用命令行执行的 为了测试方便&#xff0c;我将它改成容易debug的 """ This c…

键入网址发生什么--基础网络知识

浏览器解析URL生成请求信息&#xff0c;发送给web服务器。 一、浏览器解析URL & 浏览器解析URL作用&#xff1a;确定了 Web 服务器和文件名 URL组成&#xff1a;http&#xff1a; // web服务器域名 /目录名/ / 目录名/ ....文件名 当没有具体文件路径名时&#xff…

SRT对比TCP协议的优缺点

主流的流媒体协议&#xff0c;如HTTP&#xff0c;HLS&#xff0c;RTMP是TCP协议&#xff0c;而RTSP既可以基于TCP也可基于UDP协议进行数据传输。 从趋势来看&#xff0c;新的流媒体协议大都选择UDP作为底层传输协议&#xff0c;其主要原因和流媒体业务本身的特性及TCP特性有关。…

[相遇 Bug] - ImportError: numpy.core.multiarray failed to import

背景: 因为最近在看点云模型, 在自己的环境上部署该项目: https://github.com/open-mmlab/OpenPCDet/tree/master 执行命令: 这里执行github项目给的demo.py文件, 命令格式如下: python demo.py --cfg_file cfgs/kitti_models/pointpillar.yaml --ckpt xxx/pointpillar_772…

找回删除的照片?这4招很简单!

“电脑上删除的照片还能找回来吗&#xff1f;我的照片刚刚被误删了很多张&#xff0c;现在想把它们恢复回来&#xff0c;还有成功的可能性吗&#xff1f;” 对于很多朋友来说&#xff0c;将照片保存下来是一件很美好的事。当我们想起某个场景时&#xff0c;我们能通过这些照片来…

Vue3 – 高级语法补充

1 Vue中自定义指令 2 Vue内置组件Teleport 3 Vue内置组件Suspense 4 Vue中安装插件的方式 5 Vue中渲染函数的使用 6 Vue中编写jsx的语法 Vue中自定义指令 自定义指令的绑定方法有两种&#xff0c;一种是局部的&#xff0c;一种是全局的。 指令可以将部分js代码转换成指令的…

前端 | (四)CSS基础及CSS选择器 | 尚硅谷前端html+css零基础教程2023最新

学习来源&#xff1a;尚硅谷前端htmlcss零基础教程&#xff0c;2023最新前端开发html5css3视频 文章目录 &#x1f4da;CSS基础&#x1f407;CSS简介&#x1f407;CSS编写位置⭐️行内样式⭐️内部样式⭐️外部样式 &#x1f407;样式表的优先级&#x1f407;CSS语法规范&#…

Appium 全新 2.0 全新跨平台生态,版本特性抢鲜体验!

关于Appium V2 Appium V2 beta版本在2021年发布&#xff0c;从2022年1月1号开始&#xff0c;Appium核心团队不会再维护Appium 1.x版本了&#xff0c;所有近期官方发布的平台驱动&#xff08;如Android平台的UIAutomator&#xff0c;IOS平台的XCUITest&#xff09;不再兼容Appi…

大数据分析案例-基于随机森林算法构建心力衰竭预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

云原生周刊:6 项 K8s 成本控制策略 | 2023.7.17

开源项目推荐 Base Image Finder 当使用容器扫描工具来识别已知漏洞&#xff08;CVE&#xff0c;或常见漏洞和暴露&#xff09;时&#xff0c;可能很难理解漏洞在容器中的位置&#xff0c;以及如何缓解这些漏洞。通常&#xff0c;最简单、最有效的缓解方法是更新 "基本映…

EasyPoi实战系列集合

历史文章&#xff08;文章累计480&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 导…