Vue自定义指令使用方法详解 和 使用场景
Vue自定义指令的使用,具体内容如下
1.自定义指令的语法
Vue自定义指令语法如下:
- Vue.directive(id, definition)
传入的两个参数,id是指指令ID,definition是指定义对象。其中,定义对象可以提供一些钩子函数
钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
接下来我们来看一下钩子函数的参数 (即 el
、binding
、vnode
和 oldVnode
)。
钩子函数参数
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM 。binding
:一个对象,包含以下属性:vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
除了 el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset
来进行。
这是一个使用了这些属性的自定义钩子样例:
- Vue.directive('my-directive', {
- bind: function(){
- //做绑定的准备工作
- //比如添加事件监听器,或是其他只需要执行一次的复杂操作
- },
- inserted: function(){
- //...
- },
- update: function(){
- //根据获得的新值执行对应的更新
- //对于初始值也会调用一次
- },
- componentUpdated: function(){
- //...
- },
- unbind: function(){
- //做清理操作
- //比如移除bind时绑定的事件监听器
- }
官网文档:https://cn.vuejs.org/v2/guide/custom-directive.html
使用场景
- 代码复用和抽象的主要形式是组件
- 当需要对普通 DOM 元素进行底层操作,此时就会用到自定义指令
- 但是,对于大幅度的 DOM 变动,还是应该使用组件
3. 示例
3.1 输入框自动聚焦
- // 注册一个全局自定义指令 `v-focus`
- Vue.directive('focus', {
- // 当被绑定的元素插入到 DOM 中时
- inserted: function (el) {
- // 聚焦元素
- el.focus()
- }
- })
- <input v-focus>
3.2 下拉菜单
- 点击下拉菜单本身不会隐藏菜单
- 点击下拉菜单以外的区域隐藏菜单
- Vue.directive('clickoutside', {
- bind(el, binding) {
- function documentHandler(e) {
- if (el.contains(e.target)) {
- return false
- }
- if (binding.expression) {
- binding.value(e)
- }
- }
- el.__vueMenuHandler__ = documentHandler
- document.addEventListener('click', el.__vueMenuHandler__)
- },
- unbind(el) {
- document.removeEventListener('click', el.__vueMenuHandler__)
- delete el.__vueMenuHandler__
- }
- })
- new Vue({
- el: '#app',
- data: {
- show: false
- },
- methods: {
- handleHide() {
- this.show = false
- }
- }
- })
- <div class="main" v-menu="handleHide">
- <button @click="show = !show">点击显示下拉菜单</button>
- <div class="dropdown" v-show="show">
- <div class="item"><a href="#">选项 1</a></div>
- <div class="item"><a href="#">选项 2</a></div>
- <div class="item"><a href="#">选项 3</a></div>
- </div>
- </div>
3.3 相对时间转换
类似微博、朋友圈发布动态后的相对时间,比如刚刚、两分钟前等等
- <span v-relativeTime="time"></span>
- new Vue({
- el: '#app',
- data: {
- time: 1565753400000
- }
- })
- Vue.directive('relativeTime', {
- bind(el, binding) {
- // Time.getFormatTime() 方法,自行补充
- el.innerHTML = Time.getFormatTime(binding.value)
- el.__timeout__ = setInterval(() => {
- el.innerHTML = Time.getFormatTime(binding.value)
- }, 6000)
- },
- unbind(el) {
- clearInterval(el.innerHTML)
- delete el.__timeout__
- }
- })
3.4 滚动动画
- <div id="app">
- <h1 class="centered">Scroll me</h1>
- <div class="box" v-scroll="handleScroll">
- <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A atque amet harum aut ab veritatis earum porro praesentium ut corporis. Quasi provident dolorem officia iure fugiat, eius mollitia sequi quisquam.</p>
- </div>
- </div>
- Vue.directive('scroll', {
- inserted: function(el, binding) {
- let f = function(evt) {
- if (binding.value(evt, el)) {
- window.removeEventListener('scroll', f)
- }
- }
- window.addEventListener('scroll', f)
- }
- })
- // main app
- new Vue({
- el: '#app',
- methods: {
- handleScroll: function(evt, el) {
- if (window.scrollY > 50) {
- TweenMax.to(el, 1.5, {
- y: -10,
- opacity: 1,
- ease: Sine.easeOut
- })
- }
- return window.scrollY > 100
- }
- }
- })
- body {
- font-family: 'Abhaya Libre', Times, serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- background: #000;
- color: #fff;
- overflow-x: hidden;
- }
- h1,
- h2,
- h3,
- h4 {
- font-family: 'Fira Sans', Helvetica, Arial, sans-serif;
- font-weight:;
- }
- .centered {
- margin: 0 auto;
- display: table;
- font-size: 60px;
- margin-top: 100px;
- }
- .box {
- border: 1px solid rgba(255, 255, 255, 0.5);
- padding: 8px 20px;
- line-height: 1.3em;
- opacity:;
- color: white;
- width: 200px;
- margin: 0 auto;
- margin-top: 30px;
- transform: translateZ(0);
- perspective: 1000px;
- backface-visibility: hidden;
- background: rgba(255, 255, 255, 0.1);
- }
- #app {
- height: 2000px;
- }
自定义指令:
属性:
Vue.directive(指令名称,function(参数){
this.el -> 原生DOM元素
});
<div v-red="参数"></div>
指令名称: v-red -> red
* 注意: 必须以 v-开头
拖拽:
-------------------------------
自定义元素指令:(用处不大)
Vue.elementDirective('zns-red',{
bind:function(){
this.el.style.background='red';
}
});
------------------------------------------------
@keydown.up
@keydown.enter
@keydown.a/b/c....
自定义键盘信息:
Vue.directive('on').keyCodes.ctrl=17;
Vue.directive('on').keyCodes.myenter=13;
------------------------------------------------
Vue自定义指令使用方法详解 和 使用场景的更多相关文章
- Vue入门---事件与方法详解
一. vue方法实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- join() 方法详解及应用场景
总结:join方法的功能就是使异步执行的线程变成同步执行.也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用jo ...
- 每个人都能实现的vue自定义指令
前文 先来bb一堆废话哈哈.. 用vue做项目也有一年多了.除了用别人的插件之外.自己也没尝试去封装指令插件之类的东西来用. 刚好最近在项目中遇到一个问题.(快速点击按钮多次触发多次绑定的方法),于是 ...
- vue自定义指令,比onerror更优雅的方式实现当图片加载失败时使用默认图,提供三种方法
首先,来看下效果图(演示一下图片正常加载与加载失败时的效果) 在线体验地址:https://hxkj.vip/demo/vueImgOnerror/ 一.常规方法解决 我们都知道,img标签支持one ...
- vue自定义指令
Vue自定义指令: Vue.directive('myDr', function (el, binding) { el.onclick =function(){ binding.value(); } ...
- Vue插件编写、用法详解(附demo)
Vue插件编写.用法详解(附demo) 1.概述 简单来说,插件就是指对Vue的功能的增强或补充. 比如说,让你在每个单页面的组件里,都可以调用某个方法,或者共享使用某个变量,或者在某个方法之前执行一 ...
- AngularJS指令进阶 – ngModelController详解
AngularJS指令进阶 – ngModelController详解 在自定义Angular指令时,其中有一个叫做require的字段,这个字段的作用是用于指令之间的相互交流.举个简单的例子,假如我 ...
- Vue自定义指令使用场景
当你第一次接触vue的时候,一定会使用到其中的几个指令,比如:v-if.v-for.v-bind...这些都是vue为我们写好的,用起来相当的爽.如果有些场景不满足,需要我们自己去自定义,那要怎么办呢 ...
- 使用Vue自定义指令实现Select组件
完成的效果图如下: 一.首先,我们简单布局一下: <template> <div class="select"> <div class="i ...
随机推荐
- Nginx 简介与安装、常用的命令和配置文件
1.nginx 简介(1)介绍 nginx 的应用场景和具体可以做什么事情 (2)介绍什么是反向代理 (3)介绍什么是负载均衡 (4)介绍什么是动静分离 2.nginx 安装(1)介绍 nginx 在 ...
- Spring学习的第二天
第二天总共学习了以下内容: spring中的ioc常用注解: 案例使用xml方式和注解方式实现单表的CRUD操作(但还是需要xml配置文件,并不是纯注解的配置): 改造基于注解的Ioc案例,使用纯注解 ...
- 用python暴力破解压缩文件并不是万能,至少这个场景我告诉你密码你用代码也破解不了
看到论坛上各种贴子写用python进行暴力破解的文章,于是自己也想去尝试一下,不试不知道,一试吓一跳,真的就像那句有名的”python由入门到放弃“,把论坛上别人的脚本全部自己敲一遍,运行不报错,但也 ...
- 剑指Offer-40.数组中只出现一次的数字(C++/Java)
题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 我们知道,两个相同的数字异或的结果等于0,所以利用这个性质将数组中所有的数字异或,求得的结 ...
- E-factory
E-factory为生成XML和HTML提供了一种简单而紧凑的语法 # coding:utf-8 from lxml.builder import E def CLASS(*args): # clas ...
- c++实现通讯录管理系统(控制台版)
c++实现通讯录管理系统(控制台版) 此项目适合c++初学者,针对c++基础知识,涉及到变量.结构体定义使用.数组定义使用.指针定义使用等. 运行之后的结果如下: 代码: #include <i ...
- Spring Cloud Gateway、并发编程等等
2019年 JUC线程池服务ExecutorService接口实现源码分析 Github Page:http://www.throwable.club/2019/07/27/java-concurre ...
- Redis Cluster 集群三主三从高可用环境搭建
前言 Redis 是我们目前大规模使用的缓存中间件,由于它强大高效而又便捷的功能,得到了广泛的使用. Window环境下载地址:https://github.com/tporadowski/redis ...
- Linux ssh突然连接不了的案例浅析
公司的Linux服务器都是通过一台JumpServer跳转的.个人使用Jumpserver(开源跳板机系统)时,有时候由于需要上传.下载文件很不方便.而由于配置关系,一般情况无法使用SecureCRT ...
- tomcat修改进程名称
1.window平台: 打开tomcat_home\bin\setclasspath.bat文件,找到set _RUNJAVA=”%JRE_HOME%\bin\java”这一行. 将该行注释掉 ,然后 ...