vue实现带过渡效果的下拉菜单功能
作者:szjSmiling 发布时间:2024-05-09 15:18:47
标签:vue,下拉菜单
本文实例为大家分享了vue仿写下拉菜单功能,带有过渡效果(移动端),供大家参考,具体内容如下
效果图
clickOutside.js 点击目标之外的地方,下拉框隐藏
代码如下:
export const clickOutside = {
bind(el, binding, vnode) {
function documentHandler(e) {
if (el.contains(e.target)) {
return false;
}
if (binding.expression) {
binding.value(e);
}
}
el.__vueClickOutside__ = documentHandler;
document.addEventListener("click", documentHandler);
},
update() {},
unbind(el, binding) {
document.removeEventListener("click", el.__vueClickOutside__);
delete el.__vueClickOutside__;
}
};
正文html如下:
<div class="info-select">
<div class="select">
<p class="select-p" @click="showSelectUl('s1')" v-clickOutside="hideSelectUl">
<span>{{issues}}</span>
<img :src="require('../../assets/images/support/icon_xiala.png')" alt="">
</p>
<transition name="slide-fade">
<div class="select-ul" v-show="!showIssues" >
<div v-for="(item, index) in list" :key="index" >
<div>{{item.class}}</div>
<div v-for="(item1, i) in item.node" :key="i" @click="getSize('s1', item1.class, index, i)">
<p :class="{active:item == issues}">{{item1.class}}</p>
</div>
</div>
</div>
</transition>
<transition leave-active-class="slideOutRight" enter-active-class="slideInRight">
<p class="animated errP" style="position: absolute;margin:0.2rem 0 0 -3%;" v-show="form.issueErr" >{{form.issueMsg}}</p>
</transition>
</div>
<div class="select">
<p class="select-p" @click="showSelectUl('s2')" v-clickOutside="hideSelectUl2">
<span>{{issues2}}</span>
<img :src="require('../../assets/images/support/icon_xiala.png')" alt="">
</p>
<transition name="component-fade" mode="out-in">
<div class="select-ul" v-show="!showIssues2">
<p v-for="(item, index) in childList" :class="{active:item == issues2}"
:key="index" @click="getSize('s2', item.class, index)">{{item.class}}</p>
</div>
</transition>
<transition leave-active-class="slideOutUp" enter-active-class="slideInUp">
<p class="animated errP" style="position:absolute;margin:0.2rem 0 0 -3%;" v-if="form.issueErr1" >{{form.issueMsg1}}</p>
</transition>
</div>
</div>
<div class="p-bts clearafter">
<button @click="form.issueErr = !form.issueErr">p1</button>
<button @click="form.issueErr1 = !form.issueErr1">p2</button>
</div>
js 代码如下:
import { clickOutside } from 'Models/clickoutside.js';
export default {
data(){
return{
catogery:'flight',
issues:"Select Category",
issues2:"Select Issue",
showIssues:true,
showIssues2:true,
list:[
{id:0,class:'flight',node:[
{class:'1.1 a1111111111111 11111111111111',node:[
{class:'问题a1?'},
{class:'问题a2?'}
]},
{class:'1.2 a2',node:[
{class:'问题a3?'},
{class:'问题a4?'}
]},
]},
{id:1,class:'hotel',node:[
{class:'1.1 b1',node:[
{class:'问题b1?'},
{class:'问题b2?'}
]},
{class:'1.2 b2',node:[
{class:'问题b3?'},
{class:'问题b4?'}
]},
]},
],
childList:[],
form:{
issueMsg:"Please select a category",issueErr:true,
issueMsg1:"Please select a issue",issueErr1:true,
},
}
},
methods: {
hideSelectUl(){
this.showIssues = true;
},
hideSelectUl2(){
this.showIssues2 = true;
},
showSelectUl(s){
if(s == 's1'){
this.showIssues = !this.showIssues;
this.showIssues2 = true;
}else{
this.showIssues = true;
this.showIssues2 = !this.showIssues2;
}
},
getSize(s, val, index, index2){
if(s == 's1'){
this.issues = val;
this.showIssues = true;
this.catogery = this.list[index].class;
this.childList = this.list[index].node[index2].node;
this.issues2 = 'Select Issue';
}else if(s == 's2'){
this.issues2 = val;
this.showIssues2 = true;
}
},
},
directives:{
clickOutside,
}
}
css代码如下:
.info-select{
display: flex;
justify-content: space-between;
.select{
width:40%;
position: relative;
padding:0.1rem 3% 0.1rem;
vertical-align: top;
font-size: 0.15rem;
border-radius:2px;
background: #fff;
border-top:1px solid #ddd;
border-bottom:1px solid #ddd;
border-right:1px solid #ddd;
}
.select:last-child{
border-right:0;
border-top:1px solid #ddd;
border-bottom:1px solid #ddd;
border-left:1px solid #ddd;
}
.select-p{
position: relative;
height:0.21rem;
line-height:0.21rem;
span{
font-size: 0.16rem;
display: inline-block;
width:90%;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
img{
display:block;
width:0.12rem;
position: absolute;
right: 0;
top: 0;
vertical-align: middle;
}
}
.select-ul{
width:93.5%;
padding:0.12rem 3%;
position: absolute;
top: 0.42rem;
left: 0;
z-index: 12;
background: #fff;
border:1px solid #eee;
p{
padding:0.1rem 0 0.1rem 0.1rem;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
p:hover{
background: #eee;
}
p.active{
background: #eee;
}
}
.errP{
color:#f00;
}
}
.p-bts{
margin-top: 0.4rem;
zoom: 1;// zoom(IE转有属性)可解决ie6,ie7浮动问题
button{
width:1.5rem;
height:0.4rem;
background: #ffa000;
float: left;
color:#fff;
font-size:0.25rem;
border-radius:2px;
}
button:last-child{
float: right;
}
}
.component-fade-enter-active, .component-fade-leave-active {
transition: opacity .3s ease;
}
.component-fade-enter, .component-fade-leave-to
/* .component-fade-leave-active for below version 2.1.8 */ {
opacity: 0;
}
// css animate
.slide-fade-enter-active{
transition:all .2s ease-in;
}
.slide-fade-leave-active {
transition: all .2s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to{
/* .slide-fade-leave-active for below version 2.1.8 */
transform: translateY(20px);
opacity: 0;
}
// bounce
.bounce-enter-active {
animation: bounce-in .2s;
}
.bounce-leave-active {
animation: bounce-in .1s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1);
}
100% {
transform: scale(1);
}
}
查看完整代码
更多教程点击《Vue.js前端组件学习教程》,欢迎大家学习阅读。
关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。
来源:https://blog.csdn.net/szjSmiling/article/details/84836910


猜你喜欢
- 目录Counter举例实战sortedallF-strings总结Python中冷门但非常好用的内置函数 Counter举例 实战sorte
- function getBytesLength(str){ var re=/[\x00-\xf
- 在本篇文章里,我们会使用一个简单的Web表单,它会列出某个目录下的一些XML文件。然后,我们会从这个目录里选择一个文件,将它发送到另一个We
- 1 为什么需要防抖和节流在前端开发当中,有些交互事件,会被频繁触发,这样会导致我们的页面渲染性能下降,如果频繁触发接口调用的话,会直接导致服
- 在web开发的时候我们经常会遇到网页抓取和分析,各种语言都可以完成这个功能。我喜欢用python实现,因为python提供了很多成熟的模块,
- 1.单列运算在Pandas中,DataFrame的一列就是一个Series, 可以通过map来对一列进行操作:df['col2
- 前言提示:这里可以添加本文要记录的大概内容:将一个EXCEL等份拆成多个EXCEL将多个小EXCEL合并成一个大EXCEL并标记来源提示:以
- 1.准备工作: 准备相关的软件(Eclipse除外,开源软件可以从官网下载)<1>.Microsoft SQL server 2
- 最近工作中慢慢开始用python协程相关的东西,所以用到了一些相关模块,如aiohttp, aiomysql, aioredis等,用的过程
- 当然,如果你的网站文章中有图片,那么请记得一定要打上自己的LOGO,而且这个LOGO不要固定在这些图片的某个角落里,一定要随机出现在图片的任
- 如下所示:#tensorflow 中从ckpt文件中恢复指定的层或将指定的层不进行恢复:#tensorflow 中不同的layer指定不同的
- 一、定时器概述window对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和window.setInter
- 🚩 前言本次实现了一个在浏览器中运行的简陋的人脸检测功能,由于水平有限,这里使用表单上传图片,只能一次检测一张人脸。实现过程中遇到的主要问题
- Vue项目遇到要表单验证了吧,对我来说表单验证是个很纠(dan)结(teng)的内容,各种判断凌乱到飞起。往常使用jquery的valida
- 如下所示:#ltp_data 字符串 写进777.txt1、def save(filename, contents): fh = open(
- 前言文章包括下几点:考点--操作SQLite数据库:创建SQLite数据库;向表中插入记录;其他数据库操作。面试题:1.面试题一:如何创建S
- 前言MYSQL Command Line Client是一款用于输入密码的程序,相信大多数用户在使用这款程序的时候都有遇到这样的一种情况吧?
- 问题:这里只解决一个问题,到底什么是Access?设计一个数据库管理系统,用access在access里面设计好表,查询,然后再用vb做窗体
- php魔术方法在php类保留方法中以 “__”两个下划线开头的函数称为魔术方法,我的理解为php类设
- 环境准备创建QQ互联应用创建一个QQ互联应用,并获取到App ID和App Key。QQ互联官网:https://connect.qq.co