click suffix icon to show options
This commit is contained in:
@ -1,17 +1,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {nextTick, onMounted, onUnmounted, ref, toRefs, watch, watchEffect,} from "vue";
|
||||||
nextTick,
|
|
||||||
onMounted,
|
|
||||||
onUnmounted,
|
|
||||||
ref,
|
|
||||||
toRefs,
|
|
||||||
watch,
|
|
||||||
watchEffect,
|
|
||||||
} from "vue";
|
|
||||||
import InfiniteLoading from "v3-infinite-loading";
|
import InfiniteLoading from "v3-infinite-loading";
|
||||||
import "v3-infinite-loading/lib/style.css";
|
import "v3-infinite-loading/lib/style.css";
|
||||||
import { debounce } from "lodash-es"; //required if you're not going to override default slots
|
import {debounce} from "lodash-es"; //required if you're not going to override default slots
|
||||||
import { ElInput, ElPopover, ElScrollbar } from "element-plus";
|
import {ElInput, ElPopover, ElScrollbar} from "element-plus";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
@ -25,7 +17,7 @@ const props = defineProps({
|
|||||||
width: {
|
width: {
|
||||||
type: Number,
|
type: Number,
|
||||||
},
|
},
|
||||||
prefixIcon: { type: String },
|
prefixIcon: {type: String},
|
||||||
query: {
|
query: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
@ -43,13 +35,14 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { modelValue } = toRefs(props);
|
const {modelValue} = toRefs(props);
|
||||||
const loadKey = ref(0);
|
const loadKey = ref(0);
|
||||||
const emit = defineEmits(["update:modelValue", "change", "confirm"]);
|
const emit = defineEmits(["update:modelValue", "change", "confirm"]);
|
||||||
|
|
||||||
const showPopOver = ref(false);
|
const showPopOver = ref(false);
|
||||||
|
|
||||||
const inputRefWhenShowPop = ref();
|
const inputRefWhenShowPop = ref();
|
||||||
|
const inputRefWhenNotShowPop = ref()
|
||||||
const placeholderWhenShowPop = ref("");
|
const placeholderWhenShowPop = ref("");
|
||||||
const placeholderWhenNotShowPop = ref("");
|
const placeholderWhenNotShowPop = ref("");
|
||||||
const optionLabelWhenShowPop = ref("");
|
const optionLabelWhenShowPop = ref("");
|
||||||
@ -57,43 +50,43 @@ const optionLabelWhenNotShowPop = ref("");
|
|||||||
const echoLabel = ref("");
|
const echoLabel = ref("");
|
||||||
const options = ref([]);
|
const options = ref([]);
|
||||||
const page = ref(0);
|
const page = ref(0);
|
||||||
|
|
||||||
const initOptions = (keyword) => {
|
const initOptions = (keyword) => {
|
||||||
props
|
props
|
||||||
.remoteMethod({
|
.remoteMethod({
|
||||||
[props.query.page]: page.value,
|
[props.query.page]: page.value,
|
||||||
[props.query.size]: 10,
|
[props.query.size]: 10,
|
||||||
[props.query.searchKey]: keyword,
|
[props.query.searchKey]: keyword,
|
||||||
})
|
})
|
||||||
.then((rows) => {
|
.then((rows) => {
|
||||||
options.value = rows;
|
options.value = rows;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadMore = async ($state) => {
|
const loadMore = async ($state) => {
|
||||||
page.value++;
|
page.value++;
|
||||||
props
|
props
|
||||||
.remoteMethod({
|
.remoteMethod({
|
||||||
[props.query.page]: page.value,
|
[props.query.page]: page.value,
|
||||||
[props.query.size]: 10,
|
[props.query.size]: 10,
|
||||||
[props.query.searchKey]: showPopOver.value
|
[props.query.searchKey]: showPopOver.value
|
||||||
? optionLabelWhenShowPop.value ?? null
|
? optionLabelWhenShowPop.value ?? null
|
||||||
: null,
|
: null,
|
||||||
})
|
})
|
||||||
.then((rows) => {
|
.then((rows) => {
|
||||||
options.value.push(...rows);
|
options.value.push(...rows);
|
||||||
if (rows.length < 10) {
|
if (rows.length < 10) {
|
||||||
$state.complete();
|
$state.complete();
|
||||||
} else {
|
} else {
|
||||||
$state.loaded();
|
$state.loaded();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
$state.error();
|
$state.error();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInputClick = () => {
|
const handleInputClick = (event) => {
|
||||||
|
event.stopPropagation()
|
||||||
showPopOver.value = true;
|
showPopOver.value = true;
|
||||||
placeholderWhenShowPop.value = optionLabelWhenNotShowPop.value;
|
placeholderWhenShowPop.value = optionLabelWhenNotShowPop.value;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@ -143,12 +136,12 @@ watchEffect(() => {
|
|||||||
if (showPopOver.value) return;
|
if (showPopOver.value) return;
|
||||||
if (modelValue.value) {
|
if (modelValue.value) {
|
||||||
optionLabelWhenNotShowPop.value =
|
optionLabelWhenNotShowPop.value =
|
||||||
options.value.find((el) => el[props.prop.value] === modelValue.value)?.[
|
options.value.find((el) => el[props.prop.value] === modelValue.value)?.[
|
||||||
props.prop.label
|
props.prop.label
|
||||||
] ??
|
] ??
|
||||||
echoLabel.value ??
|
(echoLabel.value.length ? echoLabel.value : null) ??
|
||||||
props.defaultLabel ??
|
props.defaultLabel ??
|
||||||
"...";
|
"...";
|
||||||
} else {
|
} else {
|
||||||
optionLabelWhenNotShowPop.value = "";
|
optionLabelWhenNotShowPop.value = "";
|
||||||
placeholderWhenNotShowPop.value = props.placeholder;
|
placeholderWhenNotShowPop.value = props.placeholder;
|
||||||
@ -159,6 +152,7 @@ watch(modelValue, (value) => {
|
|||||||
emit("change", value);
|
emit("change", value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 点击空白关闭弹出选项列表
|
* 点击空白关闭弹出选项列表
|
||||||
* @param event
|
* @param event
|
||||||
@ -179,6 +173,17 @@ onMounted(() => {
|
|||||||
page.value++;
|
page.value++;
|
||||||
initOptions();
|
initOptions();
|
||||||
document.body.addEventListener("click", handleBodyClick);
|
document.body.addEventListener("click", handleBodyClick);
|
||||||
|
watch(showPopOver, (show) => {
|
||||||
|
if (show) {
|
||||||
|
inputRefWhenNotShowPop.value?.input?.parentNode?.removeEventListener('click', handleInputClick)
|
||||||
|
} else {
|
||||||
|
nextTick(() => {
|
||||||
|
inputRefWhenNotShowPop.value?.input?.parentNode?.addEventListener('click', handleInputClick)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}, {immediate: true})
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@ -188,48 +193,48 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-popover
|
<el-popover
|
||||||
:popper-style="{
|
:popper-style="{
|
||||||
padding: 0,
|
padding: 0,
|
||||||
}"
|
}"
|
||||||
:visible="showPopOver"
|
:visible="showPopOver"
|
||||||
:width="width ?? 240"
|
:width="width ?? 240"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div :style="`width: ${width ?? 240}px`">
|
<div :style="`width: ${width ?? 240}px`">
|
||||||
<!--选项显示时-->
|
<!--选项显示时-->
|
||||||
<el-input
|
<el-input
|
||||||
v-if="showPopOver"
|
v-if="showPopOver"
|
||||||
ref="inputRefWhenShowPop"
|
ref="inputRefWhenShowPop"
|
||||||
v-model="optionLabelWhenShowPop"
|
v-model="optionLabelWhenShowPop"
|
||||||
:placeholder="placeholderWhenShowPop"
|
:placeholder="placeholderWhenShowPop"
|
||||||
:prefix-icon="prefixIcon"
|
:prefix-icon="prefixIcon"
|
||||||
:size="size ?? 'default'"
|
:size="size ?? 'default'"
|
||||||
class="select-inner"
|
class="select-inner"
|
||||||
suffix-icon="ArrowUp"
|
suffix-icon="ArrowUp"
|
||||||
@input="handleInputChange"
|
@input="handleInputChange"
|
||||||
@click.stop
|
@click.stop
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<slot name="prefix" />
|
<slot name="prefix"/>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<!--选项隐藏时-->
|
<!--选项隐藏时-->
|
||||||
<el-input
|
<el-input
|
||||||
v-else
|
v-else
|
||||||
v-model="optionLabelWhenNotShowPop"
|
ref="inputRefWhenNotShowPop"
|
||||||
:placeholder="placeholderWhenNotShowPop"
|
v-model="optionLabelWhenNotShowPop"
|
||||||
:prefix-icon="prefixIcon"
|
:placeholder="placeholderWhenNotShowPop"
|
||||||
:size="size ?? 'default'"
|
:prefix-icon="prefixIcon"
|
||||||
class="select-inner"
|
:size="size ?? 'default'"
|
||||||
clearable
|
class="select-inner"
|
||||||
suffix-icon="ArrowDown"
|
clearable
|
||||||
@clear="handleClearSeletion"
|
suffix-icon="ArrowDown"
|
||||||
@click.stop="handleInputClick"
|
@clear="handleClearSeletion"
|
||||||
>
|
>
|
||||||
<!-- @blur="handleInputBlur"-->
|
<!-- @click.stop="handleFocus"-->
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<slot name="prefix" />
|
<slot name="prefix"/>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
@ -237,12 +242,12 @@ onUnmounted(() => {
|
|||||||
<el-scrollbar class="options-wrap" height="260" @click.stop>
|
<el-scrollbar class="options-wrap" height="260" @click.stop>
|
||||||
<ul class="options">
|
<ul class="options">
|
||||||
<li
|
<li
|
||||||
v-for="option in options"
|
v-for="option in options"
|
||||||
:key="option[prop.value]"
|
:key="option[prop.value]"
|
||||||
:class="`option-item ${
|
:class="`option-item ${
|
||||||
option[prop.value] === modelValue ? 'selected' : null
|
option[prop.value] === modelValue ? 'selected' : null
|
||||||
}`"
|
}`"
|
||||||
@click.stop="selectOption(option)"
|
@click.stop="selectOption(option)"
|
||||||
>
|
>
|
||||||
{{ option[prop.label] }}
|
{{ option[prop.label] }}
|
||||||
</li>
|
</li>
|
||||||
@ -253,7 +258,7 @@ onUnmounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
<template #complete>
|
<template #complete>
|
||||||
<div
|
<div
|
||||||
style="display: flex; justify-content: center; align-items: center"
|
style="display: flex; justify-content: center; align-items: center"
|
||||||
>
|
>
|
||||||
-
|
-
|
||||||
</div>
|
</div>
|
||||||
|
@ -224,7 +224,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<template v-if="tenantSettingForm.mode==='3'">
|
<template v-if="tenantSettingForm.mode==='3'">
|
||||||
<div class="data-source-item">
|
<div v-for="item in tenantSettingForm.datasourceList" :key="`${item.ip}-${item.port}-${item.name}`"
|
||||||
|
class="data-source-item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="database-type">{{ "MySQL" }}</div>
|
<div class="database-type">{{ "MySQL" }}</div>
|
||||||
<div class="database-url">{{ "127.0.0.1" }} : {{ 3306 }}</div>
|
<div class="database-url">{{ "127.0.0.1" }} : {{ 3306 }}</div>
|
||||||
@ -285,6 +286,7 @@ const total = ref(0);
|
|||||||
const title = ref("");
|
const title = ref("");
|
||||||
const showTenantSetting = ref(false) /*是否显示租户设置对话框*/
|
const showTenantSetting = ref(false) /*是否显示租户设置对话框*/
|
||||||
const tenantSettingRef = ref()
|
const tenantSettingRef = ref()
|
||||||
|
const editDatasourceIndex = ref(-1)
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
form: {},
|
form: {},
|
||||||
queryParams: {
|
queryParams: {
|
||||||
@ -310,17 +312,17 @@ const data = reactive({
|
|||||||
},
|
},
|
||||||
tenantSettingForm: {
|
tenantSettingForm: {
|
||||||
// TODO:
|
// TODO:
|
||||||
dataSource: [
|
// dataSource: [
|
||||||
{
|
// {
|
||||||
type: "MySQL",
|
// type: "MySQL",
|
||||||
ip: "127.0.0.1",
|
// ip: "127.0.0.1",
|
||||||
port: "",
|
// port: "",
|
||||||
name: "",
|
// name: "",
|
||||||
username: "",
|
// username: "",
|
||||||
password: ""
|
// password: ""
|
||||||
}
|
// }
|
||||||
],
|
// ],
|
||||||
mode: '3'
|
// mode: '3'
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
tenantSettingRules: {
|
tenantSettingRules: {
|
||||||
@ -383,7 +385,14 @@ function reset() {
|
|||||||
const resetSettingTenant = () => {
|
const resetSettingTenant = () => {
|
||||||
form.value = {
|
form.value = {
|
||||||
/*TODO:*/
|
/*TODO:*/
|
||||||
datasourceList: []
|
datasourceList: [{
|
||||||
|
type: null,
|
||||||
|
ip: null,
|
||||||
|
port: null,
|
||||||
|
name: null,
|
||||||
|
username: null,
|
||||||
|
password: null,
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
tenantSettingRef.value?.resetFields()
|
tenantSettingRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
@ -430,6 +439,7 @@ function handleUpdate(row) {
|
|||||||
* @param row
|
* @param row
|
||||||
*/
|
*/
|
||||||
const handleSetting = (row) => {
|
const handleSetting = (row) => {
|
||||||
|
// editDatasourceIndex.value = 0
|
||||||
resetSettingTenant()
|
resetSettingTenant()
|
||||||
getSetting(row.tenantId).then(resp => {
|
getSetting(row.tenantId).then(resp => {
|
||||||
tenantSettingForm.value = resp.data
|
tenantSettingForm.value = resp.data
|
||||||
|
Reference in New Issue
Block a user