1. 程式人生 > 程式設計 >vue實現帶過渡效果的下拉選單功能

vue實現帶過渡效果的下拉選單功能

本文例項為大家分享了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="vue實現帶過渡效果的下拉選單功能">
 </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="vue實現帶過渡效果的下拉選單功能">
 </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,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元件學習教程進行學習。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。