mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee
This commit is contained in:
		
						commit
						45ec532ec6
					
				@ -39,6 +39,7 @@ menus:
 | 
				
			|||||||
  hsdialog: Dialog Components
 | 
					  hsdialog: Dialog Components
 | 
				
			||||||
  hsmessage: Message Tips Components
 | 
					  hsmessage: Message Tips Components
 | 
				
			||||||
  hsvideo: Video Components
 | 
					  hsvideo: Video Components
 | 
				
			||||||
 | 
					  hssegmented: Segmented Components
 | 
				
			||||||
  hswaterfall: Waterfall Components
 | 
					  hswaterfall: Waterfall Components
 | 
				
			||||||
  hsmap: Map Components
 | 
					  hsmap: Map Components
 | 
				
			||||||
  hsdraggable: Draggable Components
 | 
					  hsdraggable: Draggable Components
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ menus:
 | 
				
			|||||||
  hsdialog: 函数式弹框组件
 | 
					  hsdialog: 函数式弹框组件
 | 
				
			||||||
  hsmessage: 消息提示组件
 | 
					  hsmessage: 消息提示组件
 | 
				
			||||||
  hsvideo: 视频组件
 | 
					  hsvideo: 视频组件
 | 
				
			||||||
 | 
					  hssegmented: 分段控制器组件
 | 
				
			||||||
  hswaterfall: 瀑布流组件
 | 
					  hswaterfall: 瀑布流组件
 | 
				
			||||||
  hsmap: 地图组件
 | 
					  hsmap: 地图组件
 | 
				
			||||||
  hsdraggable: 拖拽组件
 | 
					  hsdraggable: 拖拽组件
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								src/components/ReSegmented/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/components/ReSegmented/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					import reSegmented from "./src/index";
 | 
				
			||||||
 | 
					import { withInstall } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 分段控制器组件 */
 | 
				
			||||||
 | 
					export const ReSegmented = withInstall(reSegmented);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ReSegmented;
 | 
				
			||||||
 | 
					export type { OptionsType } from "./src/type";
 | 
				
			||||||
							
								
								
									
										78
									
								
								src/components/ReSegmented/src/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/components/ReSegmented/src/index.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					.pure-segmented {
 | 
				
			||||||
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					  display: inline-block;
 | 
				
			||||||
 | 
					  padding: 2px;
 | 
				
			||||||
 | 
					  font-size: 14px;
 | 
				
			||||||
 | 
					  color: rgba(0, 0, 0, 0.65);
 | 
				
			||||||
 | 
					  background-color: rgb(0 0 0 / 4%);
 | 
				
			||||||
 | 
					  border-radius: 2px;
 | 
				
			||||||
 | 
					  transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-group {
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: stretch;
 | 
				
			||||||
 | 
					  justify-items: flex-start;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item-selected {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					  display: none;
 | 
				
			||||||
 | 
					  width: 0;
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  padding: 4px 0;
 | 
				
			||||||
 | 
					  background-color: #fff;
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  box-shadow: 0 2px 8px -2px rgb(0 0 0 / 5%), 0 1px 4px -1px rgb(0 0 0 / 7%),
 | 
				
			||||||
 | 
					    0 0 1px rgb(0 0 0 / 7%);
 | 
				
			||||||
 | 
					  transition: transform 0.5s cubic-bezier(0.645, 0.045, 0.355, 1),
 | 
				
			||||||
 | 
					    width 0.5s cubic-bezier(0.645, 0.045, 0.355, 1);
 | 
				
			||||||
 | 
					  will-change: transform, width;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item {
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item > div {
 | 
				
			||||||
 | 
					  min-height: 28px;
 | 
				
			||||||
 | 
					  line-height: 28px;
 | 
				
			||||||
 | 
					  padding: 0 11px;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  white-space: nowrap;
 | 
				
			||||||
 | 
					  text-overflow: ellipsis;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item > input {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  inset-block-start: 0;
 | 
				
			||||||
 | 
					  inset-inline-start: 0;
 | 
				
			||||||
 | 
					  width: 0;
 | 
				
			||||||
 | 
					  height: 0;
 | 
				
			||||||
 | 
					  opacity: 0;
 | 
				
			||||||
 | 
					  pointer-events: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item-label {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item-icon svg {
 | 
				
			||||||
 | 
					  width: 16px;
 | 
				
			||||||
 | 
					  height: 16px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-segmented-item-disabled {
 | 
				
			||||||
 | 
					  color: rgba(0, 0, 0, 0.25);
 | 
				
			||||||
 | 
					  cursor: not-allowed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										150
									
								
								src/components/ReSegmented/src/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/components/ReSegmented/src/index.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,150 @@
 | 
				
			|||||||
 | 
					import "./index.css";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  h,
 | 
				
			||||||
 | 
					  ref,
 | 
				
			||||||
 | 
					  watch,
 | 
				
			||||||
 | 
					  nextTick,
 | 
				
			||||||
 | 
					  defineComponent,
 | 
				
			||||||
 | 
					  getCurrentInstance
 | 
				
			||||||
 | 
					} from "vue";
 | 
				
			||||||
 | 
					import type { OptionsType } from "./type";
 | 
				
			||||||
 | 
					import { isFunction, useDark } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = {
 | 
				
			||||||
 | 
					  options: {
 | 
				
			||||||
 | 
					    type: Array<OptionsType>,
 | 
				
			||||||
 | 
					    default: () => []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  /** 默认选中,按照第一个索引为 `0` 的模式 */
 | 
				
			||||||
 | 
					  defaultValue: {
 | 
				
			||||||
 | 
					    type: Number,
 | 
				
			||||||
 | 
					    default: 0
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default defineComponent({
 | 
				
			||||||
 | 
					  name: "ReSegmented",
 | 
				
			||||||
 | 
					  props,
 | 
				
			||||||
 | 
					  emits: ["change"],
 | 
				
			||||||
 | 
					  setup(props, { emit }) {
 | 
				
			||||||
 | 
					    const width = ref(0);
 | 
				
			||||||
 | 
					    const translateX = ref(0);
 | 
				
			||||||
 | 
					    const { isDark } = useDark();
 | 
				
			||||||
 | 
					    const initStatus = ref(false);
 | 
				
			||||||
 | 
					    const curMouseActive = ref(-1);
 | 
				
			||||||
 | 
					    const segmentedItembg = ref("");
 | 
				
			||||||
 | 
					    const instance = getCurrentInstance()!;
 | 
				
			||||||
 | 
					    const curIndex = ref(props.defaultValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function handleChange({ option, index }, event: Event) {
 | 
				
			||||||
 | 
					      if (option.disabled) return;
 | 
				
			||||||
 | 
					      event.preventDefault();
 | 
				
			||||||
 | 
					      curIndex.value = index;
 | 
				
			||||||
 | 
					      segmentedItembg.value = "";
 | 
				
			||||||
 | 
					      emit("change", { index, option });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function handleMouseenter({ option, index }, event: Event) {
 | 
				
			||||||
 | 
					      event.preventDefault();
 | 
				
			||||||
 | 
					      curMouseActive.value = index;
 | 
				
			||||||
 | 
					      if (option.disabled || curIndex.value === index) {
 | 
				
			||||||
 | 
					        segmentedItembg.value = "";
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        segmentedItembg.value = isDark.value
 | 
				
			||||||
 | 
					          ? "#1f1f1f"
 | 
				
			||||||
 | 
					          : "rgba(0, 0, 0, 0.06)";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function handleMouseleave(_, event: Event) {
 | 
				
			||||||
 | 
					      event.preventDefault();
 | 
				
			||||||
 | 
					      curMouseActive.value = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function handleInit(index = curIndex.value) {
 | 
				
			||||||
 | 
					      nextTick(() => {
 | 
				
			||||||
 | 
					        const curLabelRef = instance?.proxy?.$refs[`labelRef${index}`] as ElRef;
 | 
				
			||||||
 | 
					        width.value = curLabelRef.clientWidth;
 | 
				
			||||||
 | 
					        translateX.value = curLabelRef.offsetLeft;
 | 
				
			||||||
 | 
					        initStatus.value = true;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    watch(
 | 
				
			||||||
 | 
					      () => curIndex.value,
 | 
				
			||||||
 | 
					      index => {
 | 
				
			||||||
 | 
					        nextTick(() => {
 | 
				
			||||||
 | 
					          handleInit(index);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        deep: true,
 | 
				
			||||||
 | 
					        immediate: true
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const rendLabel = () => {
 | 
				
			||||||
 | 
					      return props.options.map((option, index) => {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					          <label
 | 
				
			||||||
 | 
					            ref={`labelRef${index}`}
 | 
				
			||||||
 | 
					            class={[
 | 
				
			||||||
 | 
					              "pure-segmented-item",
 | 
				
			||||||
 | 
					              option?.disabled && "pure-segmented-item-disabled"
 | 
				
			||||||
 | 
					            ]}
 | 
				
			||||||
 | 
					            style={{
 | 
				
			||||||
 | 
					              background:
 | 
				
			||||||
 | 
					                curMouseActive.value === index ? segmentedItembg.value : "",
 | 
				
			||||||
 | 
					              color:
 | 
				
			||||||
 | 
					                !option.disabled &&
 | 
				
			||||||
 | 
					                (curIndex.value === index || curMouseActive.value === index)
 | 
				
			||||||
 | 
					                  ? isDark.value
 | 
				
			||||||
 | 
					                    ? "rgba(255, 255, 255, 0.85)"
 | 
				
			||||||
 | 
					                    : "rgba(0,0,0,.88)"
 | 
				
			||||||
 | 
					                  : ""
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					            onMouseenter={event => handleMouseenter({ option, index }, event)}
 | 
				
			||||||
 | 
					            onMouseleave={event => handleMouseleave({ option, index }, event)}
 | 
				
			||||||
 | 
					            onClick={event => handleChange({ option, index }, event)}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <input type="radio" name="segmented" />
 | 
				
			||||||
 | 
					            <div class="pure-segmented-item-label">
 | 
				
			||||||
 | 
					              {option.icon && !isFunction(option.label) ? (
 | 
				
			||||||
 | 
					                <span
 | 
				
			||||||
 | 
					                  class="pure-segmented-item-icon"
 | 
				
			||||||
 | 
					                  style={{ marginRight: option.label ? "6px" : 0 }}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                  {h(useRenderIcon(option.icon))}
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					              ) : null}
 | 
				
			||||||
 | 
					              {option.label ? (
 | 
				
			||||||
 | 
					                isFunction(option.label) ? (
 | 
				
			||||||
 | 
					                  h(option.label)
 | 
				
			||||||
 | 
					                ) : (
 | 
				
			||||||
 | 
					                  <span>{option.label}</span>
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					              ) : null}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </label>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return () => (
 | 
				
			||||||
 | 
					      <div class="pure-segmented">
 | 
				
			||||||
 | 
					        <div class="pure-segmented-group">
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            class="pure-segmented-item-selected"
 | 
				
			||||||
 | 
					            style={{
 | 
				
			||||||
 | 
					              width: `${width.value}px`,
 | 
				
			||||||
 | 
					              transform: `translateX(${translateX.value}px)`,
 | 
				
			||||||
 | 
					              display: initStatus.value ? "block" : "none"
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          ></div>
 | 
				
			||||||
 | 
					          {rendLabel()}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/components/ReSegmented/src/type.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/components/ReSegmented/src/type.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					import type { VNode, Component } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface OptionsType {
 | 
				
			||||||
 | 
					  /** 文字 */
 | 
				
			||||||
 | 
					  label?: string | (() => VNode | Component);
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * @description 图标,采用平台内置的 `useRenderIcon` 函数渲染
 | 
				
			||||||
 | 
					   * @see {@link 用法参考 https://yiming_chang.gitee.io/pure-admin-doc/pages/icon/#%E9%80%9A%E7%94%A8%E5%9B%BE%E6%A0%87-userendericon-hooks }
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  icon?: string | Component;
 | 
				
			||||||
 | 
					  /** 值 */
 | 
				
			||||||
 | 
					  value?: string | number;
 | 
				
			||||||
 | 
					  /** 是否禁用 */
 | 
				
			||||||
 | 
					  disabled?: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -31,6 +31,15 @@ export default {
 | 
				
			|||||||
        title: $t("menus.hsmessage")
 | 
					        title: $t("menus.hsmessage")
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/components/segmented",
 | 
				
			||||||
 | 
					      name: "Segmented",
 | 
				
			||||||
 | 
					      component: () => import("@/views/components/segmented/index.vue"),
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: $t("menus.hssegmented"),
 | 
				
			||||||
 | 
					        extraIcon: "IF-pure-iconfont-new svg"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/waterfall",
 | 
					      path: "/components/waterfall",
 | 
				
			||||||
      name: "Waterfall",
 | 
					      name: "Waterfall",
 | 
				
			||||||
 | 
				
			|||||||
@ -138,4 +138,18 @@ html.dark {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* ReSegmented 组件 */
 | 
				
			||||||
 | 
					  .pure-segmented {
 | 
				
			||||||
 | 
					    color: rgb(255 255 255 / 65%);
 | 
				
			||||||
 | 
					    background-color: #000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .pure-segmented-item-selected {
 | 
				
			||||||
 | 
					      background-color: #1f1f1f;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .pure-segmented-item-disabled {
 | 
				
			||||||
 | 
					      color: rgb(255 255 255 / 25%);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										201
									
								
								src/views/components/segmented/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								src/views/components/segmented/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,201 @@
 | 
				
			|||||||
 | 
					<script setup lang="tsx">
 | 
				
			||||||
 | 
					import { h } from "vue";
 | 
				
			||||||
 | 
					import { message } from "@/utils/message";
 | 
				
			||||||
 | 
					import HomeFilled from "@iconify-icons/ep/home-filled";
 | 
				
			||||||
 | 
					import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
				
			||||||
 | 
					import Segmented, { type OptionsType } from "@/components/ReSegmented";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineOptions({
 | 
				
			||||||
 | 
					  name: "Segmented"
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 基础用法 */
 | 
				
			||||||
 | 
					const optionsBasis: Array<OptionsType> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周一",
 | 
				
			||||||
 | 
					    value: 1
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周二",
 | 
				
			||||||
 | 
					    value: 2
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周三",
 | 
				
			||||||
 | 
					    value: 3
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周四",
 | 
				
			||||||
 | 
					    value: 4
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周五",
 | 
				
			||||||
 | 
					    value: 5
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 禁用 */
 | 
				
			||||||
 | 
					const optionsDisabled: Array<OptionsType> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周一",
 | 
				
			||||||
 | 
					    value: 1
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周二",
 | 
				
			||||||
 | 
					    value: 2
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周三",
 | 
				
			||||||
 | 
					    value: 3,
 | 
				
			||||||
 | 
					    disabled: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周四",
 | 
				
			||||||
 | 
					    value: 4
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周五",
 | 
				
			||||||
 | 
					    value: 5,
 | 
				
			||||||
 | 
					    disabled: true
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 设置图标 */
 | 
				
			||||||
 | 
					const optionsIcon: Array<OptionsType> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周一",
 | 
				
			||||||
 | 
					    value: 1,
 | 
				
			||||||
 | 
					    icon: HomeFilled
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周二",
 | 
				
			||||||
 | 
					    value: 2
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周三",
 | 
				
			||||||
 | 
					    value: 3,
 | 
				
			||||||
 | 
					    icon: "terminalWindowLine"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周四",
 | 
				
			||||||
 | 
					    value: 4,
 | 
				
			||||||
 | 
					    icon: "streamline-emojis:airplane"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周五",
 | 
				
			||||||
 | 
					    value: 5,
 | 
				
			||||||
 | 
					    icon: "streamline-emojis:2"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 只设置图标 */
 | 
				
			||||||
 | 
					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"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 自定义渲染 */
 | 
				
			||||||
 | 
					const optionsLabel: Array<OptionsType> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: () => (
 | 
				
			||||||
 | 
					      <div>
 | 
				
			||||||
 | 
					        {h(useRenderIcon(HomeFilled), {
 | 
				
			||||||
 | 
					          class: "m-auto w-[20px] h-[20px]"
 | 
				
			||||||
 | 
					        })}
 | 
				
			||||||
 | 
					        <p>周一</p>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    value: 1
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: () => (
 | 
				
			||||||
 | 
					      <div>
 | 
				
			||||||
 | 
					        {h(useRenderIcon("terminalWindowLine"), {
 | 
				
			||||||
 | 
					          class: "m-auto w-[20px] h-[20px]"
 | 
				
			||||||
 | 
					        })}
 | 
				
			||||||
 | 
					        <p>周二</p>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    value: 2
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: () => (
 | 
				
			||||||
 | 
					      <div>
 | 
				
			||||||
 | 
					        {h(useRenderIcon("streamline-emojis:cow-face"), {
 | 
				
			||||||
 | 
					          class: "m-auto w-[20px] h-[20px]"
 | 
				
			||||||
 | 
					        })}
 | 
				
			||||||
 | 
					        <p>周三</p>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    value: 3
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const optionsChange: Array<OptionsType> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周一",
 | 
				
			||||||
 | 
					    value: 1
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周二",
 | 
				
			||||||
 | 
					    value: 2
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "周三",
 | 
				
			||||||
 | 
					    value: 3
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** change事件 */
 | 
				
			||||||
 | 
					function onChange({ index, option }) {
 | 
				
			||||||
 | 
					  const { label, value } = option;
 | 
				
			||||||
 | 
					  message(`当前选中项索引为:${index},名字为${label},值为${value}`, {
 | 
				
			||||||
 | 
					    type: "success"
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-card shadow="never">
 | 
				
			||||||
 | 
					    <template #header>
 | 
				
			||||||
 | 
					      <div class="card-header">
 | 
				
			||||||
 | 
					        <span class="font-medium">分段控制器</span>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <p class="mb-2">基础用法</p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsBasis" />
 | 
				
			||||||
 | 
					    <el-divider />
 | 
				
			||||||
 | 
					    <p class="mb-2">默认选中和禁用</p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsDisabled" :defaultValue="2" />
 | 
				
			||||||
 | 
					    <el-divider />
 | 
				
			||||||
 | 
					    <p class="mb-2">设置图标</p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsIcon" />
 | 
				
			||||||
 | 
					    <el-divider />
 | 
				
			||||||
 | 
					    <p class="mb-2">只设置图标</p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsOnlyIcon" />
 | 
				
			||||||
 | 
					    <el-divider />
 | 
				
			||||||
 | 
					    <p class="mb-2">自定义渲染</p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsLabel" />
 | 
				
			||||||
 | 
					    <el-divider />
 | 
				
			||||||
 | 
					    <p class="mb-2">change事件</p>
 | 
				
			||||||
 | 
					    <Segmented :options="optionsChange" @change="onChange" />
 | 
				
			||||||
 | 
					    <el-divider />
 | 
				
			||||||
 | 
					  </el-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user