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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3268610.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

LoRA:低秩自适应

LoRA:低秩自适应 本章节是对轻松上手微调大语言模型——QLORA篇中提到的LoRA的原理解释。 背后动机 现今模型的参数量变得越来越大&#xff0c;对预训练模型进行全微调变得越来越不可行。为了解决这个问题有了LoRA&#xff08;Low-Rank Adaption&#xff09;的诞生。将可训练…

ATF-541M4全解析(一)

目录 一、描述二、规格三、各参数最大值四、25℃下的典型值 一、描述 安华高科技 (Avago Technologies) 的 ATF-541M4 是一款高线性度、低噪声、单电源供电的E-PHEMT&#xff0c;封装在一个微型无引脚封装中。 ATF-541M4 的小尺寸和低外形使其非常适合用于混合模块和其他空间…

C++多态的底层原理

目录 1.虚函数表 &#xff08;1&#xff09;虚函数表指针 &#xff08;2&#xff09;虚函数表 2.虚函数表的继承--重写&#xff08;覆盖&#xff09;的原理 3.观察虚表的方法 &#xff08;1&#xff09;内存观察 &#xff08;2&#xff09;打印虚表 虚表的地址 函数 传参…

SpringBoot添加密码安全配置以及Jwt配置

Maven仓库&#xff08;依赖查找&#xff09; 1、SpringBoot安全访问配置 首先添加依赖 spring-boot-starter-security 然后之后每次启动项目之后&#xff0c;访问任何的请求都会要求输入密码才能请求。&#xff08;如下&#xff09; 在没有配置的情况下&#xff0c;默认用户…

【python】python基于 Q-learning 算法的迷宫游戏(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

ctfshow-web入门-php特性(web137-web141)

目录 1、web137 2、web138 3、web139 4、web140 5、web141 1、web137 直接调用 ctfshow 这个类下的 getFlag 函数&#xff0c;payload&#xff1a; ctfshowctfshow::getFlag 查看源码&#xff1a; 拿到 flag&#xff1a;ctfshow{dd387d95-6fbe-4703-8ec5-9c8f9baf2bb5} 在…

【Linux】远程连接Linux虚拟机(MobaXterm)

【Linux】远程连接Linux虚拟机&#xff08;MobaXterm&#xff09; 零、原因 有时候我们在虚拟机中操作Linux不太方便&#xff0c;比如不能复制粘贴&#xff0c;不能传文件等等&#xff0c;我们在主机上使用远程连接软件远程连接Linux虚拟机后可以解决上面的问题。 壹、软件下…

MySQL_JDBC

目录 一、JDBC常用的接口和类 1.1 数据库连接 Connection 1.2 Statement 对象 二、JDBC的使用 总结 【Java 的数据库编程】 JDBC 即 Java Database Connectivity (Java数据库连接)&#xff0c;是一种用于执行 SQL 语句的 Java API。这个 API 由 java.sql.*,javax.sql.* …

软件测试:Postman 工具的使用。开发及测试均需要掌握的测试工具

工具介绍 各个模块功能的介绍如下&#xff1a; 1、New&#xff1a;在这里创建新的请求、集合或环境&#xff1b;还可以创建更高级的文档、Mock Server 和 Monitor以及API。 2、Import&#xff1a;这用于导入集合或环境。有一些选项&#xff0c;例如从文件&#xff0c;文件夹导…

Linux环境下(DeepinV20+)使用docker安装和使用mysql、redis、minio等各类中间件(后续用到其他中间件会继续更新)

docker安装&#xff1a;https://blog.csdn.net/HXBest/article/details/140702265 本人环境放置路径为&#xff1a;/env/中间件名称/&#xff0c;实际改为你自己的&#xff01;&#xff01;&#xff01; 一、mysql安装和使用 docker run -itd --name mysql -p 3306:3306 \ -d …

用 apifox cli 命令行运行本地接口出现TypeError:Invalid IP address: undefined

用 apifox cli 命令行运行本地接口出现TypeError:Invalid IP address: undefined&#xff0c;客户端运行是通过的但命令行运行会报错 修改端口也是一样报错&#xff0c;地址修改为127.0.0.1会报错connect ECONNREFUSED 127.0.0.1:8080 解决方法&#xff1a;不用localhost&…

PHP家政系统自营+多商户独立端口系统源码小程序

家政行业的新篇章 引言&#xff1a;家政行业的数字化转型 近年来&#xff0c;随着科技的飞速发展和人们生活节奏的加快&#xff0c;家政服务行业也迎来了数字化转型的浪潮。为了提升服务效率、优化用户体验&#xff0c;越来越多的家政公司开始探索“家政系统自营多商户小程序…

Ubuntu24.04安装

1. 系统安装 1.1 引导界面 开机进入grub引导界面后&#xff0c;会有安装服务和测试内存两个选择&#xff0c;选择第一个进行安装。 1.2 语言选择 这里的语言选择的是安装过程中的语言&#xff0c;根据个人偏好选择即可&#xff0c;不过没有中文&#xff0c;所以默认使用英文…

【C++】选择结构- 嵌套if语句

嵌套if语句的语法格式&#xff1a; if(条件1) { if(条件1满足后判断是否满足此条件) {条件2满足后执行的操作} else {条件2不满足执行的操作} } 下面是一个实例 #include<iostream> using namespace std;int main4() {/*提示用户输入一个高考分数&#xff0c;根据分…

计算机实验室排课查询小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#xff0c;取消预约管理&#xff0c;实验课程管理&#xff0c;实验报告管理&#xff0c;报修信息管理&#xff0…

qt总结--翻金币案例

完成了一个小项目的在qt5.15.2环境下的运行,并使用NSIS editNSIS打包完成.有待改进之处:增加计时功能,随机且能通关功能,过关后选择下一关功能.打包后仅仅有安装包有图标 安装后应用图标并未改变 在qt .pro中有待改进对qt的基本操作和帮助文档有了基本的认识.对C制作小游戏有了…

在jeesite开源平台上写了一个SQL命令中心的功能

实现目的: 这个SQL命令中心,是因为老项目就有这个页面,主要的功能是根据写出的SQL语句查询数据,并且在查出的数据基础上直接修改更新,还有新增和删除的功能,这么一说跟plsql就一样一样的了;这页面本来是给运维的同事来用,而且他们还会用plsql和Navicat等SQL语言操作工…

VS2019编译和使用gtest测试(C++)

目录 一、首先下载gtest开源 二、使用gtest 一、首先下载gtest开源 https://pan.baidu.com/s/15m62KAJ29vNe1mrmAcmehA 提取码&#xff1a;vfxz 下载下来解压到文件夹&#xff0c;再在文件夹里面新建一个build文件夹&#xff0c;如下&#xff1a; 再安装cmake&#xff0c;…

WEB集群-Tomact集群

linux云计算中小企业规模集群架构设计图----总结 在写今天内容前&#xff0c;小编绘制一个图&#xff1a;我设计了linux云计算中小企业规模集群架构设计图&#xff08;也可根据业务需求&#xff0c;增加业务变成大型企业架构设计图&#xff09; 知识补充–故障案例-https no s…