一,封装蒙层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 插槽
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
不够完善,未完待续