mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	perf: 优化分段控制器组件,添加v-model支持
				
					
				
			This commit is contained in:
		
							parent
							
								
									59fcac86c4
								
							
						
					
					
						commit
						af224dceea
					
				@ -2,31 +2,33 @@ import "./index.css";
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  h,
 | 
					  h,
 | 
				
			||||||
  ref,
 | 
					  ref,
 | 
				
			||||||
 | 
					  toRef,
 | 
				
			||||||
  watch,
 | 
					  watch,
 | 
				
			||||||
  nextTick,
 | 
					  nextTick,
 | 
				
			||||||
  defineComponent,
 | 
					  defineComponent,
 | 
				
			||||||
  getCurrentInstance
 | 
					  getCurrentInstance
 | 
				
			||||||
} from "vue";
 | 
					} from "vue";
 | 
				
			||||||
import type { OptionsType } from "./type";
 | 
					import type { OptionsType } from "./type";
 | 
				
			||||||
import { isFunction, useDark } from "@pureadmin/utils";
 | 
					 | 
				
			||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
					import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
				
			||||||
 | 
					import { isFunction, isNumber, useDark } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = {
 | 
					const props = {
 | 
				
			||||||
  options: {
 | 
					  options: {
 | 
				
			||||||
    type: Array<OptionsType>,
 | 
					    type: Array<OptionsType>,
 | 
				
			||||||
    default: () => []
 | 
					    default: () => []
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  /** 默认选中,按照第一个索引为 `0` 的模式 */
 | 
					  /** 默认选中,按照第一个索引为 `0` 的模式,可选(`modelValue`只有传`number`类型时才为响应式) */
 | 
				
			||||||
  defaultValue: {
 | 
					  modelValue: {
 | 
				
			||||||
    type: Number,
 | 
					    type: undefined,
 | 
				
			||||||
    default: 0
 | 
					    require: false,
 | 
				
			||||||
 | 
					    default: "0"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
  name: "ReSegmented",
 | 
					  name: "ReSegmented",
 | 
				
			||||||
  props,
 | 
					  props,
 | 
				
			||||||
  emits: ["change"],
 | 
					  emits: ["change", "update:modelValue"],
 | 
				
			||||||
  setup(props, { emit }) {
 | 
					  setup(props, { emit }) {
 | 
				
			||||||
    const width = ref(0);
 | 
					    const width = ref(0);
 | 
				
			||||||
    const translateX = ref(0);
 | 
					    const translateX = ref(0);
 | 
				
			||||||
@ -35,12 +37,16 @@ export default defineComponent({
 | 
				
			|||||||
    const curMouseActive = ref(-1);
 | 
					    const curMouseActive = ref(-1);
 | 
				
			||||||
    const segmentedItembg = ref("");
 | 
					    const segmentedItembg = ref("");
 | 
				
			||||||
    const instance = getCurrentInstance()!;
 | 
					    const instance = getCurrentInstance()!;
 | 
				
			||||||
    const curIndex = ref(props.defaultValue);
 | 
					    const curIndex = isNumber(props.modelValue)
 | 
				
			||||||
 | 
					      ? toRef(props, "modelValue")
 | 
				
			||||||
 | 
					      : ref(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function handleChange({ option, index }, event: Event) {
 | 
					    function handleChange({ option, index }, event: Event) {
 | 
				
			||||||
      if (option.disabled) return;
 | 
					      if (option.disabled) return;
 | 
				
			||||||
      event.preventDefault();
 | 
					      event.preventDefault();
 | 
				
			||||||
      curIndex.value = index;
 | 
					      isNumber(props.modelValue)
 | 
				
			||||||
 | 
					        ? emit("update:modelValue", index)
 | 
				
			||||||
 | 
					        : (curIndex.value = index);
 | 
				
			||||||
      segmentedItembg.value = "";
 | 
					      segmentedItembg.value = "";
 | 
				
			||||||
      emit("change", { index, option });
 | 
					      emit("change", { index, option });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<script setup lang="tsx">
 | 
					<script setup lang="tsx">
 | 
				
			||||||
import { h } from "vue";
 | 
					import { h, ref } from "vue";
 | 
				
			||||||
import { message } from "@/utils/message";
 | 
					import { message } from "@/utils/message";
 | 
				
			||||||
import HomeFilled from "@iconify-icons/ep/home-filled";
 | 
					import HomeFilled from "@iconify-icons/ep/home-filled";
 | 
				
			||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
					import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
				
			||||||
@ -10,51 +10,43 @@ defineOptions({
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 基础用法 */
 | 
					/** 基础用法 */
 | 
				
			||||||
 | 
					const value = ref(4); // 必须为number类型
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const optionsBasis: Array<OptionsType> = [
 | 
					const optionsBasis: Array<OptionsType> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周一",
 | 
					    label: "周一"
 | 
				
			||||||
    value: 1
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周二",
 | 
					    label: "周二"
 | 
				
			||||||
    value: 2
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周三",
 | 
					    label: "周三"
 | 
				
			||||||
    value: 3
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周四",
 | 
					    label: "周四"
 | 
				
			||||||
    value: 4
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周五",
 | 
					    label: "周五"
 | 
				
			||||||
    value: 5
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 禁用 */
 | 
					/** 禁用 */
 | 
				
			||||||
const optionsDisabled: Array<OptionsType> = [
 | 
					const optionsDisabled: Array<OptionsType> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周一",
 | 
					    label: "周一"
 | 
				
			||||||
    value: 1
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周二",
 | 
					    label: "周二"
 | 
				
			||||||
    value: 2
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周三",
 | 
					    label: "周三",
 | 
				
			||||||
    value: 3,
 | 
					 | 
				
			||||||
    disabled: true
 | 
					    disabled: true
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周四",
 | 
					    label: "周四"
 | 
				
			||||||
    value: 4
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周五",
 | 
					    label: "周五",
 | 
				
			||||||
    value: 5,
 | 
					 | 
				
			||||||
    disabled: true
 | 
					    disabled: true
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
@ -63,26 +55,21 @@ const optionsDisabled: Array<OptionsType> = [
 | 
				
			|||||||
const optionsIcon: Array<OptionsType> = [
 | 
					const optionsIcon: Array<OptionsType> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周一",
 | 
					    label: "周一",
 | 
				
			||||||
    value: 1,
 | 
					 | 
				
			||||||
    icon: HomeFilled
 | 
					    icon: HomeFilled
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周二",
 | 
					    label: "周二"
 | 
				
			||||||
    value: 2
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周三",
 | 
					    label: "周三",
 | 
				
			||||||
    value: 3,
 | 
					 | 
				
			||||||
    icon: "terminalWindowLine"
 | 
					    icon: "terminalWindowLine"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周四",
 | 
					    label: "周四",
 | 
				
			||||||
    value: 4,
 | 
					 | 
				
			||||||
    icon: "streamline-emojis:airplane"
 | 
					    icon: "streamline-emojis:airplane"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "周五",
 | 
					    label: "周五",
 | 
				
			||||||
    value: 5,
 | 
					 | 
				
			||||||
    icon: "streamline-emojis:2"
 | 
					    icon: "streamline-emojis:2"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
@ -90,23 +77,18 @@ const optionsIcon: Array<OptionsType> = [
 | 
				
			|||||||
/** 只设置图标 */
 | 
					/** 只设置图标 */
 | 
				
			||||||
const optionsOnlyIcon: Array<OptionsType> = [
 | 
					const optionsOnlyIcon: Array<OptionsType> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    value: 1,
 | 
					 | 
				
			||||||
    icon: HomeFilled
 | 
					    icon: HomeFilled
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    value: 2,
 | 
					 | 
				
			||||||
    icon: "terminalWindowLine"
 | 
					    icon: "terminalWindowLine"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    value: 3,
 | 
					 | 
				
			||||||
    icon: "streamline-emojis:cow-face"
 | 
					    icon: "streamline-emojis:cow-face"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    value: 4,
 | 
					 | 
				
			||||||
    icon: "streamline-emojis:airplane"
 | 
					    icon: "streamline-emojis:airplane"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    value: 5,
 | 
					 | 
				
			||||||
    icon: "streamline-emojis:2"
 | 
					    icon: "streamline-emojis:2"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
@ -121,8 +103,7 @@ const optionsLabel: Array<OptionsType> = [
 | 
				
			|||||||
        })}
 | 
					        })}
 | 
				
			||||||
        <p>周一</p>
 | 
					        <p>周一</p>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    ),
 | 
					    )
 | 
				
			||||||
    value: 1
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: () => (
 | 
					    label: () => (
 | 
				
			||||||
@ -132,8 +113,7 @@ const optionsLabel: Array<OptionsType> = [
 | 
				
			|||||||
        })}
 | 
					        })}
 | 
				
			||||||
        <p>周二</p>
 | 
					        <p>周二</p>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    ),
 | 
					    )
 | 
				
			||||||
    value: 2
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: () => (
 | 
					    label: () => (
 | 
				
			||||||
@ -143,8 +123,7 @@ const optionsLabel: Array<OptionsType> = [
 | 
				
			|||||||
        })}
 | 
					        })}
 | 
				
			||||||
        <p>周三</p>
 | 
					        <p>周三</p>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    ),
 | 
					    )
 | 
				
			||||||
    value: 3
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -179,11 +158,15 @@ function onChange({ index, option }) {
 | 
				
			|||||||
        <span class="font-medium">分段控制器</span>
 | 
					        <span class="font-medium">分段控制器</span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </template>
 | 
					    </template>
 | 
				
			||||||
    <p class="mb-2">基础用法</p>
 | 
					    <p class="mb-2">
 | 
				
			||||||
    <Segmented :options="optionsBasis" />
 | 
					      基础用法(v-model)<span class="text-primary">
 | 
				
			||||||
 | 
					        {{ optionsBasis[value].label }}
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsBasis" v-model="value" />
 | 
				
			||||||
    <el-divider />
 | 
					    <el-divider />
 | 
				
			||||||
    <p class="mb-2">默认选中和禁用</p>
 | 
					    <p class="mb-2">禁用</p>
 | 
				
			||||||
    <Segmented :options="optionsDisabled" :defaultValue="2" />
 | 
					    <Segmented :options="optionsDisabled" />
 | 
				
			||||||
    <el-divider />
 | 
					    <el-divider />
 | 
				
			||||||
    <p class="mb-2">设置图标</p>
 | 
					    <p class="mb-2">设置图标</p>
 | 
				
			||||||
    <Segmented :options="optionsIcon" />
 | 
					    <Segmented :options="optionsIcon" />
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user