当前位置: 代码迷 >> 综合 >> vue 封装 下拉选择框 actionSheet, dropDown ,类似mint-ui中的actionSheet
  详细解决方案

vue 封装 下拉选择框 actionSheet, dropDown ,类似mint-ui中的actionSheet

热度:9   发布时间:2024-01-10 00:20:54.0

一,封装蒙层Popup 框---带淡入淡出渐变效果的

<template>
    <transition name="rytpopup-transition">
        <div class="rytPopup" v-show="visible" @click="closeRytpopup">
            <slot></slot>
        </div>
    </transition>
</template>
<!--  slot 意为插槽 里面可以放任何标签 -->
<script>
 export default {
     name:"rytPopup",
     props:{
         center:{
             type: Boolean,
             default:false    
         }
      
     },
    data(){
        return{
            visible:false,     
        }
       
    },
    methods:{
        closeRytpopup(){
            this.visible = false
        },

    },
    watch:{
        visible(val){
           this.$emit('input',val)  //当visible的值发生改变的时候,把val(viaible的值)传给父组件的v-model属性
        },
          center(val){ //当center的值发生改变的时候,把center的val值传给this.viaible
            this.visible = val
          }    

    },
 }
</script>
<style scoped>
    .rytPopup {
      position: fixed;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      opacity: 0.5;
      background-color: #000
    }
    /*利用vue 的transition 中的过渡实现背景色的opacity 的值在0 和1之间的过渡*/
  .rytpopup-transition-enter-active, .rytpopup-transition-leave-active {
      transition: opacity .5s;
    }
    .rytpopup-transition-enter, .rytpopup-transition-leave-to /* .fade-leave-active below version 2.1.8 */ 
    {
      opacity: 0;
    }
</style>

 

二,封装 dropdown下拉选择框

<template>
  <div>
    <!--     蒙层组件,此处是父组件开始 -->
    <ryt-popup :center="currentValue" v-model="currentValue">
    </ryt-popup>
    <!--     蒙层组件,此处是父组件结束 -->
    <!-- 下拉选择弹框组建封装 开始 -->
    <transition name="ryt-transition">
            <div class="ryt-actionsheet" v-show="currentValue">
                <p class="rytTitle parent">{ {title}}</p>
                <ul style="border-bottom-right-radius: 12px;border-bottom-left-radius:12px;background-color: #fff">
                    <li class="ryt-mint-actionsheet-listitem parent" @click="clickItem(item,index)" v-for="(item,index) in actions">{ {item}}</li>
                </ul>
                <button class="ryt-mint-actionsheet-button parent" @click="closeRytDropdown" :style="{color:cancenTextColor}">{ {cancelText}}</button>
            </div>
    </transition>
    <!-- 下拉选择弹框组建封装 结束 -->
 </div>
</template>

<script>
    import rytPopup from './rytPopup.vue';  //popup蒙层框
    export default {
      name:"rytDropdown",
      components:{
        rytPopup
      },
      props:{
          title:{
              type:String,
              default:'请选择您将进行的操作'
          },
          actions:{
              type:[Array,String,Object], //传过来的参数可以为对象,字符串,数组
              default:() => []
          },
          cancelText:{
              type:String,
              default:'取消'
          },
          center:{ //接受父组件给子组件的center属性的传值
              type:Boolean,
              default:false
          },
          cancenTextColor:{   //取消按钮的文字颜色
            type:String,
              default:'rgb(255, 130, 0)'
          }

      },
      data(){
          return {
              currentValue:false,
          }

      },
      methods:{
          closeRytDropdown(){  //关闭子组件
           this.currentValue = false
          },
          clickItem(item,index){ //选择下拉框选项
              this.$emit('clickOption',{
                  item:item,
                  index:index
              })
            
           this.currentValue = false
          }
      },
      watch: {
      currentValue(val) {  //监听currentValue的值传给父组件,父组件没有Input事件为什么还传值给父组件了?解释: v-model 绑定的是input事件
         this.$emit('input', val);
       },
      center(val){  //监听父组件通过props传过来的center的布尔值打开子组件下拉框
          this.currentValue = val

      }
      
     },
     mounted() {
         
    },

    }
</script>
<style scoped>
      .ryt-actionsheet{
         position: fixed;
          width: 355px;
          border-radius: 12px;
          text-align: center;
          bottom: 0;
          left: 50%;
          max-height: 100%;
          overflow-y: auto;
          transform: translate3d(-50%, 0, 0);
          backface-visibility: hidden;
          transition: transform .3s ease-out;
         }
         .rytTitle{
              color:#999999;
              font-size: 16px;
              height:44px;
              line-height: 44px;
              background-color: #fff;
             }
         .parent{
           position: relative;
         }
         .parent::after {  /*利用缩放和伪元素解决1px在不同手机有粗有细问题*/
          margin:auto auto;
          width:355px;
          position: absolute;
          bottom: 0;
          left: 0;
          right: 0;
          content: "";
          box-sizing: border-box;
          height: 1px;
          border-bottom: 1px solid #e8e8e8;
          
          transform: scaleY(0.5);
          transform-origin: 0 0;
        }
         .ryt-mint-actionsheet-listitem, .ryt-mint-actionsheet-button{
        display: block;
        width: 100%;
        height: 44px;
        line-height: 44px;
        font-size: 18px;
        color: #333;
        }
        .ryt-mint-actionsheet-button{
         margin-top:11px;
         border-radius: 12px;
         background-color: #fff;
         }
         /*弹窗动画*/
          .ryt-transition-enter,
          .ryt-transition-leave-active {
            transform: translate3d(-50%, 100%, 0);
          }
</style>

 

三,具体页面中的引用dropdown组件

<template>
  <div class="about marquee">
  
   <!-- 自定义dropDown组件 -->
     <ryt-dropdown
      v-model="rytDropdown"
      :actions="actions"
      :center="rytDropdown"
      @clickOption="chooseOption"
      title="请选择您的提示语"
      cancelText="关闭/取消"
      cancenTextColor="rgb(255, 130, 0)"
      >
    </ryt-dropdown>

     <button @click="clickRyt">点击Rytdropdown</button>

  </div>
</template>

<script>
import rytDropdown from '../../components/dropDown/rytDropdown.vue';  //下拉框带popup蒙层
export default {
   name:'cece',
   components: { //注册组件
    rytDropdown,
  },
 
  data() {
    return {
     actions: {  //下拉框选项
          "1": "半年以内",
          "2": "半年至一年",
          "3": "一年至上",
        },
     rytDropdown:false,
    };
  },
  methods: {
     //rytdropdown
     clickRyt(){
        this.rytDropdown = true
        
     },
     chooseOption(e){ //选中下拉框中的某一项出发的事件
      console.log(e,'chooseOption')
     }
  
  },
  mounted(){
    
  },
  watch:{
 
  }


 }
</script>


<style scoped>

</style>

四,大概效果如下

五,需要掌握知识点
父子组件之间的传值  slot 插槽

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

不够完善,未完待续

  相关解决方案