首页 > 其他分享 >Css 一个选择器实现带你实现高级搜索的展开收起

Css 一个选择器实现带你实现高级搜索的展开收起

时间:2023-11-06 11:56:06浏览次数:30  
标签:style const form 实现 value column grid 选择器 Css

在表格页面中,我们经常用到带有展开收起功能的过滤表单,看似很简单的功能,但是实现起来通常不那么优雅。
我们使用grid布局来实现这个就非常简单:

.search-form {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-gap: 10px;

    &:not(.expend) {
        .el-form-item {
        // 前三个和最后一个一直显示,其他的隐藏
        &:nth-child(n + 4):not(:nth-last-child(-n + 1)) {
            display: none;
        }
        }
    }

    .el-form-item {
        margin-bottom: 0;
}

我们把它封装成通用组件

SearchForm.vue

<script setup lang="ts">
import { computed, ref, useCssModule, watch } from 'vue'
import type { FormInstance, FormProps } from 'element-plus'
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'

interface SearchFormProps extends Omit<FormProps, 'inline'> {
  column?: number
  offset?: boolean
}

const props = withDefaults(defineProps<SearchFormProps>(), {
  column: 4,
  offset: true
})

const emits = defineEmits<{
  toggle: [boolean]
  reset: []
  confirm: []
}>()

const style = useCssModule()

const formRef = ref<FormInstance | null>(null)
const expand = ref(false)
const offsetNum = ref(0)

const formProps = computed(() => {
  const { column, ...formProps } = props
  return formProps
})

const handleToggle = () => {
  handleSetOffset()
  expand.value = !expand.value
  emits('toggle', expand.value)
}

const handleReset = () => {
  emits('reset')
}

const handleConfirm = () => {
  emits('confirm')
}

const styleEl = ref<HTMLStyleElement | null>(null)

const handleGenerateCss = (column: number) => {
  const { searchForm } = style
  const css = `
    .${searchForm}:not(.expend) .el-form-item:nth-child(n + ${column}):not(:nth-last-child(-n + 1)) {
      display: none;
    }
  `
  const cssText = document.createTextNode(css)
  if (styleEl.value) {
    styleEl.value.removeChild(styleEl.value.firstChild)
    styleEl.value.appendChild(cssText)
  } else {
    const style = document.createElement('style')
    style.appendChild(cssText)
    styleEl.value = style
    document.head.appendChild(style)
  }
}

const handleCalcOffset = () => {
  const { column, offset } = props
  if (!offset) return 0
  const formEl: HTMLElement = formRef.value?.$el
  if (!formEl) return 0
  const formLength = formEl.querySelectorAll(
    '.el-form-item:not(.virtual)'
  ).length
  if (formLength < column) return column - formLength
  return column - (formLength % column)
}

const handleSetOffset = () => {
  offsetNum.value = handleCalcOffset()
}

watch(
  () => props.column,
  (column) => {
    handleGenerateCss(column)
    handleSetOffset()
  },
  { immediate: true }
)

defineExpose({
  form: formRef
})
</script>

<template>
  <el-form
    ref="formRef"
    v-bind="formProps"
    @submit.prevent="handleConfirm"
    @reset.prevent="handleReset"
    :class="[style.searchForm, { expend: expand }]"
  >
    <slot></slot>
    <div v-for="item of offsetNum" :key="item" class="el-form-item virtual" />
    <el-form-item>
      <el-button @click="handleToggle" :icon="expand ? ArrowUp : ArrowDown">
        {{ expand ? '收起' : '展开' }}
      </el-button>
      <el-button type="primary" native-type="submit">查询</el-button>
      <el-button native-type="reset">重置</el-button>
    </el-form-item>
  </el-form>
</template>

<style module lang="scss">
.searchForm {
  display: grid;
  grid-template-columns: repeat(v-bind(column), 1fr);
  grid-gap: 10px;

  :global(.el-form-item) {
    margin-bottom: 0;
  }
}
</style>

Usage

<script setup lang="ts">
import { reactive, ref } from 'vue'
import SearchForm from './Search.vue'

const formStore = reactive({
  name: '',
  region: '',
  type: '',
  age: '',
  title: '',
  color: '',
  tag: '',
  date: '',
  time: ''
})

</script>

<template>
  <SearchForm :model="formStore" labelWidth="100px">
    <el-form-item label="name" prop="name">
      <el-input v-model="formStore.name" />
    </el-form-item>
    <el-form-item label="region" prop="region">
      <el-input v-model="formStore.region" />
    </el-form-item>
    <el-form-item label="type" prop="type">
      <el-input v-model="formStore.type" />
    </el-form-item>
    <el-form-item label="age" prop="age">
      <el-input v-model="formStore.age" />
    </el-form-item>
    <el-form-item label="title" prop="title">
      <el-input v-model="formStore.title" />
    </el-form-item>
    <el-form-item label="color" prop="color">
      <el-input v-model="formStore.color" />
    </el-form-item>
    <el-form-item label="tag" prop="tag">
      <el-input v-model="formStore.tag" />
    </el-form-item>
    <el-form-item label="date" prop="date">
      <el-input v-model="formStore.date" />
    </el-form-item>
    <el-form-item label="time" prop="time">
      <el-input v-model="formStore.time" />
    </el-form-item>
    <el-form-item label="time" prop="time">
      <el-input v-model="formStore.time" />
    </el-form-item>
  </SearchForm>
</template>

标签:style,const,form,实现,value,column,grid,选择器,Css
From: https://www.cnblogs.com/coderDemo/p/17812342.html

相关文章

  • 数字孪生帮助水务行业实现智能化发展
    在当今数字化时代,水务行业也积极迎接变革,数字孪生技术正成为该行业的一项重要助力。数字孪生不仅帮助水务行业实现智能化发展,还提供了许多重要的优势,为水资源管理、供水系统运营和环境保护等方面带来了革命性的改变。水务行业面临着供水、污水处理、水资源管理等各种挑战,包括供需......
  • 前端的路由如何实现跳转?
     下面的路由配置-访问路径为: http://localhost:9999/#/ok/productData/tpProductDatajs配置路由跳转consttpRouter={path:'/ok',component:Layout,name:'ok',meta:{},children:[{path:'indexPricing�......
  • 【开源】基于Vue.js的电子元器件管理系统的设计和实现
    一、摘要1.1项目简介电子元器件是高校电子实验室进行实验的必备物品,随着电子元器件的种类不断增多,人工管理的方式容易出现错误,对实验室管理员的体验感也不是很好,所以需要开发一套电子元器件管理系统实现对电子元器件的数字化管理需求,其中包括对电子元器件档案的管理和采购入库、学......
  • C#中登录功能的实现
    具体代码//登录功能privatevoidbutton1_Click(objectsender,EventArgse){if(userID.Text==""||userPassword.Text==""){MessageBox.Show("用户名或者密码为空~");}......
  • 网页CAD SDK 集成后怎么实现参数化绘图(在线编辑CAD)
    前言MxCAD 的WEBCADSDK提供了参数化绘图的功能,我们可以通过查看继承自McDbEntity的类的所有实例,它们都可以进行参数化的绘图。首先我们应该在页面上显示一张图纸,请根据mxcad入门文档的说明或者通过查看github|gitee存储的初始化各种示例项目查看代码来实现显示图纸的页......
  • win bat 脚本 - 使用vbs实现 带参数 创建桌面快捷方式 - chrome多版本安装为例子
    官网下载win安装包,地址https://www.chromedownloads.net/chrome64win-canary/解压win安装chrome文件,得到这个文件夹 bat脚本放在同一个目录下安装脚本如下【可用的哦,这是带参数的】@echooff::快捷方式名称set"name=chrome快捷桌面启动入口"setroot=%~dp0se......
  • Winform中使用Log4Net实现日志记录到文件并循环覆盖
    场景log4nethttps://logging.apache.org/log4net/TheApachelog4netlibraryisatooltohelptheprogrammeroutputlogstatementstoavarietyofoutputtargets.log4netisaportoftheexcellentApachelog4j™frameworktotheMicrosoft®.NETruntime.We......
  • java web 上传文件夹的实现(支持Chrome)
    上传文件夹的思路其实就是将文件夹中所有的文件上传到服务器,上传的时候文件名称要从文件夹目录开始截取,以下图中的目录为例,index.html文件应该以news_1/index.html的路径传到服务器,所有文件上传之后,上传到服务器的文件夹路径是从上传的上传的文件路径截取到文件夹结束。下面详细介......
  • 记一次 OSS 大批量文件下载的实现 → bat脚本不好玩!
    开心一刻一天夜里,侄女跟我哥聊天侄女一脸期待的看着我哥:爸爸,你说妈妈和奶奶谁漂亮啊?我哥不慌不忙的拿起一粒瓜子,轻声说道:为啥没有你啊?侄女笑容渐起,似乎得到了她想要的回答,仍继续问道:那妈妈和奶奶还有我,谁漂亮?我哥瞄了一眼侄女,又拿起一粒瓜子坚定的说到:奶......
  • 优雅设计之美:实现Vue应用程序的时尚布局
    前言页面布局是减少代码重复和创建可维护且具有专业外观的应用程序的基本模式。如果使用的是Nuxt,则可以提供开箱即用的优雅解决方案。然而,令人遗憾的是,在Vue中,这些问题并未得到官方文档的解决。经过多次尝试,小编得出了一个运行良好且可扩展而不会令人头疼的架构的模式。下面用一......