项目开始
当我们拿到设计稿或者原型图时,看到如下图展示的页面。我们就要想如何能够减少工作量,做出可复用的组件。
既然每个页面都长得差不多,那我们观察可以发现,这个页面分成四个部分,
【搜索部分、新增部分、表格展示部分、分页部分】
由于本人使用的vue3+ts+element-plus+sass 开发,以下是我写的代码。
搜索部分
在我们的管理后台中,常见搜索包含【输入框,下拉列表,时间选择】;当页面存在0个或者多个搜索框时,一般采用列表或者对象来传递数据。那如何定义每一个数据的数据格式,以下是我使用TS定义的属性接口
export interface searchItemInterface {
key: string //这个很关键,这个是搜索框的字段
type: string //输入框的类型
modelValue?: string | number | undefined | boolean | string[] | Date[] //输入框的值类型
timeFormat?: string //日期输入框显示的格式
placeholder?: string //输入框的提示
clearable?: boolean //是否显示删除icon
name?: string //输入框前面的字段名
width?: number //输入框的宽度
change?: (arg?: any) => void //监听输入框变化函数
options?: any[] //选择下拉框的下拉列表
}
搜索vue模板
首先我们要在components文件夹中,创建 search 文件夹,并创建,Index.vue 和index.ts 两个文件
Index.vue 文件
<template>
<div class="search-context">
<div class="search-box">
<div class="search-block" v-for="(item, index) in data.list" :key="index">
<div class="search-title" v-if="item.name !== ''">{
{ item.name }}</div>
<div class="search-content">
<!-- 数字或文本输入框 -->
<template v-if="item.type === 'text' || item.type === 'number'">
<el-input
class="search-input"
:style="{ width: item.width + 'px' }"
:type="item.type"
v-model="item.modelValue"
:placeholder="item.placeholder ? item.placeholder : '请输入' + item.name"
:clearable="item.clearable"
@input="item.change"
/>
</template>
<!-- 下拉框 -->
<template v-else-if="item.type === 'select'">
<el-select
:style="{ width: item.width + 'px' }"
v-model="item.modelValue"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.name"
:clearable="item.clearable"
@change="item.change"
>
<el-option
v-for="itemOption in item.options"
:key="itemOption.value ? itemOption.value : itemOption.id"
:label="itemOption.label ? itemOption.label : item.name"
:value="itemOption.value ? itemOption.value : itemOption.id"
/>
</el-select>
</template>
<!-- 下拉框 多选框 -->
<template v-else-if="item.type === 'select-multiple'">
<el-select
:style="{ width: item.width + 'px' }"
v-model="item.modelValue"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.name"
:clearable="item.clearable"
multiple
collapse-tags
@change="item.change"
>
<el-option
v-for="itemOption in item.options"
:key="itemOption.value ? itemOption.value : itemOption.id"
:label="itemOption.label ? itemOption.label : item.name"
:value="itemOption.value ? itemOption.value : itemOption.id"
/>
</el-select>
</template>
<!-- 时间选择器 -->
<template v-else-if="item.type === 'date'">
<el-config-provider :locale="locale">
<el-date-picker
:style="{ width: item.width + 'px' }"
v-model="item.modelValue"
type="date"
format="YYYY-MM-DD"
:value-format="item.timeFormat"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.name"
@change="item.change"
/>
</el-config-provider>
</template>
<!-- 时间段选择器 -->
<template v-else-if="item.type === 'daterange'">
<el-config-provider :locale="locale">
<el-date-picker
style="width: 380px"
v-model="item.modelValue"
type="daterange"
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
:value-format="item.timeFormat"
:locale="locale"
@change="item.change"
:disabled-date="limitDate"
/>
</el-config-provider>
</template>
<!-- 时间段选择器 精确到秒 -->
<template v-else-if="item.type === 'datetimerange'">
<el-config-provider :locale="locale">
<el-date-picker
style="width: 380px"
v-model="item.modelValue"
type="datetimerange"
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY/MM/DD ddd"
:locale="locale"
@change="item.change"
:shortcuts="shortcuts"
:disabled-date="limitDate"
:default-time="defaultTime"
/>
</el-config-provider>
</template>
<!-- 月份选择器 -->
<template v-else-if="item.type === 'month'">
<el-date-picker
:style="{ width: item.width + 'px' }"
v-model="item.modelValue"
value-format="YYYY-MM"
type="month"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.name"
/>
</template>
<!-- 开关选择器 -->
<template v-else-if="item.type === 'switch'">
<el-switch v-model="item.modelValue" />
</template>
<!-- slot -->
<template v-else-if="item.type === 'slot'">
<div :style="{ width: item.width + 'px' }"><slot name="custom"></slot></div>
</template>
</div>
</div>
<div class="search-block btn-box">
<div class="btn">
<el-button @click="onSearch" type="primary">
<!-- <el-icon class="el-icon--left"><Search /></el-icon> -->
搜索
</el-button>
<el-button @click="onReset">
<!-- <el-icon class="el-icon--left"><Refresh /></el-icon> -->
清空
</el-button>
<slot name="btn"></slot>
</div>
<div class="add">
<slot name="add"></slot>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {
ref, reactive } from 'vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import {
searchItemInterface, SearchData } from './index'
import {
formatTime } from '@/utils'
/**
* 引入element-plus中文包
*/
const locale = ref(zhCn)
/**
* 注册父组件回调方法
*/
const emits = defineEmits(['search', 'reset'])
/**
* 接受来自父组件的传参
*/
const props = defineProps({
list: {
type: Array<searchItemInterface | string | string[]>,
default: () => {
return []
}
},
resetKeys: {
type: Array<searchItemInterface | string>,
default: () => {
return []
}
},
permission: {
type: Array<string>,
default: () => {
return []
}
}
})
/**
* 初始化数据
*/
const data = reactive(new SearchData(props.list))
const defaultTime: [Date, Date] = [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] // '00:00:00', '23:59:59'
const shortcuts = [
{
text: '今天',
value: () => {
const start = new Date()
return [
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, 0, 0),
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 23, 59, 59)
]
}
},
{
text: '昨天',
value: () => {
const start = new Date()
start.setDate(start.getDate() - 1)
return [
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, 0, 0),
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 23, 59, 59)
]
}
},
{
text: '上一周',
value: () => {
const end = new Date()
const start = new Date()
start.setDate(start.getDate() - 7)
return [
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, 0, 0),
new Date(end.getFullYear(), end.getMonth(), end.getDate(), 23, 59, 59)
]
}
},
{
text: '上个月',
value: () => {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 1)
return [
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, 0, 0),
new Date(end.getFullYear(), end.getMonth(), end.getDate(), 23, 59, 59)
]
}
},
{
text: '最近三个月',
value: () => {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 3)
return [
new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0, 0, 0)
标签:const,表格,管理系统,59,start,Date,new,getDate,页面
From: https://blog.csdn.net/aa18616377429/article/details/142178750