Переглянути джерело

feat(components): 编写输入保存组件,用于修改参数值

wangcong 1 день тому
батько
коміт
23ae8fa6c5
1 змінених файлів з 131 додано та 0 видалено
  1. 131 0
      src/components/InputSave.vue

+ 131 - 0
src/components/InputSave.vue

@@ -0,0 +1,131 @@
+<script setup lang="ts">
+import { computed, ref, useTemplateRef, watch } from 'vue';
+
+import type { CSSProperties } from 'vue';
+import type { GroupModuleDevParam } from '@/types';
+
+interface Props {
+  info: GroupModuleDevParam;
+  width?: string;
+}
+
+const props = defineProps<Props>();
+
+const inputNumberRef = useTemplateRef('inputNumber');
+const inputVal = ref(props.info.value);
+const showInput = ref(false);
+
+const emit = defineEmits<{
+  ok: [value: string];
+}>();
+
+const containerStyle = computed<CSSProperties>(() => {
+  return {
+    width: props.width || '100%',
+  };
+});
+
+watch(
+  () => props.info.value,
+  () => {
+    inputVal.value = props.info.value;
+  },
+);
+
+const handlePlaceholderClick = () => {
+  showInput.value = true;
+
+  setTimeout(() => {
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    (inputNumberRef.value as any)?.focus();
+  }, 0);
+};
+
+const handleInputBlur = () => {
+  setTimeout(() => {
+    showInput.value = false;
+    inputVal.value = props.info.value;
+  }, 200);
+};
+
+const handleSave = () => {
+  props.info.value = inputVal.value;
+  emit('ok', inputVal.value);
+};
+</script>
+
+<template>
+  <div class="input-save-container" :style="containerStyle">
+    <div v-show="!showInput" class="input-save-placeholder" @click="handlePlaceholderClick">{{ info.value }}</div>
+    <AInputNumber
+      ref="inputNumber"
+      v-show="showInput"
+      class="input-save-input"
+      v-model:value="inputVal"
+      :controls="false"
+      @blur="handleInputBlur"
+    />
+    <AButton v-show="showInput" class="input-save-button" type="primary" size="small" @click="handleSave">
+      {{ $t('common.save') }}
+    </AButton>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.input-save-container {
+  position: relative;
+}
+
+.input-save-placeholder {
+  width: 100%;
+  height: 32px;
+  padding: 0 11px;
+  line-height: 32px;
+  color: var(--antd-color-text);
+  border: 1px solid #d9d9d9;
+  border-radius: 6px;
+  outline: 0;
+  transition: all 0.2s linear;
+
+  &:hover {
+    cursor: text;
+    border-color: var(--antd-color-primary-hover);
+  }
+}
+
+.input-save-input {
+  width: 100%;
+}
+
+.input-save-button {
+  position: absolute;
+  bottom: -28px;
+  left: 50%;
+  z-index: 10;
+
+  /* 添加阴影效果 */
+  box-shadow:
+    0 4px 6px -1px rgb(0 0 0 / 10%),
+    0 2px 4px -1px rgb(0 0 0 / 6%);
+
+  /* 增强视觉层次的过渡效果 */
+  transition: all 0.2s ease;
+  transform: translate(-50%);
+
+  /* 悬停时的阴影变化 */
+  &:hover {
+    box-shadow:
+      0 10px 15px -3px rgb(0 0 0 / 10%),
+      0 4px 6px -2px rgb(0 0 0 / 5%);
+    transform: translate(-50%, -2px);
+  }
+
+  /* 点击时的效果 */
+  &:active {
+    box-shadow:
+      0 4px 6px -1px rgb(0 0 0 / 10%),
+      0 2px 4px -1px rgb(0 0 0 / 6%);
+    transform: translate(-50%, 0);
+  }
+}
+</style>