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 封装了一个查询控件,专 ...
随机推荐
- phpstudy-sqlilabs-less-11
题目:POST - Error Based - Single quotes- String 基于错误的单引号post型字符变形的注入 看到有个账密输入口第一反应尝试post注入 打开post data ...
- 代码随想录算法训练营Day27 回溯算法|39. 组合总和 40.组合总和II 131.分割回文串
代码随想录算法训练营 39. 组合总和 题目链接:39. 组合总和 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 ta ...
- Python连接es笔记四之创建和删除操作
本文首发于公众号:Hunter后端 原文链接:Python连接es笔记四之创建和删除操作 这一篇笔记介绍一下索引和数据的创建和删除. 其实对于索引来说,如果可以接触到 kibana 的话,可以很方便的 ...
- Java(数组声明创建、初始化、特点、内存分析、边界)
数组的定义 数组是相同类型数据的有序集合 数组描述的是相同类型的若干数据,按照一定先后次序排序组合而成 其中,每一个数据称作一个数组元素,每个数组元素可以通过下标访问它们 1.数组声明和创建 声明 d ...
- logging 模块因权限问题写入日志失败
哈喽大家好,我是咸鱼 今天跟大家分享一个使用 Python 的 logging 模块写入日志文件时遇到的权限问题,不知道你们有没有遇到过 1.案例现象 今天上班的时候手机短信收到了 zabbix 告警 ...
- 聊一聊 Python 安装中的 --enable-shared
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 今天在 CentOS 7.4 使用源码编译安装 Python-2.7.15 的时候,发现了一个 ...
- uniapp主题切换功能的第二种实现方式(scss变量+require)
在上一篇 "uniapp主题切换功能的第一种实现方式(scss变量+vuex)" 中介绍了第一种如何切换主题,但我们总结出一些不好的地方,例如扩展性不强,维护起来也困难等等,那么接 ...
- 三分钟免费将 Claude API 接入个人服务
首先我们介绍一下今天的主角 Claude Claude 是最近新开放的一款 AI 聊天机器人,是世界上最大的语言模型之一,比之前的一些模型如 GPT-3 要强大得多,因此 Claude 被认为是 Ch ...
- 2023-06-09:什么是Redis事务?原理是什么?
2023-06-09:什么是Redis事务?原理是什么? 答案2023-06-09: Redis中的事务是以一组命令的形式出现的,这些命令被认为是最小的执行单位.事务可以保证在一个单独独立的隔离操作中 ...
- JUC同步锁原理源码解析五----Phaser
JUC同步锁原理源码解析五----Phaser Phaser Phaser的来源 A reusable synchronization barrier, similar in functionalit ...