当前位置: 首页 > news >正文

Vue3分段控制器(Segmented)

效果如下图:在线预览

在这里插入图片描述
在这里插入图片描述

APIs

Segmented

参数说明类型默认值必传
block是否将宽度调整为父元素宽度,同时所有选项占据相同的宽度booleanfalsefalse
disabled是否禁用booleanfalsefalse
options选项数据string[] | number[] | SegmentedOption[][]false
size控件尺寸‘large’ | ‘middle’ | ‘small’‘middle’false
value v-model当前选中的值string | numberundefinedfalse

SegmentedOption Type

名称说明类型必传
label选项名stringfalse
value选项值string | numbertrue
disabled是否禁用选项booleanfalse
payload自定义数据载体anyfalse

Events

名称说明类型
change选项变化时的回调函数(value: string | number) => void

创建分段控制器组件Segmented.vue

<script setup lang="ts">
interface SegmentedOption {label?: string // 选项名value: string | number // 选项值disabled?: boolean // 是否禁用选项payload?: any // 自定义数据载体
}
interface Props {block?: boolean // 是否将宽度调整为父元素宽度,同时所有选项占据相同的宽度disabled?: boolean // 是否禁用options?: string[] | number[] | SegmentedOption[] // 选项数据size?: 'large' | 'middle' | 'small' // 控件尺寸value?: string | number // v-model 当前选中的值
}
const props = withDefaults(defineProps<Props>(), {block: false,disabled: false,options: () => [],size: 'middle',value: undefined
})
const emits = defineEmits(['update:value', 'change'])
function onSelected(value: string | number) {if (value !== props.value) {emits('update:value', value)emits('change', value)}
}
function getOptionDisabled(option: string | number | SegmentedOption) {if (typeof option == 'object') {return option?.disabled || false}return false
}
function getOptionValue(option: string | number | SegmentedOption) {if (typeof option == 'object') {return option.value}return option
}
function getOptionLabel(option: string | number | SegmentedOption) {if (typeof option == 'object') {return option.label}return option
}
</script>
<template><divclass="m-segmented":class="{'segmented-small': size == 'small','segmented-large': size == 'large','segmented-block': block}"><div class="m-segmented-group"><divclass="m-segmented-item":class="{'segmented-item-selected': value === getOptionValue(option),'segmented-item-disabled': disabled || getOptionDisabled(option),'segmented-item-block': block}"v-for="(option, index) in options":key="index"@click="disabled || getOptionDisabled(option) ? () => false : onSelected(getOptionValue(option))"><inputclass="segmented-item-input"type="radio":checked="value === getOptionValue(option)":disabled="disabled || getOptionDisabled(option)"/><divclass="segmented-item-label":title="typeof option === 'object' && option.payload ? undefined : String(getOptionLabel(option))"><slotname="label":label="getOptionLabel(option)":payload="typeof option === 'object' ? option.payload : {}">{{ getOptionLabel(option) }}</slot></div></div></div></div>
</template>
<style lang="less" scoped>
.m-segmented {display: inline-block;padding: 2px;color: rgba(0, 0, 0, 0.65);font-size: 14px;line-height: 1.5714285714285714;background-color: #f5f5f5;border-radius: 6px;transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);.m-segmented-group {position: relative;display: flex;align-items: stretch;justify-items: flex-start;width: 100%;.m-segmented-item {position: relative;text-align: center;cursor: pointer;transition:color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1),background-color 0.2s;border-radius: 4px;&:hover:not(.segmented-item-selected):not(.segmented-item-disabled) {color: rgba(0, 0, 0, 0.88);&::after {background-color: rgba(0, 0, 0, 0.06);}}&::after {position: absolute;width: 100%;height: 100%;top: 0;inset-inline-start: 0;border-radius: inherit;transition: background-color 0.2s;pointer-events: none;content: '';}.segmented-item-input {position: absolute;inset-block-start: 0;inset-inline-start: 0;width: 0;height: 0;opacity: 0;pointer-events: none;}.segmented-item-label {min-height: 28px;line-height: 28px;padding: 0 11px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}}.segmented-item-selected {background-color: #ffffff;box-shadow:0 1px 2px 0 rgba(0, 0, 0, 0.03),0 1px 6px -1px rgba(0, 0, 0, 0.02),0 2px 4px 0 rgba(0, 0, 0, 0.02);color: rgba(0, 0, 0, 0.88);}.segmented-item-disabled {color: rgba(0, 0, 0, 0.25);cursor: not-allowed;}}
}
.segmented-small {border-radius: 4px;.m-segmented-group .m-segmented-item {border-radius: 2px;.segmented-item-label {min-height: 20px;line-height: 20px;padding: 0 7px;}}
}
.segmented-large {border-radius: 8px;.m-segmented-group .m-segmented-item {border-radius: 6px;.segmented-item-label {min-height: 36px;line-height: 36px;padding: 0 11px;font-size: 16px;}}
}
.segmented-block {display: flex;width: 100%;.m-segmented-group .m-segmented-item {flex: 1;min-width: 0;}
}
</style>

在要使用的页面引入

<script setup lang="ts">
import Segmented from './Segmented.vue'
import { reactive, ref } from 'vue'
const options = reactive(['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly'])
const optionsDisabled = reactive(['Daily',{ label: 'Weekly', value: 'Weekly', disabled: true },'Monthly',{ label: 'Quarterly', value: 'Quarterly', disabled: true },'Yearly'
])
const value = ref(options[0])
const value2 = ref('Daily')
const onChange = (value: string | number) => {console.log('change', value)
}
const dynamicOptions = reactive(['Daily', 'Weekly', 'Monthly'])
const dynamicValue = ref(dynamicOptions[0])
const loading = ref(false)
const disabled = ref(false)
const loadMore = () => {loading.value = truesetTimeout(() => {dynamicOptions.push(...['Quarterly', 'Yearly'])loading.value = falsedisabled.value = true}, 1000)
}
const customOptions1 = reactive([{label: 'user1',value: 'user1',payload: {src: 'https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg',style: { backgroundColor: '#f56a00' }}},{label: 'user2',value: 'user2',payload: {style: { backgroundColor: '#f56a00' },content: 'K'}},{label: 'user3',value: 'user3',payload: {icon: 'User',style: { backgroundColor: '#f56a00' }}}
])
const customValue = ref(customOptions1[0].value)
const customOptions2 = reactive([{value: 'spring',payload: {title: 'Spring',subTitle: 'Jan-Mar'}},{value: 'summer',payload: {title: 'Summer',subTitle: 'Apr-Jun'}},{value: 'autumn',payload: {title: 'Autumn',subTitle: 'Jul-Sept'}},{value: 'winter',payload: {title: 'Winter',subTitle: 'Oct-Dec'}}
])
const customValue2 = ref(customOptions2[0].value)
</script>
<template><div><h1>{{ $route.name }} {{ $route.meta.title }}</h1><h2 class="mt30 mb10">基本使用</h2><Segmented v-model:value="value" :options="options" @change="onChange" /><h2 class="mt30 mb10">禁用</h2><Space vertical><Segmented v-model:value="value" disabled :options="options" /><Segmented v-model:value="value2" :options="optionsDisabled" /></Space><h2 class="mt30 mb10">动态加载数据</h2><Space vertical><Segmented v-model:value="dynamicValue" :options="dynamicOptions" /><Button type="primary" :loading="loading" :disabled="disabled" @click="loadMore">Load More</Button></Space><h2 class="mt30 mb10">block 分段控制器</h2><Space :width="600"><Segmented v-model:value="value" block :options="options" /></Space><h2 class="mt30 mb10">自定义渲染</h2><Space vertical><Segmented v-model:value="customValue" :options="customOptions1"><template #label="{ label, payload = {} }"><div style="padding: 4px"><template v-if="payload.icon"><Avatar :style="payload.style"><template #icon><svgfocusable="false"class="u-icon"data-icon="user"width="1em"height="1em"fill="currentColor"aria-hidden="true"viewBox="64 64 896 896"><pathd="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"></path></svg></template>{{ payload.content }}</Avatar></template><template v-else><Avatar :src="payload.src" :style="payload.style">{{ payload.content }}</Avatar></template><div>{{ label }}</div></div></template></Segmented><Segmented v-model:value="customValue2" :options="customOptions2"><template #label="{ payload }"><div style="padding: 4px 4px"><div>{{ payload.title }}</div><div>{{ payload.subTitle }}</div></div></template></Segmented></Space><h2 class="mt30 mb10">三种大小</h2><Space vertical><Segmented v-model:value="value" :options="options" size="large" /><Segmented v-model:value="value" :options="options" /><Segmented v-model:value="value" :options="options" size="small" /></Space></div>
</template>
<style lang="less" scoped>
.u-icon {display: inline-block;fill: #fff;
}
</style>

相关文章:

Vue3分段控制器(Segmented)

效果如下图&#xff1a;在线预览 APIs Segmented 参数说明类型默认值必传block是否将宽度调整为父元素宽度&#xff0c;同时所有选项占据相同的宽度booleanfalsefalsedisabled是否禁用booleanfalsefalseoptions选项数据string[] | number[] | SegmentedOption[][]falsesize控…...

SpringSecurity如何正确的设置白名单

在SpringSecurity中,往往需要对部分接口白名单访问,而大部分在使用Security中就有一个误区,那就是免鉴权访问和白名单的区别。 大部分的Security文章包括官方文档给出免鉴权访问都是使用.permitAll()去对相应路径进行免鉴权访问,但实际上这仅仅只表示该资源不需要相应的权限访问…...

【Langchain大语言模型开发教程】评估

&#x1f517; LangChain for LLM Application Development - DeepLearning.AI 学习目标 1、Example generation 2、Manual evaluation and debug 3、LLM-assisted evaluation 4、LangChain evaluation platform 1、引包、加载环境变量&#xff1b; import osfrom dotenv imp…...

Python爬虫小项目实战

1.自动获取小说多个章节内容 2.获取英雄联盟里面的全部英雄 3. 简单地自动抽奖系统 4. 简单地点赞系统 5. 制作查询手机号工具 6. 制做登录系统 7. 操作excel办公自动化 8. 自动批量保存图片 9. 获取NBA数据 10. 获取彩票信息 11. 获取房地产信息 12. 获取小说…...

PHP Filesystem 简介

PHP Filesystem 简介 PHP 是一种广泛使用的开源服务器端脚本语言,特别适用于网页开发。在 PHP 中,Filesystem 是一个功能丰富的库,提供了一系列用于文件系统操作的函数。这些函数允许开发者读取、写入、修改和删除文件和目录,以及执行其他与文件系统相关的任务。 PHP Fil…...

源代码加密软件哪家好?五款企业级加密软件推荐

随着软件开发行业的快速发展&#xff0c;源代码作为核心资产&#xff0c;面临着越来越大的安全威胁。保护源代码不被泄露或盗用&#xff0c;是每个开发团队和企业都需要高度重视的问题。源代码加密软件通过对代码进行加密处理&#xff0c;确保其在传输和存储过程中保持机密性。…...

Redis常见的数据类型及操作方式

一、通用命令 1&#xff09;获取redis中所有key keys * 2&#xff09;删除一个或多个key del key1 key2 ... 3&#xff09;判断key是否存在 exists key 4&#xff09;给key添加过期时间 expire key time 5&#xff09;查看key剩余过期时间 ttl key 6) 查看redis内存…...

谷粒商城实战笔记-55-商品服务-API-三级分类-修改-拖拽数据收集

文章目录 一&#xff0c;拖拽后结点的parentCid的更新二&#xff0c;拖拽后结点的父节点下所有结点的sort排序属性的变化更新排序的逻辑代码分析 三&#xff0c;拖拽后结点及其子节点catLevel的变化判断是否需要更新 catLevel获取拖动后的新节点 更新 catLevel完整代码 这一节的…...

AI绘画入门实践|Midjourney:使用 --seed 制作情侣头像与漫画

在 Midjourney 中&#xff0c;seed 是指一个种子&#xff0c;用于生成图像时的起点或基础。 使用格式&#xff1a;--seed 获取的seed值 获取 seed 值 使用 seed 生成图像 a cute boys avatar, background with blue sky and white cloud, Ghibli Studio style, Hayao Miyazaki…...

笔记:Enum中FlagsAttribute特性的用法

一、目的&#xff1a;分享Enum中FlagsAttribute特性的用法 在C#中&#xff0c;Enum&#xff08;枚举&#xff09;类型可以使用[Flags]属性来表示一个枚举可以存储多个值。这是通过按位运算符&#xff08;如|&#xff08;或&#xff09;和&&#xff08;与&#xff09;&#…...

QWidget如何切换ui

在Qt中&#xff0c;QWidget及其子类用于构建图形用户界面。如果你想要在不同的UI之间切换&#xff0c;可以使用QStackedWidget&#xff0c;它可以管理一组QWidget&#xff0c;并且每次只显示其中一个。 以下是一个简单的例子&#xff0c;展示如何使用QStackedWidget切换UI&…...

web网站组成

web网站由四部分组成&#xff1a;浏览器 前端服务器 后端服务器 数据库服务器 流程&#xff1a; 1.浏览器输入网站后&#xff0c;向前端服务器发送请求&#xff0c;前端服务器响应&#xff0c;静态的数据给浏览器。 2.前端代码中script中有url,这个是向后台发送请求的网…...

带您详细了解安全漏洞的产生和防护

什么是漏洞&#xff1f; 漏洞是 IT、网络、云、Web 或移动应用程序系统中的弱点或缺陷&#xff0c;可能使其容易受到成功的外部攻击。攻击者经常试图寻找网络安全中的各种类型的漏洞来组合和利用系统。 一些最常见的漏洞&#xff1a; 1.SQL注入 注入诸如 SQL 查询之类的小代…...

【接口测试】params传参与body传参区别

文章目录 一.params传参二.body传参三.两者区别说明 一.params传参 params传参一般用于get请求 params传参时,参数会附于URL后面以问号形式展示。 示例&#xff1a; http://ip地址:端口号/login?usernamexm&pwd111二.body传参 body传参一般用于post请求 body传参时需…...

【docker】部署证书过期监控系统mouday/domain-admin

证书过期了再去部署证书容易被骂&#xff0c;就找了一个开源的证书过期系统来部署一下 过程 官方文档&#xff1a;https://domain-admin.readthedocs.io/zh-cn/latest/manual/install.html#docker 直接下载镜像是超时的&#xff0c;切换一下文档推荐的镜像源 新建docker配置…...

高级java每日一道面试题-2024年7月17日

面试官: java中都有哪些引用类型? 我回答: 强引用&#xff08;Strong Reference&#xff09; 描述&#xff1a;这是最常见和最直观的引用类型&#xff0c;我们通常在代码中创建的对象引用就是强引用。例如&#xff0c;Object obj new Object();。只要强引用存在&#xff0c;…...

css中如何清除浮动

在CSS中&#xff0c;可以使用clear:both属性来清除浮动。以下是几种常见的清除浮动的方法&#xff1a; 使用clearfix类&#xff1a;在CSS中定义一个clearfix类&#xff0c;并将其应用于需要清除浮动的父元素上。 .clearfix::after {content: "";display: table;cle…...

【网络】tcp_socket

tcp_socket 一、tcp_server与udp_server一样的部分二、listen接口&#xff08;监听&#xff09;三、accept接收套接字1、为什么还要多一个套接字&#xff08;明明已经有了个socket套接字文件了&#xff0c;为什么要多一个accept套接字文件&#xff1f;&#xff09;2、底层拿到新…...

Live555源码阅读笔记:哈希表的实现

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

vue3创建vite项目

一、创建vue3 vite项目&#xff1a; 命令行创建&#xff1a;npm create vitelatest vue3-tdly-demo -- --template vue (1)先进入项目文件夹&#xff0c;cd vue3-tdly-demo (2)之后执行&#xff0c; npm install (3)最后运行&#xff0c;npm run dev 将main.js文件内容改成…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

Java设计模式:责任链模式

一、什么是责任链模式&#xff1f; 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09; 是一种 行为型设计模式&#xff0c;它通过将请求沿着一条处理链传递&#xff0c;直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者&#xff0c;…...

Linux信号保存与处理机制详解

Linux信号的保存与处理涉及多个关键机制&#xff0c;以下是详细的总结&#xff1a; 1. 信号的保存 进程描述符&#xff08;task_struct&#xff09;&#xff1a;每个进程的PCB中包含信号相关信息。 pending信号集&#xff1a;记录已到达但未处理的信号&#xff08;未决信号&a…...

[C++错误经验]case语句跳过变量初始化

标题&#xff1a;[C错误经验]case语句跳过变量初始化 水墨不写bug 文章目录 一、错误信息复现二、错误分析三、解决方法 一、错误信息复现 write.cc:80:14: error: jump to case label80 | case 2:| ^ write.cc:76:20: note: crosses initialization…...