下拉选择和多选弹窗组件简单封装
本篇介绍下拉选择和多选弹窗组件简单封装
本篇介绍下拉选择和多选弹窗组件简单封装
<template>
<div>
下拉组件和多选弹窗简单封装
<div>数据:{{ form }}</div>
<lee-form :form="form" :formList="formList" @update:form="updateForm">
<template v-slot:slotTwo>
<inputSingleSelectTable
:label="'name'"
prop="id"
:formList="formListTwo"
url="xxxx"
:columns="[
{ prop: 'id', label: 'id', width: 100 },
{ prop: 'name', label: '姓名', width: 100 },
{ prop: 'age', label: '年龄', width: 100 }
]"
@select="
(val) => {
console.log(val)
form.slotTwo = { label: val.name, value: val.id }
}
"
/>
</template>
<template v-slot:slotThree>
<inputMultipleSelectTable
:label="'name'"
prop="id"
url="xxxx"
:formList="formListThree"
:columns="[
{ prop: '', label: '', type: 'selection', width: 200 },
{ prop: 'id', label: 'id', width: 200 },
{ prop: 'name', label: '姓名', width: 200 },
{ prop: 'age', label: '年龄', width: 200 }
]"
@select="
(val) => {
console.log(val)
form.slotThree = val
}
"
/>
</template>
</lee-form>
</div>
</template>
<script setup lang="ts">
import { reactive, computed } from 'vue'
import { type FormList, FormInter } from '@/types/types'
import LeeForm from '@/components/form/leeForm.vue'
import inputSingleSelectTable from '@/components/form/inputSingleSelectTable.vue'
import inputMultipleSelectTable from '@/components/form/inputMultipleSelectTable.vue'
const formList = computed<FormList[]>(() => [
{
renderType: 'slot',
label: '单选悬浮窗',
prop: 'slotTwo',
span: 12,
slotName: 'slotTwo',
rules: [{ required: true, message: '请选择', trigger: 'blur' }]
},
{
renderType: 'slot',
label: '多选弹窗',
prop: 'slotThree',
span: 12,
slotName: 'slotThree',
rules: [{ required: true, message: '请选择', trigger: 'blur' }]
}
])
const formListTwo = computed<FormList[]>(() => [
{
renderType: 'ElInput',
label: '姓名',
prop: 'name',
span: 12
},
{
renderType: 'ElInputNumber',
label: '年龄',
prop: 'age',
span: 12
}
])
const formListThree = computed<FormList[]>(() => [
{
renderType: 'ElInput',
label: '姓名',
prop: 'name',
span: 12
},
{
renderType: 'ElInputNumber',
label: '年龄',
prop: 'age',
span: 12
}
])
const form = reactive{
name: '',
elCascader: []
})
/**
* 更新表单数据
* @param {Record<string, any>} val - 需要更新的表单数据对象
* @description 通过 Object.assign 方法将传入的数据对象合并到现有表单对象中
*/
const updateForm = (val: Record<string, any>) => {
console.log(val)
Object.assign(form, val)
}
</script>
<style scoped></style>
<!-- input框选择组件 -->
<template>
<div class="input-select-table">
<el-popover placement="bottom" :width="400" trigger="click">
<template #reference>
<el-input v-model="selectedValue" readonly placeholder="请选择" @click="showTable = true" />
</template>
<lee-form :form="form" :formList="formList" labelWidth="auto" @update:form="updateForm"
:buttonList="[{ btnType: 'primary', text: '查询'}]"></lee-form>
<LeeTable
:table-data="tableData"
:table-columns="columns"
:show-pagination="true"
:total="total"
:current-page="currentPage"
rowKey="prop"
@page-change="handlePageChange"
@row-click="handleRowClick"
/>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import LeeTable from '@/components/table/leeTable.vue'
const props = defineProps({
url: {
type: String,
default: ''
},
columns: {
type: Array,
default: () => []
},
label: {
type: String,
default: ''
},
prop: {
type: String,
default: ''
},
formList: {
type: Array,
default: () => []
}
})
interface TableRow {
[key: string]: any
}
const emit = defineEmits(['update:modelValue', 'pageChange', 'select'])
const showTable = ref(false)
const selectedValue = ref('')
const tableData = ref<TableRow[]>([])
let total = ref(0)
let currentPage = ref(1)
const form = ref({})
const handlePageChange = (page: number) => {
emit('pageChange', page)
currentPage.value = page
getData(page)
}
const handleRowClick = (row: any) => {
console.log('handleRowClick', row)
selectedValue.value = row[props.label]
showTable.value = false
emit('select', row)
}
const getData = (page: number = 1) => {
console.log(page, form.value)
if (props.url) {
// 获取数据
setTimeout(() => {
tableData.value = [
{
id: currentPage.value *10 + 1,
name: '张三',
age: 20
},
{
id: currentPage.value *10 + 2,
name: '李四',
age: 20
},
{
id: currentPage.value *10 + 3,
name: '王五',
age: 20
},
{
id: currentPage.value *10 + 4,
name: '赵六',
age: 20
}
]
total.value = 100
})
}
}
const updateForm = (val: Record<string, any>) => {
console.log(val)
Object.assign(form, val)
}
onMounted(() => {
if (props.url) {
getData()
}
})
</script>
<style scoped>
.input-select-table {
position: relative;
}
</style>
<template>
<div class="input-multiple-select-table">
<el-input v-model="selectedLabels" readonly placeholder="请选择" @click="showTable = true" />
<el-dialog v-model="showTable" width="80%" title="选择表格数据">
<lee-form :form="form" :formList="formList" @update:form="updateForm" :buttonList="[{ btnType: 'primary', text: '查询'}]"></lee-form>
<LeeTable
ref="tableRef"
:table-data="tableData"
:table-columns="columns"
:show-pagination="true"
:total="total"
:rowKey="prop"
:currentPage="currentPage"
@page-change="handlePageChange"
@selection-change="handleSelectionChange"
@deselected-rows="handelDeselectedRows"
/>
<!-- 显示已选内容 -->
<div class="selected-tags" style="height: 200px;border: 1px solid #ccc">
<el-tag
v-for="(item, index) in selectedValues"
:key="index"
closable
@close="removeTag(index)"
>
{{ item[props.label] }}
</el-tag>
</div>
<template #footer>
<div>
<el-button @click="showTable = false">取消</el-button>
<el-button type="primary" @click="showTable = false">确定</el-button>
</div>
</template>
</el-dialog>
<!-- 显示已选内容 -->
<div class="selected-tags">
<el-tag
v-for="(item, index) in selectedValues"
:key="index"
closable
@close="removeTag(index)"
>
{{ item[props.label] }}
</el-tag>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import LeeTable from '@/components/table/leeTable.vue'
const props = defineProps({
url: {
type: String,
default: ''
},
columns: {
type: Array,
default: () => []
},
label: {
type: String,
default: ''
},
prop: {
type: String,
default: ''
},
formList: {
type: Array,
default: () => []
}
})
interface TableRow {
[key: string]: any
}
const emit = defineEmits(['update:modelValue', 'pageChange', 'select'])
const showTable = ref(false)
const selectedLabels = ref('')
const selectedValues = ref<TableRow[]>([])
const tableData = ref<TableRow[]>([])
const total = ref(0)
const tableRef = ref()
let currentPage = ref(1)
const form = ref({})
const handlePageChange = (page: number) => {
emit('pageChange', page)
currentPage.value = page
getData(page)
}
const handleSelectionChange = (rows: TableRow[]) => {
rows.forEach((row) => {
const index = selectedValues.value.findIndex((item) => item[props.prop] === row[props.prop])
if (index === -1) {
selectedValues.value.push(row)
}
})
selectedLabels.value = rows.map((row) => row[props.label]).join(', ')
emit('select', rows)
}
const handelDeselectedRows = (rows: TableRow[]) => {
rows.forEach((row) => {
const index = selectedValues.value.findIndex((item) => item[props.prop] === row[props.prop])
if (index !== -1) {
selectedValues.value.splice(index, 1)
}
})
selectedLabels.value = rows.map((row) => row[props.label]).join(', ')
}
const removeTag = (index: number) => {
const [row] = selectedValues.value.splice(index, 1)
selectedLabels.value = selectedValues.value.map((row) => row[props.label]).join(', ')
tableRef.value.cancelRowSelection(row)
}
const getData = (page: number) => {
console.log(page)
// 获取数据
setTimeout(() => {
tableData.value = [
{ id: currentPage.value * 10 + 1, name: currentPage.value + '张三', age: 20 },
{ id: currentPage.value * 10 + 2, name: currentPage.value + '李四', age: 20 },
{ id: currentPage.value * 10 + 3, name: currentPage.value + '王五', age: 20 },
]
total.value = 100
if(tableRef.value){
tableRef.value.setRowsSelection(selectedValues.value)
}
},1000)
}
const updateForm = (val: Record<string, any>) => {
console.log(val)
Object.assign(form, val)
}
onMounted(() => {
if (props.url) {
// 获取数据
getData(1)
}
})
</script>
<style scoped>
.input-multiple-select-table {
position: relative;
}
.selected-tags {
margin-top: 8px;
}
.selected-tags .el-tag {
margin-right: 8px;
margin-bottom: 8px;
}
</style>
form表单和表格组件也做了相应调整,具体查看githua代码
小恐龙
专注于WEB和移动前端开发