瀏覽代碼

perf: 优化分段控制器组件,添加`v-model`支持

xiaoxian521 1 年之前
父節點
當前提交
af224dceea
共有 2 個文件被更改,包括 37 次插入48 次删除
  1. 14 8
      src/components/ReSegmented/src/index.tsx
  2. 23 40
      src/views/components/segmented/index.vue

+ 14 - 8
src/components/ReSegmented/src/index.tsx

@@ -2,31 +2,33 @@ import "./index.css";
 import {
   h,
   ref,
+  toRef,
   watch,
   nextTick,
   defineComponent,
   getCurrentInstance
 } from "vue";
 import type { OptionsType } from "./type";
-import { isFunction, useDark } from "@pureadmin/utils";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import { isFunction, isNumber, useDark } from "@pureadmin/utils";
 
 const props = {
   options: {
     type: Array<OptionsType>,
     default: () => []
   },
-  /** 默认选中,按照第一个索引为 `0` 的模式 */
-  defaultValue: {
-    type: Number,
-    default: 0
+  /** 默认选中,按照第一个索引为 `0` 的模式,可选(`modelValue`只有传`number`类型时才为响应式) */
+  modelValue: {
+    type: undefined,
+    require: false,
+    default: "0"
   }
 };
 
 export default defineComponent({
   name: "ReSegmented",
   props,
-  emits: ["change"],
+  emits: ["change", "update:modelValue"],
   setup(props, { emit }) {
     const width = ref(0);
     const translateX = ref(0);
@@ -35,12 +37,16 @@ export default defineComponent({
     const curMouseActive = ref(-1);
     const segmentedItembg = ref("");
     const instance = getCurrentInstance()!;
-    const curIndex = ref(props.defaultValue);
+    const curIndex = isNumber(props.modelValue)
+      ? toRef(props, "modelValue")
+      : ref(0);
 
     function handleChange({ option, index }, event: Event) {
       if (option.disabled) return;
       event.preventDefault();
-      curIndex.value = index;
+      isNumber(props.modelValue)
+        ? emit("update:modelValue", index)
+        : (curIndex.value = index);
       segmentedItembg.value = "";
       emit("change", { index, option });
     }

+ 23 - 40
src/views/components/segmented/index.vue

@@ -1,5 +1,5 @@
 <script setup lang="tsx">
-import { h } from "vue";
+import { h, ref } from "vue";
 import { message } from "@/utils/message";
 import HomeFilled from "@iconify-icons/ep/home-filled";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
@@ -10,51 +10,43 @@ defineOptions({
 });
 
 /** 基础用法 */
+const value = ref(4); // 必须为number类型
+
 const optionsBasis: Array<OptionsType> = [
   {
-    label: "周一",
-    value: 1
+    label: "周一"
   },
   {
-    label: "周二",
-    value: 2
+    label: "周二"
   },
   {
-    label: "周三",
-    value: 3
+    label: "周三"
   },
   {
-    label: "周四",
-    value: 4
+    label: "周四"
   },
   {
-    label: "周五",
-    value: 5
+    label: "周五"
   }
 ];
 
 /** 禁用 */
 const optionsDisabled: Array<OptionsType> = [
   {
-    label: "周一",
-    value: 1
+    label: "周一"
   },
   {
-    label: "周二",
-    value: 2
+    label: "周二"
   },
   {
     label: "周三",
-    value: 3,
     disabled: true
   },
   {
-    label: "周四",
-    value: 4
+    label: "周四"
   },
   {
     label: "周五",
-    value: 5,
     disabled: true
   }
 ];
@@ -63,26 +55,21 @@ const optionsDisabled: Array<OptionsType> = [
 const optionsIcon: Array<OptionsType> = [
   {
     label: "周一",
-    value: 1,
     icon: HomeFilled
   },
   {
-    label: "周二",
-    value: 2
+    label: "周二"
   },
   {
     label: "周三",
-    value: 3,
     icon: "terminalWindowLine"
   },
   {
     label: "周四",
-    value: 4,
     icon: "streamline-emojis:airplane"
   },
   {
     label: "周五",
-    value: 5,
     icon: "streamline-emojis:2"
   }
 ];
@@ -90,23 +77,18 @@ const optionsIcon: Array<OptionsType> = [
 /** 只设置图标 */
 const optionsOnlyIcon: Array<OptionsType> = [
   {
-    value: 1,
     icon: HomeFilled
   },
   {
-    value: 2,
     icon: "terminalWindowLine"
   },
   {
-    value: 3,
     icon: "streamline-emojis:cow-face"
   },
   {
-    value: 4,
     icon: "streamline-emojis:airplane"
   },
   {
-    value: 5,
     icon: "streamline-emojis:2"
   }
 ];
@@ -121,8 +103,7 @@ const optionsLabel: Array<OptionsType> = [
         })}
         <p>周一</p>
       </div>
-    ),
-    value: 1
+    )
   },
   {
     label: () => (
@@ -132,8 +113,7 @@ const optionsLabel: Array<OptionsType> = [
         })}
         <p>周二</p>
       </div>
-    ),
-    value: 2
+    )
   },
   {
     label: () => (
@@ -143,8 +123,7 @@ const optionsLabel: Array<OptionsType> = [
         })}
         <p>周三</p>
       </div>
-    ),
-    value: 3
+    )
   }
 ];
 
@@ -179,11 +158,15 @@ function onChange({ index, option }) {
         <span class="font-medium">分段控制器</span>
       </div>
     </template>
-    <p class="mb-2">基础用法</p>
-    <Segmented :options="optionsBasis" />
+    <p class="mb-2">
+      基础用法(v-model)<span class="text-primary">
+        {{ optionsBasis[value].label }}
+      </span>
+    </p>
+    <Segmented :options="optionsBasis" v-model="value" />
     <el-divider />
-    <p class="mb-2">默认选中和禁用</p>
-    <Segmented :options="optionsDisabled" :defaultValue="2" />
+    <p class="mb-2">禁用</p>
+    <Segmented :options="optionsDisabled" />
     <el-divider />
     <p class="mb-2">设置图标</p>
     <Segmented :options="optionsIcon" />