详解Vue用自定义指令完成一个下拉菜单(select组件)

前端之家收集整理的这篇文章主要介绍了详解Vue用自定义指令完成一个下拉菜单(select组件)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

这次分享的是关于Vue自定义指令的使用方法,学习完基础后我们再来实战完成一个下拉列表,废话不多说,直接上干货

基本用法

注册 Vue.directive('my-directive',{ // 指令选项 })

// 局部注册
var app = new Vue({
el: '#app'
directives: {
'my-directive': {
// 指令选项
}
})

相信对Vue比较熟悉的人看完都知道,directive的写法与组件 基本类似,只是方法名由component改为了directive。上例只是注册自定义指令v-my-directive,还没实现具体功能,下面具体介绍 自定义指令的各个选项。

指令定义函数提供了几个钩子函数 (可选):

  1. bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  2. inserted:被绑定元素插入父节点时调用 (父节点存在即可调用,不必存在于 document 中)。
  3. update:所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
  4. componentUpdated:所在组件的 VNode 及其孩子的 VNode 全部更新时调用
  5. unbind:只调用一次,指令与元素解绑时调用

可根据需求在不同的钩子函数 内完成逻辑代码,如下面v-focus,我们希望在元素插入父节点时就调用,那用到的最好的就是inserted了。示例代码如下

// js部分 Vue.directive('focus',{ // 当绑定元素插入到 DOM 中。 inserted: function (el) { // 聚焦元素 el.focus() } })

效果如下图所示

自定义指令 v-focus.png

可以看到,打开这个页面,input输入框就自动获取焦点了,成为可输入状态。

每个钩子函数 都可以有几个参数可用,比如我们上面用到了el。它们 的含义如下:

  1. el:指令所绑定的元素,可以用来直接操作 DOM 。
  2. binding:一个对象,包含以下属性
    1. name:指令名,不包括 v-前缀。
    2. value:指令的绑定值,例如:v-my-directive="1 + 1",value 的值是 2。
    3. oldValue:指令绑定的前一个值,仅在 update和 componentUpdated钩子中可用。无论值是否改变都可用。
    4. expression:绑定值的字符串形式。例如 v-my-directive="1 + 1" ,expression 的值是 "1 + 1"。
    5. arg:传给指令的参数。例如 v-my-directive:foo,arg 的值是 "foo"。
    6. modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar,修饰符对象 modifiers 的值是 { foo: true,bar: true }。
  3. vnode:Vue 编译生成的虚拟节点,查阅 VNode API 了解更多详情。
  4. oldVnode:上一个虚拟节点,仅在 update和 componentUpdated钩子中可用。

下面是结合了以上参数 的一些具体示例,代码如下

// JS部分 Vue.directive('demo',{ bind: function (el,binding,vnode) { var s = JSON.stringify el.innerHTML = 'name: ' + binding.name + '
' + 'value: ' + binding.value + '
' + 'expression: ' + binding.expression + '
' + 'argument: ' + binding.arg + '
' + 'modifiers: ' + JSON.stringify(binding.modifiers).modifiers + '
' + 'vnode keys: ' + Object.keys(vnode).join(',') } }) new Vue({ el: '#app',data: { message: 'some text' } })

执行后,

内容会使用innerHTML重置,结果为

Meta,isAsyncPlaceholder

在多数使用场景,我们会在bind钩子里绑定一些事件,比如在document上用addEventListerer绑定,在unbind里有 removeEventListener 解绑,比较典型的示例就是让这个元素随着鼠标拖拽。

如果需要更多个值,自定义指令也可以传入一个JavaScript对象字面量, 只要是合法类型的JavaScript表达式都是可以的。示例代码如下:

//JS部分
Vue.directive('test',vnode) {
console.log(binding.value.msg)
console.log(binding.value.name)
}
})
var app = new Vue({
el: '#app'
})

Vue 2.x很移除大量Vue 1.x自定义指令的配置。在使用自定义指令时,应该充分解业务需求,因为很多时候你需要的可能并不是自定义指令,而是组件。

基础的东西讲完了,我们来根据directive提供的API来写一个点击外部区域可以让其下拉列表消失的菜单

显示下拉菜单

// JS部分
var app = new Vue({
el: '#app',data: {
show: false
},
methods: {
handleClose() {
this.show = false;
}
}
})

Vue.directive('clickoutside',{
bind: function(el,vode) {
function documentHandler (e) {
if (el.contains(e.target)) {
return false
}
if (binding.expression) {
binding.value(e)
}
}
el.vueClickOutSide = documentHandler
document.addEventListener('click',documentHandler)
},unbind: function(el,binding) {
document.removeEventListener('click',el.vueClickOutSide)
delete el.vueClickOutSide
}
})

要在document上绑定click事件,所以在bind钩子内声明了一个函数documentHandler,并将它作为句柄定在document的click事件上。documentHandler函数做了两个判断,第一个是判断点击的区域是否是指令所在的元素内部,如果是,就跑出函数,不信下继续执行

contains方法是用来判断元素A是否包含了元素 B,包含返回true,不包含返回false

// JS var a = doucment.getElemengById('parent') var b = doucment.getElemengById('children') console.log(A.contains(B)) // true console.log(B.contains(A)) // false

第二个判断是当前 的指令v-clickoutside有没有写表达式,在该自定义指令中,表达 式应该是第一个函数 ,在过滤了内部元素后,点击外面任何区域应该招待用户表达 式中的函数 ,所以binding.value就用来执行上下文methods中指定的函数

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

原文链接:https://www.f2er.com/vue/35445.html

猜你在找的Vue相关文章