| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 | <template>	<view v-if="visible" :class="CssSheet" :style="[StyleSheet]" class="ax ax-popup">		<view @animationend="animationend()" class="__body"><slot></slot></view>		<view v-if="maskEnable || maskClose" @click="mask()" class="__mask"></view>	</view></template><script>	export default {		name:"ax-popup",		emits: [			// 打开弹窗			'open',			// 已打开弹窗			'opened',			// 关闭窗口			'close',			// 已关闭窗口			'closed',			// 幕布被点击			'mask'		],		props:{			// 内容方位 [默认居中 | top 上方 | left 左边 | right 右边 | bottom 下方]			position:{type:String,default:''},			// 启用幕布			maskEnable:{type:Boolean,default:false},			// 幕布类型 [默认透明 | black 黑色 | white 白色]			maskType:{type:String,default:''},			// 幕布模糊			maskBlur:{type:[Number,String],default:0},			// 幕布关闭			maskClose:{type:Boolean,default:false},		},		data() {			return {				// 组件可视性				visible: false,				// 关闭动画				closing: false			};		},		computed:{			CssSheet(){				return [					this.position,					this.maskType,					this.closing?'close':'',				]			},			StyleSheet(){				return {					'--mask-blur': `blur(${this.maskBlur}px)`,				}			}		},		methods:{			animationend(e){				if(this.visible==true && this.closing==false){					this.$emit('opened');				}else{					this.visible = false;					this.closing = false;					this.$emit('closed');				}			},			mask(){				if(this.maskClose) this.close();				this.$emit('mask');			},			close(){				this.closing = true;				this.$emit('close');			},			open(){				this.visible = true;				this.closing = false;				this.$emit('open');			}		}	}</script><style scoped>.ax-popup{	--duration: 150ms;	--mask-background: transparent;		display: flex;	align-items: center;	justify-content: center;	flex-direction: column;	transform-style: preserve-3d;	position: fixed;	top: 0;	left: 0;	right: 0;	bottom: 0;	z-index: 99999;}.ax-popup .__mask{	position: absolute;	top: 0;	left: 0;	right: 0;	bottom: 0;	backdrop-filter: var(--mask-blur);	background-color: var(--mask-background);	z-index: 0;	animation: showMask var(--duration) ease-out 1;}@keyframes showMask{	0%{opacity: 0;}	100%{opacity: 1;}}.ax-popup .__body{	position: relative;	z-index: 1;	animation: showBody var(--duration) ease-out 1;}@keyframes showBody{	0%{transform: translateY(75%);opacity: 0;}	100%{transform: translateY(0%);opacity: 1;}}.ax-popup.black .__mask{	--mask-background: rgba(0, 0, 0, 0.35);}.ax-popup.white .__mask{	--mask-background: rgba(255, 255, 255, 0.85);}.ax-popup.close .__mask{	animation-name: closeMask;	animation-fill-mode: forwards;}@keyframes closeMask{	0%{opacity: 1;}	100%{opacity: 0;}}.ax-popup.close .__body{	animation-name: closeBody;	animation-fill-mode: forwards;}@keyframes closeBody{	0%{transform: translateY(0%);opacity: 1;}	100%{transform: translateY(-75%);opacity: 0;}}.ax-popup.top{	justify-content: flex-start;}.ax-popup.top .__body{	animation-name: showTopBody;}.ax-popup.top.close .__body{	animation-name: closeTopBody;}@keyframes showTopBody{	0%{transform: translateY(-100%);opacity: 0;}	100%{transform: translateY(0%);opacity: 1;}}@keyframes closeTopBody{	0%{transform: translateY(0%);opacity: 1;}	100%{transform: translateY(-100%);opacity: 0;}}.ax-popup.bottom{	justify-content: flex-end;}.ax-popup.bottom .__body{	animation-name: showBottomBody;}.ax-popup.bottom.close .__body{	animation-name: closeBottomBody;}@keyframes showBottomBody{	0%{transform: translateY(100%);opacity: 0;}	100%{transform: translateY(0%);opacity: 1;}}@keyframes closeBottomBody{	0%{transform: translateY(0%);opacity: 1;}	100%{transform: translateY(100%);opacity: 0;}}.ax-popup.left{	align-items: flex-start;}.ax-popup.left .__body{	animation-name: showLeftBody;}.ax-popup.left.close .__body{	animation-name: closeLeftBody;}@keyframes showLeftBody{	0%{transform: translateX(-100%);opacity: 0;}	100%{transform: translateX(0%);opacity: 1;}}@keyframes closeLeftBody{	0%{transform: translateX(0%);opacity: 1;}	100%{transform: translateX(-100%);opacity: 0;}}.ax-popup.right{	align-items: flex-end;}.ax-popup.right .__body{	animation-name: showRightBody;}.ax-popup.right.close .__body{	animation-name: closeRightBody;}@keyframes showRightBody{	0%{transform: translateX(100%);opacity: 0;}	100%{transform: translateX(0%);opacity: 1;}}@keyframes closeRightBody{	0%{transform: translateX(0%);opacity: 1;}	100%{transform: translateX(100%);opacity: 0;}}</style>
 |