uni-app 入门小白纯徒手编写组件 hello-popup

我的需求是:弹出框顶部有 title,底部有确认和取消按钮。这两部分固定,中间部分 content 的高度随自身内容会动态增长,但是它最大高度不能超过父节点 bg 的 80%,而父节点 bg 的高度也是随自身内容动态变化,但最大高度又不能超过其父 cover 的 80%

<template>
	<view v-if="showHello" :class="['cover', ani]" @tap.stop="show(false)">
		<view :class="['bg', 'translateCenter', ani]" @tap.stop="clear">
			<view class="title">
				{{title}}
			</view>
			<view class="content">
				<slot />
			</view>
			<view class="btn" >
				<button class="btn-item" type="default" @tap="show(false)">取消</button>
				<button class="btn-item" type="primary" @tap="confirm">确定</button>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: "helloPopup",
		props: {
			title: {
				type: String,
				default: 'title',
			},
		},
		watch: {
			title(newValue, oldValue) {
				console.log('title:', newValue, oldValue)
			},
		},
		created(e) {},
		data(){
			return {
				showHello: false,
				ani: '',
			}
		},
		methods: {
			show(b){
				if(b){
					this.showHello = true
					this.$nextTick(() => {
						setTimeout(() => {
							this.ani = 'ani'
						}, 30)
					})
				}else{
					this.ani = ''
					this.$nextTick(() => {
						setTimeout(() => {
							this.showHello = false
						}, 300)
					})
				}
			},
			clear(){},
			confirm(){
				this.$emit('confirm')
			},
		},
	}
</script>

<style>
@charset "UTF-8";

*{margin:0;padding:0}
.translateCenter{ position: absolute; left:50%; top:50%; transform:translate(-50%,-50%); }
.cover{
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 99999;
	background: rgba(0, 0, 0, .4);
	opacity: 0;
	transition: all .3s;
}
.cover.ani{
	opacity: 1;
}
.bg{
	max-height: 3%;
	width: 3%;
	opacity: 0;

	transition: all .3s;
}
.bg.ani{
	max-height: 80%;
	width: 80%;
	opacity: 1;

	display: flex;
	flex-direction: column;
	background-color: #FFFFFF;

	border-radius: 16upx;
	padding: 24upx 24upx;
	overflow: hidden;
}
.content{
	width: 100%;
	max-height: 80%;
	overflow:auto;
}
.title{
	text-align: center;
	font-size: 38upx;
}
.btn{
	display: flex;
	flex-direction: row;
	justify-content: center;

	align-items: center;
	align-content: center;

	vertical-align: middle;
	margin-top: 40upx;
	margin-bottom: 20upx;
	/* background-color: #00CE47; */
}
.btn.btn-item{
	flex: auto;
	max-width: 40%;
}
</style>

如此这般调用:

<template>
	<view>
		<button @tap="show">你敢点我吗</button>

		<hello-popup ref="fuck" :title="popuptitle" @confirm="onConfirm">
			<block v-for="(v,index) in 10" :key="index">
				<view>item {{index}}</view>
			</block>
			<view>
				备注:备注,备注,备注,备注,备注
			</view>
		</hello-popup>
	</view>
</template>

<script>
	import helloPopup from '@/components/hello-popup/hello-popup.vue'

	export default {
		components: {
			helloPopup,
		},
		data() {
			return {
				popuptitle: '',
			}
		},
		methods: {
			show(){
				this.popuptitle = "hangj.cnblogs.com"

				this.$refs.fuck.show(true)
			},
			onConfirm(e){
				console.log('confirmed!')
				this.$refs.fuck.show(false)
			},
		}
	}
</script>

<style>
</style>

欢迎留言~

posted on 2019-09-04 16:53  明天有风吹  阅读(2293)  评论(0编辑  收藏  举报

导航

+V atob('d2h5X251bGw=')

请备注:from博客园