背景

项目开发中遇到筛选项,并且几个页面都有使用,依次写,太过于繁琐

筛选项解构如下

封装全局组件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封装筛选项的更多相关文章

  1. vue3 封装简单的 tabs 切换组件

    背景:公司项目要求全部换成 vue3 ,而且也没有应用像 element-ui 一类的UI组件,用到的公共组件都是根据项目需求封装的,下面是使用vue3实现简单的tabs组件,我只是把代码分享出来,实 ...

  2. vue3 封装el-table时,构造$children(类式写法)

    由于业务需求(组件封装),需要在获取el-table下面的el-table-column实例 在 vue2.x 当中直接使用this.$children就可以获取到该实例 但是 vue3.x 弃用了$ ...

  3. Vue3 封装第三方组件(一)做一个合格的传声筒

    各种UI库的功能都是非常强大的,尤其对于我这种不会 css 的人来说,就更是帮了大忙了. 只是嘛,如果再封装一下的话,那么用起来就会更方便了. 那么如何封装呢? 封装三要素 -- 属性.插槽.事件.方 ...

  4. Vue3 封装 Element Plus Menu 无限级菜单组件

    本文分别使用 SFC(模板方式)和 tsx 方式对 Element Plus el-menu 组件进行二次封装,实现配置化的菜单,有了配置化的菜单,后续便可以根据路由动态渲染菜单. 1 数据结构定义 ...

  5. vue3封装input组件

    使用了2种方法去封装input组件(.vue与.jsx) 代码如下 父组件: <template> <div> <h1>input组件封装</h1> & ...

  6. 【vue3】封装自定义全局插件

    [vue3]封装自定义全局插件 原vue2方法 main.js import Vue from 'vue' import App from './App.vue' import router from ...

  7. [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处

    前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...

  8. 基于element-ui的后台系统表格、dialog、筛选、自定义按钮、分页的一次性封装

    方便基础业务开发封装的一套组件,基于vue2.5.x和element-ui,可以通过配置自动生成表格展示,表格新增.编辑功能.分页.筛选项.自定义显示表格数据等功能. 先上演示图片 --------- ...

  9. Vue3.0+Electron聊天室|electron跨平台仿QQ客户端|vue3.x聊天应用

    基于vue3+electron11跨端仿制QQ桌面应用实战Vue3ElectronQchat. 使用vue3+electron+vuex4+ant-design-vue+v3scroll+v3laye ...

  10. 基于 element-plus 封装一个依赖 json 动态渲染的查询控件

    前情回顾 基于 el-form 封装一个依赖 json 动态渲染的表单控件 Vue3 封装第三方组件(一)做一个合格的传声筒 功能 使用 vue3 + element-plus 封装了一个查询控件,专 ...

随机推荐

  1. mysql 新建数据库 排序规则

    utf8_unicode_ci和utf8_general_ci对中.英文来说没有实质的差别.utf8_general_ci校对速度快,但准确度稍差.utf8_unicode_ci准确度高,但校对速度稍 ...

  2. vue自定义组件——search-box

    pre { overflow-y: auto; max-height: 300px } github地址: https://github.com/lxmghct/my-vue-components 组 ...

  3. Charles抓包补充解释

    配置 大佬的博客真的很详细很详细,我就不重复造轮子了,第一次直接看大佬的博客就好,这里Python爬取微信小程序(Charles) 补充解释 在这一步疑问很多,大佬说的不是很详细,就由我来补充下吧~ ...

  4. SpringIOC个人笔记

    上一章讲解了SpringBoot中的 AutoConfiguration自动装配,而这一章就来讲讲自动装配时会用到的Spring三大特性之一的IOC控制反转. ​ 使用过Spring的人都熟知,Spr ...

  5. macbook苹果m1芯片训练机器学习、深度学习模型,resnet101在mnist手写数字识别上做加速,torch.device("mps")

    apple的m1芯片比以往cpu芯片在机器学习加速上听说有15倍的提升,也就是可以使用apple mac训练深度学习pytorch模型!!!惊呆了 安装apple m1芯片版本的pytorch 然后使 ...

  6. 主流原型设计工具-Axure

    原型设计工具是一种用于设计和验证用户界面的软件工具,它可以帮助用户将界面设计想法转化为可交互的原型.以下是几种常见的原型设计工具: Axure:Axure是一款强大的原型设计工具,可以创建高保真的原型 ...

  7. 谈谈ChatGPT是否可以替代人

    起初我以为我是搬砖的,最近发现其实只是一块砖,哪里需要哪里搬. 这两天临时被抽去支援跨平台相关软件开发,帮忙画几个界面.有了 ChatGPT 之后就觉得以前面向 Googel 编程会拉低我滴档次和逼格 ...

  8. PyInstaller 完美打包 Python 脚本,输出结构清晰、便于二次编辑的打包程序

    引入问题 如果我要写一个 Python 项目,打包成 exe 运行(方便在没有 Python 的电脑上使用),我需要打包出的根目录结构美观,没有多余的.杂乱的依赖文件在那里碍眼,而且需要在发现 bug ...

  9. 曲线艺术编程 coding curves 第八章 贝赛尔曲线(Bézier Curves)

    贝赛尔曲线(Bézier Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(s ...

  10. 浅聊一下 C#程序的 内存映射文件 玩法

    一:背景 1. 讲故事 前段时间训练营里有朋友问 内存映射文件 是怎么玩的?说实话这东西理论我相信很多朋友都知道,就是将文件映射到进程的虚拟地址,说起来很容易,那如何让大家眼见为实呢?可能会难倒很多人 ...