Vue 中有许多的指令提供咱们使用。它可让你进行一些模版的操做。html
可是内置指令,在实际的开发过程当中可能这些并不能知足全部的需求。因此 Vue 给咱们提供来一个灵活的方法「自定义指令」。node
说自定义指令以前,先看看什么叫「指令」。express
指令是指能够控制操做 DOM 的一些小命令,一般以 v-
前缀出现的特殊特性。bash
例如咱们常用的v-if
、v-show
、v-bind
、v-on
、v-html
等。app
使用指令时,你能够传递值,字符串,也能够给指令添加参数,修饰符等等。好比:函数
1.传递值ui
<p v-if="isShow">你好,我是六哥</p>
let vm = new Vue({
el: "#app",
data: {
isShow: true
}
});
复制代码
2.字符串spa
<p v-text="'hello world'"></p>
复制代码
3.添加参数code
// class,style 就是传给指令的参数
<div v-bind:class="classObj"></div>
<div v-bind:style="classObj"></div>
复制代码
4.修饰符component
// prevent 指令的修饰符
<button v-on:submit.prevent="onSubmit"></button>
复制代码
以上是你常用指令的方式,了解这些以后,它能够帮助咱们更好的认识自定义指令的 一些参数问题。下面就来看看自定义指令。
指令的注册方式和「过滤器」、「混入」、「组件」注册的方式同样都分为两种:一是全局注册,二是局部注册。
1.全局注册
Vue.directive('name', {})
复制代码
2.局部注册
directives: {
name: {}
}
复制代码
而后在模版中直接使用便可。
<p v-name>你好,六哥在这</p>
复制代码
我我的更倾向于使用全局注册的方式,由于既然已经使用了自定义指令,应该是通用,可复用的。
因此提供整个项目使用的指令才更有价值,而不只仅只限于某个组件内部。若是单一地方使用直接把功能搂出就好了,何须费这力气。
继续来看具体的实现方式。
Vue 提供了自定义指令的几个钩子函数:
除update 与 componentUpdated 钩子函数以外,每一个钩子函数都含有 el
、binding
、vnode
这三个参数。
oldVnode
只有在 update 与 componentUpdated 钩子中生效。
参数el
就是指令绑定的 DOM 元素,而binding
是一个对象,它包含一下属性:name
、value
、oldValue
、expression
、arg
、modifiers
。
另外值得注意的一点是,除了 el
以外,binding
、vnode
属性都是只读的。
熟悉指令的建立方式与参数以后,咱们就用它来建立一个案例。
Loading 是项目中最多见的一个小功能,别看它功能小,可是起到的做用却很大,手动建立一个 Loading 指令。
Vue.directive("loading", {
bind(el, binding) {
if (binding.value) {
let div = document.createElement("div");
div.className = "loading-parent";
div.innerHTML = `
<div class="loading-spinner"><i class='el-icon-loading'></i></div>
`;
el.appendChild(div);
}
},
update(el, binding) {
if (binding.value) {
let div = document.createElement("div");
div.className = "loading-parent";
div.innerHTML = `
<div class="loading-spinner"><i class='el-icon-loading'></i></div>
`;
el.appendChild(div);
el.load = div;
} else {
el.load && el.load.parentNode && el.load.parentNode.removeChild(el.load);
}
}
});
复制代码
而后咱们直接就能够在模版中使用了。
<div v-loading="loading" class="box"></div>
复制代码
你也看出来了不少代码是重复的,怎么办呢?
Vue 中给咱们提供了简写方式。当只有这两个钩子函数时bind
与 update
,咱们能够简写以下。
Vue.directive("loading", function(el, binding) {
if (binding.value) {
let div = document.createElement("div");
div.className = "loading-parent";
div.innerHTML = `
<div class="loading-spinner"><i class='el-icon-loading'></i></div>
`;
el.appendChild(div);
el.load = div;
} else {
el.load && el.load.parentNode && el.load.parentNode.removeChild(el.load);
}
});
复制代码
咱们实现了一个很是简单的指令,但还不够灵活,好比我想添加 loading 的背景色,修改图标的颜色怎么办呢?
这时候就须要给指令传入多个值,改造下实现背景与图标颜色。
Vue.directive("loading", function(el, binding) {
if (binding.value) {
let div = document.createElement("div");
div.className = "loading-parent";
div.style.backgroundColor = binding.value.background;
div.style.color = binding.value.color;
div.innerHTML = `
<div class="loading-spinner"><i class='el-icon-loading'></i></div>
`;
el.appendChild(div);
el.load = div;
} else {
el.load && el.load.parentNode && el.load.parentNode.removeChild(el.load);
}
});
复制代码
直接使用
<div v-loading="{color: 'white', background: '#000'}">我能够拥有更多属性</div>
复制代码
在文章开始咱们介绍指令时,还说到指令的「参数」与「修饰符」这里我就很少介绍了,你们不妨本身去尝试一下吧。体验下自定义指令的魅力。
若是文章对你有启发,记得给个赞哦。
公众号:六小登登,更多干货文章。
人人均可以成为高手。一个爱写做的技术人。欢迎交流。