Browse Source

重构switch组件

ming 2 years ago
parent
commit
a316cc6eff
2 changed files with 81 additions and 21 deletions
  1. 80 20
      components/fs-switch/fs-switch.vue
  2. 1 1
      package.json

+ 80 - 20
components/fs-switch/fs-switch.vue

@@ -1,44 +1,104 @@
 <template>
-	<switch 
-		class="fs-switch" 
-		:checked="checked" 
-		:color="color" 
-		:disabled="disabled" 
-		:class="[size]"
-		@change="change">
-	</switch>
+	<view
+		class="fs-switch"
+		:class="[{ 'fs-switch-checked': modelValue, 'fs-switch-disabled': disabled }, 'fs-switch-' + size]"
+		@click="handleClick"
+	>
+		<view class="fs-switch-text">{{ modelValue ? activeText : inactiveText }}</view>
+	</view>
 </template>
 
 <script setup>
+import { watch, ref } from 'vue'
+
 const props = defineProps({
-	checked: Boolean,
+	modelValue: Boolean,
 	disabled: Boolean,
-	color: {
+	activeColor: {
 		type: String,
 		default: '#0063F5'
 	},
+	inactiveColor: {
+		type: String,
+		default: '#fdfdfd'
+	},
+	activeText: String,
+	inactiveText: String,
 	size: {
 		type: String,
 		validator(value) {
-			return ['small', 'medium'].includes(value)
+			return ['small', 'default', 'large'].includes(value)
 		}
 	}
 })
-const emits = defineEmits(['change'])
+const emits = defineEmits(['change', 'update:modelValue'])
 
-const change = e => {
-	emits('change', e.detail.value)
+const handleClick = () => {
+	if (!props.disabled) {
+		emits('update:modelValue', !props.modelValue)
+		emits('change', !props.modelValue)
+	}
 }
 </script>
 
 <style lang="scss" scoped>
-.fs-switch{
-	transform: scale(0.8);
-	&.medium{
-		transform: scale(0.6);
+.fs-switch {
+	width: 80rpx;
+	height: 40rpx;
+	border-radius: 50rpx;
+	position: relative;
+	background-color: v-bind(inactiveColor);
+	border: 2rpx solid rgba(0, 0, 0, 0.12);
+	transition: background-color 0.1s;
+
+	&::before {
+		width: 36rpx;
+		height: 36rpx;
+		border-radius: 50%;
+		content: '';
+		position: absolute;
+		top: 0;
+		left: 0;
+		background-color: #fff;
+		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
+		transition: transform 0.3s;
+		z-index: 10;
+	}
+
+	&-text {
+		position: absolute;
+		top: 50%;
+		left: 50%;
+		transform: translateY(-50%);
+		font-size: 12px;
+		transition: all 0.3s;
+		text-align: center;
+		width: 30rpx;
+		overflow: hidden;
+	}
+
+	&-disabled {
+		opacity: 0.5;
+	}
+
+	&-checked {
+		background-color: v-bind(activeColor);
+
+		&::before {
+			transform: translateX(40rpx);
+		}
+
+		.fs-switch-text {
+			color: #fff;
+			margin-left: -30rpx;
+		}
+	}
+
+	&-large {
+		transform: scale(1.2);
 	}
-	&.small{
-		transform: scale(0.5);
+	&-small {
+		transform: scale(0.8);
 	}
 }
 </style>

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 	"name": "fs-uni",
-	"version": "2.5.4",
+	"version": "2.6.0",
 	"description": "",
 	"main": "main.js",
 	"dependencies": {