164 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
		
		
			
		
	
	
			164 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
| 
								 | 
							
								<template>
							 | 
						|||
| 
								 | 
							
									<view class="u-switch" :class="[value == true ? 'u-switch--on' : '', disabled ? 'u-switch--disabled' : '']" @tap="onClick"
							 | 
						|||
| 
								 | 
							
									 :style="[switchStyle]">
							 | 
						|||
| 
								 | 
							
										<view class="u-switch__node node-class" :style="{
							 | 
						|||
| 
								 | 
							
											width: $u.addUnit(this.size),
							 | 
						|||
| 
								 | 
							
											height: $u.addUnit(this.size)
							 | 
						|||
| 
								 | 
							
										}">
							 | 
						|||
| 
								 | 
							
											<u-loading :show="loading" class="u-switch__loading" :size="size * 0.6" :color="loadingColor" />
							 | 
						|||
| 
								 | 
							
										</view>
							 | 
						|||
| 
								 | 
							
									</view>
							 | 
						|||
| 
								 | 
							
								</template>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<script>
							 | 
						|||
| 
								 | 
							
									/**
							 | 
						|||
| 
								 | 
							
									 * switch 开关选择器
							 | 
						|||
| 
								 | 
							
									 * @description 选择开关一般用于只有两个选择,且只能选其一的场景。
							 | 
						|||
| 
								 | 
							
									 * @tutorial https://www.uviewui.com/components/switch.html
							 | 
						|||
| 
								 | 
							
									 * @property {Boolean} loading 是否处于加载中(默认false)
							 | 
						|||
| 
								 | 
							
									 * @property {Boolean} disabled 是否禁用(默认false)
							 | 
						|||
| 
								 | 
							
									 * @property {String Number} size 开关尺寸,单位rpx(默认50)
							 | 
						|||
| 
								 | 
							
									 * @property {String} active-color 打开时的背景色(默认#2979ff)
							 | 
						|||
| 
								 | 
							
									 * @property {Boolean} inactive-color 关闭时的背景色(默认#ffffff)
							 | 
						|||
| 
								 | 
							
									 * @property {Boolean | Number | String} active-value 打开选择器时通过change事件发出的值(默认true)
							 | 
						|||
| 
								 | 
							
									 * @property {Boolean | Number | String} inactive-value 关闭选择器时通过change事件发出的值(默认false)
							 | 
						|||
| 
								 | 
							
									 * @event {Function} change 在switch打开或关闭时触发
							 | 
						|||
| 
								 | 
							
									 * @example <u-switch v-model="checked" active-color="red" inactive-color="#eee"></u-switch>
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									export default {
							 | 
						|||
| 
								 | 
							
										name: "u-switch",
							 | 
						|||
| 
								 | 
							
										props: {
							 | 
						|||
| 
								 | 
							
											// 是否为加载中状态
							 | 
						|||
| 
								 | 
							
											loading: {
							 | 
						|||
| 
								 | 
							
												type: Boolean,
							 | 
						|||
| 
								 | 
							
												default: false
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 是否为禁用装填
							 | 
						|||
| 
								 | 
							
											disabled: {
							 | 
						|||
| 
								 | 
							
												type: Boolean,
							 | 
						|||
| 
								 | 
							
												default: false
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 开关尺寸,单位rpx
							 | 
						|||
| 
								 | 
							
											size: {
							 | 
						|||
| 
								 | 
							
												type: [Number, String],
							 | 
						|||
| 
								 | 
							
												default: 50
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 打开时的背景颜色
							 | 
						|||
| 
								 | 
							
											activeColor: {
							 | 
						|||
| 
								 | 
							
												type: String,
							 | 
						|||
| 
								 | 
							
												default: '#2979ff'
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 关闭时的背景颜色
							 | 
						|||
| 
								 | 
							
											inactiveColor: {
							 | 
						|||
| 
								 | 
							
												type: String,
							 | 
						|||
| 
								 | 
							
												default: '#ffffff'
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 通过v-model双向绑定的值
							 | 
						|||
| 
								 | 
							
											value: {
							 | 
						|||
| 
								 | 
							
												type: Boolean,
							 | 
						|||
| 
								 | 
							
												default: false
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 是否使手机发生短促震动,目前只在iOS的微信小程序有效(2020-05-06)
							 | 
						|||
| 
								 | 
							
											vibrateShort: {
							 | 
						|||
| 
								 | 
							
												type: Boolean,
							 | 
						|||
| 
								 | 
							
												default: false
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 打开选择器时的值
							 | 
						|||
| 
								 | 
							
											activeValue: {
							 | 
						|||
| 
								 | 
							
												type: [Number, String, Boolean],
							 | 
						|||
| 
								 | 
							
												default: true
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											// 关闭选择器时的值
							 | 
						|||
| 
								 | 
							
											inactiveValue: {
							 | 
						|||
| 
								 | 
							
												type: [Number, String, Boolean],
							 | 
						|||
| 
								 | 
							
												default: false
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
										},
							 | 
						|||
| 
								 | 
							
										data() {
							 | 
						|||
| 
								 | 
							
											return {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										},
							 | 
						|||
| 
								 | 
							
										computed: {
							 | 
						|||
| 
								 | 
							
											switchStyle() {
							 | 
						|||
| 
								 | 
							
												let style = {};
							 | 
						|||
| 
								 | 
							
												style.fontSize = this.size + 'rpx';
							 | 
						|||
| 
								 | 
							
												style.backgroundColor = this.value ? this.activeColor : this.inactiveColor;
							 | 
						|||
| 
								 | 
							
												return style;
							 | 
						|||
| 
								 | 
							
											},
							 | 
						|||
| 
								 | 
							
											loadingColor() {
							 | 
						|||
| 
								 | 
							
												return this.value ? this.activeColor : null;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										},
							 | 
						|||
| 
								 | 
							
										methods: {
							 | 
						|||
| 
								 | 
							
											onClick() {
							 | 
						|||
| 
								 | 
							
												if (!this.disabled && !this.loading) {
							 | 
						|||
| 
								 | 
							
													// 使手机产生短促震动,微信小程序有效,APP(HX 2.6.8)和H5无效
							 | 
						|||
| 
								 | 
							
													if(this.vibrateShort) uni.vibrateShort();
							 | 
						|||
| 
								 | 
							
													this.$emit('input', !this.value);
							 | 
						|||
| 
								 | 
							
													// 放到下一个生命周期,因为双向绑定的value修改父组件状态需要时间,且是异步的
							 | 
						|||
| 
								 | 
							
													this.$nextTick(() => {
							 | 
						|||
| 
								 | 
							
														this.$emit('change', this.value ? this.activeValue : this.inactiveValue);
							 | 
						|||
| 
								 | 
							
													})
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									};
							 | 
						|||
| 
								 | 
							
								</script>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<style lang="scss" scoped>
							 | 
						|||
| 
								 | 
							
									@import "../../libs/css/style.components.scss";
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
									.u-switch {
							 | 
						|||
| 
								 | 
							
										position: relative;
							 | 
						|||
| 
								 | 
							
										/* #ifndef APP-NVUE */
							 | 
						|||
| 
								 | 
							
										display: inline-block;
							 | 
						|||
| 
								 | 
							
										/* #endif */
							 | 
						|||
| 
								 | 
							
										box-sizing: initial;
							 | 
						|||
| 
								 | 
							
										width: 2em;
							 | 
						|||
| 
								 | 
							
										height: 1em;
							 | 
						|||
| 
								 | 
							
										background-color: #fff;
							 | 
						|||
| 
								 | 
							
										border: 1px solid rgba(0, 0, 0, 0.1);
							 | 
						|||
| 
								 | 
							
										border-radius: 1em;
							 | 
						|||
| 
								 | 
							
										transition: background-color 0.3s;
							 | 
						|||
| 
								 | 
							
										font-size: 50rpx;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									.u-switch__node {
							 | 
						|||
| 
								 | 
							
										@include vue-flex;
							 | 
						|||
| 
								 | 
							
										align-items: center;
							 | 
						|||
| 
								 | 
							
										justify-content: center;
							 | 
						|||
| 
								 | 
							
										position: absolute;
							 | 
						|||
| 
								 | 
							
										top: 0;
							 | 
						|||
| 
								 | 
							
										left: 0;
							 | 
						|||
| 
								 | 
							
										border-radius: 100%;
							 | 
						|||
| 
								 | 
							
										z-index: 1;
							 | 
						|||
| 
								 | 
							
										background-color: #fff;
							 | 
						|||
| 
								 | 
							
										background-color: #fff;
							 | 
						|||
| 
								 | 
							
										box-shadow: 0 3px 1px 0 rgba(0, 0, 0, 0.05), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);
							 | 
						|||
| 
								 | 
							
										box-shadow: 0 3px 1px 0 rgba(0, 0, 0, 0.05), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);
							 | 
						|||
| 
								 | 
							
										transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);
							 | 
						|||
| 
								 | 
							
										transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05), -webkit-transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);
							 | 
						|||
| 
								 | 
							
										transition: transform cubic-bezier(0.3, 1.05, 0.4, 1.05);
							 | 
						|||
| 
								 | 
							
										transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05)
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									.u-switch__loading {
							 | 
						|||
| 
								 | 
							
										@include vue-flex;
							 | 
						|||
| 
								 | 
							
										align-items: center;
							 | 
						|||
| 
								 | 
							
										justify-content: center;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									.u-switch--on {
							 | 
						|||
| 
								 | 
							
										background-color: #1989fa;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									.u-switch--on .u-switch__node {
							 | 
						|||
| 
								 | 
							
										transform: translateX(100%);
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									.u-switch--disabled {
							 | 
						|||
| 
								 | 
							
										opacity: 0.4;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								</style>
							 |