vue3封装筛选项
背景
项目开发中遇到筛选项,并且几个页面都有使用,依次写,太过于繁琐
筛选项解构如下

封装全局组件fjj-content
<template>
<div class="fjj-content">
<ul class="flex-col fjj-list">
<li v-for="(item, index) in list" :key="index">
<!-- custom 单选、多选 item.isMutiple 是否支持多选 -->
<div v-if="item.type === 'custom'">
<!-- item.isMutiple true 多选 -->
<div class="flex-row">
<span class="label-box">{{ item.title }}:</span>
<ul class="flex-row tags-list items-center">
<!-- 选中默认项 -->
<li
:class="{ activeLi: item.defaultSelect }"
class="justify-center items-center"
@click="selectDefault(item.detailList, item.isMutiple, item)"
>
<span> {{ item.defaultLabel }}</span>
</li>
<!-- 多选项、单选项公用一个 -->
<li
v-for="(ele, eIndex) in item.detailList"
:key="eIndex"
:class="{ activeLi: ele.isSelected }"
class="justify-center items-center"
@click="selectMutiple(eIndex, item.key, item.isMutiple, item)"
>
<span> {{ ele.title }}</span>
</li>
<!-- 单选项,且有日期选择框的那种 -->
<div v-if="!item.isMutiple && item.childrenType == 'rangetime'">
<el-date-picker
v-model="item.dateTime"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD HH:mm:ss"
@change="changeDate($event, item.key, item)"
/>
</div>
</ul>
</div>
</div>
</li>
</ul>
</div>
</template>
<script setup>
/***
* 筛选组件,当前支持多选、单选
* item.type (custom 单选、多选、rangetime 时间范围带时分秒、range 时间范围不带时分秒、rangenumber 数字范围)
* item.isMutiple 是否支持多选
* 筛选后返回格式{"listName1":[value,value](多选),"listName2":"value"(单选),...}
* rangenumber形式-可能为["",1]或[1,""]表示只有一个最大值或最小值
***/
// Props
defineProps({
list: {
type: Array,
default() {
return []
}
}
})
// Emit
const emit = defineEmits('resultConditon')
// Result object
const result = {}
// 选中默认项
const selectDefault = (list, isMutiple, item) => {
if (isMutiple) {
// 多选情况下,选中所有项
for (let i = 0; i < list.length; i++) {
list[i].isSelected = true
}
} else {
// 单选情况下,取消选中所有项并清空日期选择框
for (let i = 0; i < list.length; i++) {
list[i].isSelected = false
}
item.dateTime = null
}
item.defaultSelect = true
result[item.key] = ''
emit('resultConditon', result)
}
// 多选项点击事件
const selectMutiple = (index, key, isMutiple, item) => {
if (isMutiple) {
// 多选情况下,切换选中状态并更新结果对象
item.detailList[index].isSelected = !item.detailList[index].isSelected
if (!result[key]) {
result[key] = []
}
if (item.detailList[index].isSelected) {
result[key].push(item.detailList[index].value)
} else {
item.detailList[index].isSelected = false
let idx = result[key].indexOf(item.detailList[index].value)
result[key].splice(idx, 1)
}
let length = item.detailList.filter(item => item.isSelected).length
if (length === item.detailList.length || length == 0) {
item.defaultSelect = true
} else {
item.defaultSelect = false
}
console.log(result)
} else {
// 单选情况下,更新选中项并更新结果对象
item.defaultSelect = false
item.dateTime = null
result[key] = item.detailList[index].value
for (let i = 0; i < item.detailList.length; i++) {
if (index == i) {
item.detailList[i].isSelected = true
} else {
item.detailList[i].isSelected = false
}
}
}
emit('resultConditon', result)
}
// 选中日期框
const changeDate = (value, key, item) => {
const createTime = value ? [...value].join(',') : ''
result[key] = createTime
item.defaultSelect = false
for (let i = 0; i < item.detailList.length; i++) {
item.detailList[i].isSelected = false
}
if (!createTime) {
item.defaultSelect = true
}
emit('resultConditon', result)
}
</script>
<style lang="scss" scoped>
/* @use ''; 引入css类 */
.fjj-content {
.fjj-list {
row-gap: 10px;
& > li {
.label-box {
margin-right: 8px;
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #818181;
padding: 8px 0;
}
.tags-list {
li {
padding: 8px 14px;
margin-right: 2px;
cursor: pointer;
span {
line-height: 14px;
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #333333;
}
&.activeLi {
background: #ebf5ff;
span {
color: #2794ff;
}
}
}
}
}
}
}
</style>
以下是引入代码模块
<template>
<div class="newsInfo">
<!-- 筛选项 -->
<fjj-condition :list="menuList" @resultConditon="resultConditon" />
</div>
</template>
<script setup>
/**
* 筛选项数据
*/
const menuList = ref([
{
title: '信源类型',
type: 'custom',
key: 'siteTypes',
isMutiple: true, //多选
defaultLabel: '全选',
defaultSelect: true,
detailList: [
{
value: '6FD6F9F43DE8420',
title: '智库网站'
},
{
value: '5F4990CACF12410',
title: '新闻网站'
},
{
value: '5F4990CACF12666',
title: '社交媒体'
}
]
},
{
title: '采集时间',
type: 'custom',
key: 'createTime',
isMutiple: false, //单选
defaultLabel: '全部',
defaultSelect: true,
childrenType: 'rangetime',
detailList: [
{
title: '24h',
value: 1
},
{
title: '近三日',
value: 2
},
{
title: '最近一周',
value: 3
},
{
title: '最近一个月',
value: 4
}
]
}
])
// 获取筛选项数据
const resultConditon = obj => {
console.log(obj)
}
</script>
<style lang="scss" scoped>
/* @use ''; 引入css类 */
.newsInfo {
padding: 24px 39px 23px 40px;
}
</style>
vue3封装筛选项的更多相关文章
- vue3 封装简单的 tabs 切换组件
背景:公司项目要求全部换成 vue3 ,而且也没有应用像 element-ui 一类的UI组件,用到的公共组件都是根据项目需求封装的,下面是使用vue3实现简单的tabs组件,我只是把代码分享出来,实 ...
- vue3 封装el-table时,构造$children(类式写法)
由于业务需求(组件封装),需要在获取el-table下面的el-table-column实例 在 vue2.x 当中直接使用this.$children就可以获取到该实例 但是 vue3.x 弃用了$ ...
- Vue3 封装第三方组件(一)做一个合格的传声筒
各种UI库的功能都是非常强大的,尤其对于我这种不会 css 的人来说,就更是帮了大忙了. 只是嘛,如果再封装一下的话,那么用起来就会更方便了. 那么如何封装呢? 封装三要素 -- 属性.插槽.事件.方 ...
- Vue3 封装 Element Plus Menu 无限级菜单组件
本文分别使用 SFC(模板方式)和 tsx 方式对 Element Plus el-menu 组件进行二次封装,实现配置化的菜单,有了配置化的菜单,后续便可以根据路由动态渲染菜单. 1 数据结构定义 ...
- vue3封装input组件
使用了2种方法去封装input组件(.vue与.jsx) 代码如下 父组件: <template> <div> <h1>input组件封装</h1> & ...
- 【vue3】封装自定义全局插件
[vue3]封装自定义全局插件 原vue2方法 main.js import Vue from 'vue' import App from './App.vue' import router from ...
- [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处
前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...
- 基于element-ui的后台系统表格、dialog、筛选、自定义按钮、分页的一次性封装
方便基础业务开发封装的一套组件,基于vue2.5.x和element-ui,可以通过配置自动生成表格展示,表格新增.编辑功能.分页.筛选项.自定义显示表格数据等功能. 先上演示图片 --------- ...
- Vue3.0+Electron聊天室|electron跨平台仿QQ客户端|vue3.x聊天应用
基于vue3+electron11跨端仿制QQ桌面应用实战Vue3ElectronQchat. 使用vue3+electron+vuex4+ant-design-vue+v3scroll+v3laye ...
- 基于 element-plus 封装一个依赖 json 动态渲染的查询控件
前情回顾 基于 el-form 封装一个依赖 json 动态渲染的表单控件 Vue3 封装第三方组件(一)做一个合格的传声筒 功能 使用 vue3 + element-plus 封装了一个查询控件,专 ...
随机推荐
- mysql 新建数据库 排序规则
utf8_unicode_ci和utf8_general_ci对中.英文来说没有实质的差别.utf8_general_ci校对速度快,但准确度稍差.utf8_unicode_ci准确度高,但校对速度稍 ...
- vue自定义组件——search-box
pre { overflow-y: auto; max-height: 300px } github地址: https://github.com/lxmghct/my-vue-components 组 ...
- Charles抓包补充解释
配置 大佬的博客真的很详细很详细,我就不重复造轮子了,第一次直接看大佬的博客就好,这里Python爬取微信小程序(Charles) 补充解释 在这一步疑问很多,大佬说的不是很详细,就由我来补充下吧~ ...
- SpringIOC个人笔记
上一章讲解了SpringBoot中的 AutoConfiguration自动装配,而这一章就来讲讲自动装配时会用到的Spring三大特性之一的IOC控制反转. 使用过Spring的人都熟知,Spr ...
- macbook苹果m1芯片训练机器学习、深度学习模型,resnet101在mnist手写数字识别上做加速,torch.device("mps")
apple的m1芯片比以往cpu芯片在机器学习加速上听说有15倍的提升,也就是可以使用apple mac训练深度学习pytorch模型!!!惊呆了 安装apple m1芯片版本的pytorch 然后使 ...
- 主流原型设计工具-Axure
原型设计工具是一种用于设计和验证用户界面的软件工具,它可以帮助用户将界面设计想法转化为可交互的原型.以下是几种常见的原型设计工具: Axure:Axure是一款强大的原型设计工具,可以创建高保真的原型 ...
- 谈谈ChatGPT是否可以替代人
起初我以为我是搬砖的,最近发现其实只是一块砖,哪里需要哪里搬. 这两天临时被抽去支援跨平台相关软件开发,帮忙画几个界面.有了 ChatGPT 之后就觉得以前面向 Googel 编程会拉低我滴档次和逼格 ...
- PyInstaller 完美打包 Python 脚本,输出结构清晰、便于二次编辑的打包程序
引入问题 如果我要写一个 Python 项目,打包成 exe 运行(方便在没有 Python 的电脑上使用),我需要打包出的根目录结构美观,没有多余的.杂乱的依赖文件在那里碍眼,而且需要在发现 bug ...
- 曲线艺术编程 coding curves 第八章 贝赛尔曲线(Bézier Curves)
贝赛尔曲线(Bézier Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(s ...
- 浅聊一下 C#程序的 内存映射文件 玩法
一:背景 1. 讲故事 前段时间训练营里有朋友问 内存映射文件 是怎么玩的?说实话这东西理论我相信很多朋友都知道,就是将文件映射到进程的虚拟地址,说起来很容易,那如何让大家眼见为实呢?可能会难倒很多人 ...