【注】觉着原作者文章很好,怕以后找不到,便存起来,希望不要介意
作者:IT风火轮
来源:优快云
原文:https://blog.youkuaiyun.com/ITFENGHUOLUN/article/details/90320047
Vue 中有许多的指令提供我们使用。它可以让你进行一些模版的操作。
但是内置指令,在实际的开发过程中可能这些并不能满足所有的需求。所以 Vue 给我们提供来一个灵活的方法「自定义指令」。
说自定义指令之前,先看看什么叫「指令」。
指令的概念
指令是指可以控制操作 DOM 的一些小命令,通常以 v- 前缀出现的特殊特性。
例如我们经常使用的v-if、v-show、v-bind、v-on、v-html等。
使用指令时,你可以传递值,字符串,也可以给指令添加参数,修饰符等等。比如:
1.传递值
<p v-if="isShow">你好,我是**</p>
let vm = new Vue({
el: "#app",
data: {
isShow: true
}
});
2.字符串
<p v-text="'hello world'"></p>
3.添加参数
// class,style 就是传给指令的参数
<div v-bind:class="classObj"></div>
<div v-bind:style="classObj"></div>
4.修饰符
// prevent 指令的修饰符
<button v-on:submit.prevent="onSubmit"></button>
以上是你经常使用指令的方式,了解这些之后,它可以帮助我们更好的认识自定义指令的 一些参数问题。下面就来看看自定义指令。
自定义指令
指令的注册方式和「过滤器」、「混入」、「组件」注册的方式一样都分为两种:一是全局注册,二是局部注册。
1.全局注册
Vue.directive('name', {})
2.局部注册
directives: {
name: {}
}
然后在模版中直接使用即可。
<p v-name>你好,***在这</p>
我个人更倾向于使用全局注册的方式,因为既然已经使用了自定义指令,应该是通用,可复用的。
所以提供整个项目使用的指令才更有价值,而不仅仅只限于某个组件内部。如果单一地方使用直接把功能搂出就行了,何必费这力气。
继续来看具体的实现方式。
Vue 提供了自定义指令的几个钩子函数:
bind:指令第一次绑定到元素时调用,只执行一次。
inserted:被绑定的元素,插入到父节点的 DOM 中时调用。
update:组件更新时调用。
componentUpdated:组件与子组件更新时调用。
unbind:指令与元素解绑时调用,只执行一次。
除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>
1
你也看出来了很多代码是重复的,怎么办呢?
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>
作者:IT风火轮
来源:优快云
原文:https://blog.youkuaiyun.com/ITFENGHUOLUN/article/details/90320047
版权声明:本文为博主原创文章,转载请附上博文链接!