使用Vue自定义指令实现Select组件

本篇文章教大家写一个非常简单的Select组件,想必很多人都写过Select,毕竟它太常用了,但是本篇文章的示例使用到了Vue的自定义指令,如果你对Vue自定义指令不怎么熟悉的话,本篇文章或许会让您有所收获!

完成的效果图如下:

使用Vue自定义指令实现Select组件

 

一、首先,我们简单布局一下:

<template> <div> <div> <div> <input type="text" readonly placeholder="请选择菜品"> <span></span> </div> <ul> <li v-for="(item, index) in options" :key="index">{{item.value}}</li> </ul> </div> </div> </template> ...... data() { return { options: [ { value: '西红柿鸡蛋' }, { value: '青椒抱鸡蛋' }, { value: '回锅肉' }, { value: '宫保鸡丁' }, { value: '地三鲜' } ], } }

效果是这样:

使用Vue自定义指令实现Select组件

 

下面可供选择的options用的是绝对定位;同时input设置了readonly,使input变的不可输入,整体布局很简单。

二、开始添加功能

接下来,我们要添加两个功能:

点击上面的input框,可以切换显示下面的options

选择options里的某个选项后让它展示在input里,同时让选项部分消失

这两项目功能都挺简单,先来完成第一个,点击input框切换显示options,借助v-show就好。

<div @click="showOptions = !showOptions"> <input type="text" readonly placeholder="请选择菜品"> <span></span> </div> <ul v-show="showOptions" v-show="showOptions"> //添加v-show <li v-for="(item, index) in options" :key="index">{{item.value}}</li> </ul> ...... data() { showOptions: false }

如上所示,在选项里添加 v-show="showOptions" 并将 showOptions 初始化为 false 。同时,在包裹 input 的 div 上添加 click 事件来回切换 showOptions 的布尔值。

效果如下:

使用Vue自定义指令实现Select组件

 

第二个,点击下面的选项,将被选择的展示到input里,同时让options消失,也不难。

<div @click="showOptions = !showOptions"> <input type="text" readonly placeholder="请选择菜品" :value="selected"> //这里用value绑定一个data值selected <span></span> </div> <ul v-show="showOptions"> <li v-for="(item, index) in options" :key="index" @click="choose(item.value)">{{item.value}}</li> </ul> ...... data() { return { ...... showOptions: false selected: '' } }, methods: { choose(value) { this.showOptions = false if (value !== this.selected) { this.selected = value } } }

逻辑很简单,在input里用value绑定一个data值,点击选择某个选项后,将选项的内容赋给这个data值即可,同时,隐藏整个选项内容。

效果如下:

使用Vue自定义指令实现Select组件

 

从上面的效果图中可以看到,已经可以正常选择了,但是有一个问题,就是它选项内容展示的时候,我们希望点击其它空白的地方也可以让选择内容隐藏,但是上面的代码并没有解决这个问题,接下来我们来用两种办法来解决它。

3、常规的DOM操作 VS Vue自定义指令

其实,实现这个功能并不难,只是要想解决它就需要操作DOM

<div @click.stop="showOptions = !showOptions"> //注意这里的stop修饰器 <input type="text" readonly placeholder="请选择菜品" :value="selected"> <span></span> </div> <ul v-show="showOptions"> <li v-for="(item, index) in options" :key="index" @click.stop="choose(item.value)">{{item.value}}</li> //还有这里的stop修饰器 </ul> ... data() { return { ...... showOptions: false } } mounted() { let that = this document.addEventListener('click', function() { that.showOptions = false }) }

上面的代码有两点:一个是在mounted后面给整个document添加了点击事件,这样在点击时候就可以将options隐藏,但是,我们在点击输入框部分和选项内容时,我们不希望它触发,而是让它走我们之前写好的逻辑,所以给两个 click 事件都添加了 stop 修饰器来阻止冒泡,这样,点击到它们的时候就不会冒泡到 document 上面了。效果如下:

使用Vue自定义指令实现Select组件

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e275a4e71818c1ea38c4d16b75bfc12f.html