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://www.mzph.cn/news/874965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vivado生成网表文件并创建自定义IP

平台&#xff1a;vivado2018.3 应用场景&#xff0c;在设计的过程中&#xff0c;我们一些特定的模块需要交付给别人&#xff0c;但是又不想让他们看到其中的源码。就可以将源码封装成网表和IP文件。 vivado生成网表文件 设置综合。设置-flatten_hierarchy* 为full。 这里可…

基于ansible进行运维自动化的研究以及相关的属性

一、ansible-简介 介绍 ansible是新出现的自动化运维工具&#xff0c;基于Python开发&#xff0c;集合了众多运维工具&#xff08;puppet、cfengine、chef、func、fabric&#xff09;的优点&#xff0c; 实现了批量系统配置、批量程序部署、批量运行命令等功能。 无客户端。 …

【香橙派开发板测试】:在黑科技Orange Pi AIpro部署YOLOv8深度学习纤维分割检测模型

文章目录 &#x1f680;&#x1f680;&#x1f680;前言一、1️⃣ Orange Pi AIpro开发板相关介绍1.1 &#x1f393; 核心配置1.2 ✨开发板接口详情图1.3 ⭐️开箱展示 二、2️⃣配置开发板详细教程2.1 &#x1f393; 烧录镜像系统2.2 ✨配置网络2.3 ⭐️使用SSH连接主板 三、…

为什么 FPGA 的效率低于 ASIC?

FPGA是“可重构逻辑”器件。先制造的芯片&#xff0c;再次设计时“重新配置”。 ASIC 不需要“重新配置”。你先设计&#xff0c;把它交给代工厂&#xff0c;然后制造芯片。 现在让我们看看这些芯片的结构是什么样的&#xff0c;以及它们的不同之处。 ● 逻辑单元&#xff1a;F…

小程序多排数据横向滚动实现

如何实现多排数据滚动效果 swiper 外部容器 swiper-item 每一页的数据 因为现在有多排数据,现在在swiper-item 中需要循环一个数组 初版 <template><view><view class"container"><view class"swiper-box"><swiper class&qu…

拍得更近、拍得更清:Pura 70 Pro如何做到5cm对焦?

众所周知&#xff0c;我们的眼睛离一个物品越近时&#xff0c;我们就越能看清该物品的细节&#xff0c;但物品距离超过某个极限时&#xff0c;反而会看不清楚——这是因为超出了眼睛所能对焦的极限。 对于手机摄像头来说&#xff0c;也具有相似的道理。当我们的手机镜头距离被…

windows server报错--无法启动此程序,因为计算机中丢失MSVCP120.dll解决办法(已解决)

无法启动此程序&#xff0c;因为计算机中丢失MSVCP120.dll解决办法。 win7系统丢失MSVCP120.dll解决方法&#xff1a; 1、安装微软常用运行库合集&#xff0c;就可以完美的解决&#xff0c;此C运行库算是很全了&#xff0c;安装它才免于重装系统&#xff0c;完美的解决了我的丢…

【elementui】记录el-table设置左、右列固定时,加大滚动条宽度至使滚动条部分被固定列遮挡的解决方法

当前elementui版本&#xff1a;2.8.2 现象&#xff1a;此处el-table__body-wrapper默认的滚动条宽度为8px&#xff0c;我加大到10px&#xff0c;如果不设置fixed一切正常&#xff0c;设置fixed后会被遮挡一点 el-table__fixed-right::before, .el-table__fixed::before 设置…

CentOS7使用Postfix, Dovecot搭建邮箱服务

CentOS7使用Postfix&#xff0c;Dovecot搭建邮箱服务的步骤与挑战&#xff1f; 为了满足企业内部或个人的邮件服务需求&#xff0c;使用CentOS7搭建一个稳定、安全的邮箱服务器是一个非常实用的解决方案。AokSend将详细介绍如何在CentOS7系统上使用Postfix和Dovecot搭建邮箱服…

linux系统进程占cpu 100%解决步骤

1.查找进程 ps aux 查看指定进程: ps aux | grep process_name2.根据进程查找对应的主进程 pstree -p | grep process_name 3.查看主进程目录并删除 ps -axu | grep process_name rm -rf /usr/bin/2cbbb

修改 Tomcat 默认端口号最简单的方法

前言 每次在创建一个新的Maven项目之后&#xff0c;启动项目总会报8080端口号被占用的问题&#xff0c;既然每次都有这样的困扰&#xff0c;那不如一了百了&#xff0c;直接修改默认的8080端口号。 &#xff08;如果还是想要默认端口号。可参考我主页文章杀死占用了8080的进程…

IB user verbs介绍

本文来自对内核源代码文档/Documentation/infiniband/user_verbs.rst的翻译和理解。 在Infiniband设备帮助下&#xff0c;跨计算机的两个进程可以相互访问对方的虚地址空间。在Linux操作系统上&#xff0c;支持进程能直接访问本地Infiniband设备的资源&#xff0c;从而实现跨机…

openmv学习笔记(24电赛笔记)

#opemv代码烧录清除详解 openmv的代码脱离IDE运行程序&#xff0c;只需要在IDE中将代码烧录道flash里面&#xff0c;断开IDE连接&#xff0c;上电之后&#xff0c;会自动执行main.py中的程序&#xff0c;IDE烧录的时候&#xff0c;会默认将程序后缀保存为 .py文件。 ​​​​​…

防爆智能手机如何助力电气行业保驾护航?

在电气行业的智能化转型浪潮中&#xff0c;防爆智能手机以其强大的数据处理能力、实时通讯功能及高度集成的安全特性&#xff0c;正成为保障电力网络稳定运行、预防安全隐患的得力助手。 防爆智能手机在电气行业中发挥着重要的保驾护航作用&#xff0c;主要体现在以下几个方面&…

swagger-ui.html报错404

问题1&#xff1a;权限受限无法访问 由于采用的Shiro安全框架&#xff0c;需要在配置类ShiroConfig下的Shiro 的过滤器链放行该页面&#xff1a;【添加&#xff1a;filterChainDefinitionMap.put("/swagger-ui.html", "anon");】 public ShiroFilterFact…

node+mysql实现(账户密码,阿里云短信验证,QQ邮箱注册登录,短信验证密码重置,邮箱密码重置)之注册,登录密码重置总篇

node+mysql实现账户登录 注意效果图项目插件代码参数说明短信验证模块邮箱验证模块注册方式登录方式密码重置前端页面部分登录页面账户登录页面(login.html)短信验证登录页面(smsLogin.html)邮箱登录页面(emailLogin.html)注册部分页面短信验证注册页面(register.html)邮…

【C++高阶】深度剖析:从零开始模拟实现 unordered 的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;哈希底层 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀哈希 &#x1f4d2;1. 改造 HashTable…

Qt多语言功能实现

本文介绍Qt多语言功能实现。 应用程序多语言支持是常用功能&#xff0c;比如产品需要出口到不同语种的国家。采用Qt的多语言支持工具可以方便实现应用程序的多语言功能。本文以中英文语言切换为例&#xff0c;简要介绍Qt的多语言功能实现。 1.界面设计 界面设计需要考虑使用…

正则表达式与文本三剑客之grep

目录 前言 一、grep命令 二、基础正则表达式常见元字符 2.1、特殊字符 2.2、定位符 2.3、非打印字符 三、元字符操作实例 3.1、查找特定字符 3.2、利用中括号“[]”来查找集合字符 3.3、查找行首“^”与行尾字符“$” 3.4、查找任意一个字符“.”与重复字符“*” 3.…

BGP选路之Preferred value

原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时&#xff0c;BGP协议会对这些BGP路由的属性进行比较&#xff0c;以确定去往该目标网络的最优BGP路由&#xff0c;然后将该最优BGP路由与去往同一目标网络的其他协议路由进行比较&#xff0c;从而决定是否将该最优…