|
@@ -1,8 +1,9 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import {computed, defineProps, onMounted, ref, watch} from "vue";
|
|
|
|
|
|
+import {computed, defineProps, nextTick, onMounted, ref, watch} from "vue";
|
|
import XEUtils from 'xe-utils'
|
|
import XEUtils from 'xe-utils'
|
|
import {PulldownMethods} from "vxe-table/types/pulldown";
|
|
import {PulldownMethods} from "vxe-table/types/pulldown";
|
|
-
|
|
|
|
|
|
+import {useVModel} from "@vueuse/core";
|
|
|
|
+import {VxeTableInstance} from "vxe-table";
|
|
|
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
modelValue: {
|
|
modelValue: {
|
|
@@ -12,9 +13,12 @@ const props = defineProps({
|
|
type: Function,
|
|
type: Function,
|
|
default: null
|
|
default: null
|
|
},
|
|
},
|
|
|
|
+ select: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
data: {
|
|
data: {
|
|
type: Array,
|
|
type: Array,
|
|
- twoWayBinding: true,
|
|
|
|
default: null
|
|
default: null
|
|
},
|
|
},
|
|
filterable: {
|
|
filterable: {
|
|
@@ -23,6 +27,8 @@ const props = defineProps({
|
|
},
|
|
},
|
|
code: String,
|
|
code: String,
|
|
name: String,
|
|
name: String,
|
|
|
|
+ // 绑定对象的 code 自动在拼接name在字段的后面
|
|
|
|
+ codeName: String,
|
|
clearable: {
|
|
clearable: {
|
|
type: Boolean,
|
|
type: Boolean,
|
|
default: false
|
|
default: false
|
|
@@ -48,14 +54,31 @@ const props = defineProps({
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
-const emits = defineEmits(['input', 'rowClick', 'clear', 'focus', 'blur', 'update:modelValue', 'update:data'])
|
|
|
|
|
|
+const emits = defineEmits([
|
|
|
|
+ 'input',
|
|
|
|
+ 'rowClick',
|
|
|
|
+ 'clear',
|
|
|
|
+ 'focus',
|
|
|
|
+ 'blur',
|
|
|
|
+ 'update:modelValue',
|
|
|
|
+ 'update:data'
|
|
|
|
+])
|
|
|
|
+
|
|
|
|
+// 数据绑定的 modelValue
|
|
|
|
+const modVal = useVModel(props, 'modelValue', emits)
|
|
|
|
+const modData = useVModel(props, 'data', emits)
|
|
|
|
+
|
|
|
|
+let modCode = ''
|
|
|
|
+let modName = ''
|
|
|
|
+
|
|
|
|
+let selectName = ''
|
|
|
|
|
|
const isObj = typeof props.modelValue === 'object'
|
|
const isObj = typeof props.modelValue === 'object'
|
|
const tempData = ref([])
|
|
const tempData = ref([])
|
|
const pulldownRef = ref<PulldownMethods>()
|
|
const pulldownRef = ref<PulldownMethods>()
|
|
const inputData = ref('')
|
|
const inputData = ref('')
|
|
const placeholder = ref(props.placeholder)
|
|
const placeholder = ref(props.placeholder)
|
|
-const vxeTableRef = ref()
|
|
|
|
|
|
+const vxeTableRef = ref<VxeTableInstance>()
|
|
const theRowIsCurrentlySelected = ref({
|
|
const theRowIsCurrentlySelected = ref({
|
|
row: {},
|
|
row: {},
|
|
index: -1
|
|
index: -1
|
|
@@ -114,27 +137,39 @@ const change = XEUtils.debounce(async (value) => {
|
|
}
|
|
}
|
|
if (props.queryDataFunc === null) return
|
|
if (props.queryDataFunc === null) return
|
|
try {
|
|
try {
|
|
- let res = await props.queryDataFunc(value)
|
|
|
|
|
|
+ let res = await props.queryDataFunc(value) as Array<any>
|
|
if (typeof res === 'undefined') {
|
|
if (typeof res === 'undefined') {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
if (props.data === null) {
|
|
if (props.data === null) {
|
|
tempData.value = res
|
|
tempData.value = res
|
|
|
|
+ } else {
|
|
|
|
+ modData.value = res
|
|
|
|
+ await nextTick()
|
|
|
|
+ if (res.length !== modData.value.length) {
|
|
|
|
+ console.error('请使用 v-model:data 绑定data')
|
|
|
|
+ }
|
|
}
|
|
}
|
|
} catch {
|
|
} catch {
|
|
}
|
|
}
|
|
- pulldownRef.value.showPanel()
|
|
|
|
|
|
+ await pulldownRef.value.showPanel()
|
|
currentIndex.value = -1
|
|
currentIndex.value = -1
|
|
}, 500)
|
|
}, 500)
|
|
|
|
|
|
const rowClick = (val) => {
|
|
const rowClick = (val) => {
|
|
let {row, rowIndex} = val
|
|
let {row, rowIndex} = val
|
|
pulldownRef.value?.hidePanel()
|
|
pulldownRef.value?.hidePanel()
|
|
- if (isObj) {
|
|
|
|
- props.modelValue[props.code] = row.code
|
|
|
|
- props.modelValue[props.name] = row.name
|
|
|
|
|
|
+
|
|
|
|
+ if (props.select) {
|
|
|
|
+ modVal.value = row.code
|
|
|
|
+ selectName = row.name
|
|
} else {
|
|
} else {
|
|
- emits('update:modelValue', row.name)
|
|
|
|
|
|
+ if (isObj) {
|
|
|
|
+ props.modelValue[modCode] = row.code
|
|
|
|
+ props.modelValue[modName] = row.name
|
|
|
|
+ } else {
|
|
|
|
+ modVal.value = row.name
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
emits('rowClick', row, rowIndex)
|
|
emits('rowClick', row, rowIndex)
|
|
@@ -149,15 +184,27 @@ const rowClick = (val) => {
|
|
|
|
|
|
const inputClick = async () => {
|
|
const inputClick = async () => {
|
|
await pulldownRef.value.togglePanel()
|
|
await pulldownRef.value.togglePanel()
|
|
|
|
+ if (props.select) {
|
|
|
|
+ await vxeTableRef.value.setCurrentRow(theRowIsCurrentlySelected.value.row)
|
|
|
|
+ await vxeTableRef.value.scrollToRow(theRowIsCurrentlySelected.value.row)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
const handleFocus = () => {
|
|
const handleFocus = () => {
|
|
- if (isObj) {
|
|
|
|
- placeholder.value = props.modelValue[props.name]
|
|
|
|
|
|
+ if (props.select) {
|
|
|
|
+ placeholder.value = selectName
|
|
} else {
|
|
} else {
|
|
- placeholder.value = <string>props.modelValue;
|
|
|
|
|
|
+ if (isObj) {
|
|
|
|
+ placeholder.value = props.modelValue[modName]
|
|
|
|
+ } else {
|
|
|
|
+ placeholder.value = <string>props.modelValue;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
inputData.value = ''
|
|
inputData.value = ''
|
|
|
|
+ if (!placeholder.value) {
|
|
|
|
+ placeholder.value = props.placeholder
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
const handleBlur = () => {
|
|
const handleBlur = () => {
|
|
@@ -165,11 +212,16 @@ const handleBlur = () => {
|
|
if (pulldownRef.value.isPanelVisible()) {
|
|
if (pulldownRef.value.isPanelVisible()) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if (isObj) {
|
|
|
|
- inputData.value = props.modelValue[props.name]
|
|
|
|
|
|
+ if (props.select) {
|
|
|
|
+ inputData.value = selectName
|
|
} else {
|
|
} else {
|
|
- inputData.value = <string>props.modelValue;
|
|
|
|
|
|
+ if (isObj) {
|
|
|
|
+ inputData.value = props.modelValue[modName];
|
|
|
|
+ } else {
|
|
|
|
+ inputData.value = <string>props.modelValue;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
const keyUp = () => {
|
|
const keyUp = () => {
|
|
@@ -220,27 +272,59 @@ const enterToSelect = () => {
|
|
}
|
|
}
|
|
|
|
|
|
const handleClear = () => {
|
|
const handleClear = () => {
|
|
- if (isObj) {
|
|
|
|
- props.modelValue[props.code] = ''
|
|
|
|
- props.modelValue[props.name] = ''
|
|
|
|
|
|
+ if (props.select) {
|
|
|
|
+ modVal.value = ''
|
|
} else {
|
|
} else {
|
|
- emits('update:modelValue', '')
|
|
|
|
|
|
+ if (isObj) {
|
|
|
|
+ props.modelValue[modCode] = ''
|
|
|
|
+ props.modelValue[modName] = ''
|
|
|
|
+ } else {
|
|
|
|
+ modVal.value = ''
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- placeholder.value = ''
|
|
|
|
|
|
+ placeholder.value = props.placeholder
|
|
}
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
if (isObj) {
|
|
if (isObj) {
|
|
- if (!props.code || !props.name) {
|
|
|
|
- console.error('绑定是对象,要填写 code 和 name')
|
|
|
|
|
|
+ if (props.select) {
|
|
|
|
+ console.error('绑定是对象,无法使用select')
|
|
|
|
+ }
|
|
|
|
+ if (props.codeName) {
|
|
|
|
+ modCode = props.codeName;
|
|
|
|
+ modName = props.codeName + 'Name';
|
|
|
|
+ } else {
|
|
|
|
+ if (!props.code || !props.name) {
|
|
|
|
+ console.error('绑定是对象,要填写 code 和 name');
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- watch(() => props.modelValue[props.code], () => {
|
|
|
|
- inputData.value = props.modelValue[props.name]
|
|
|
|
|
|
+ watch(() => props.modelValue[modCode], () => {
|
|
|
|
+ inputData.value = props.modelValue[modName]
|
|
}, {immediate: true, deep: true});
|
|
}, {immediate: true, deep: true});
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
watch(() => props.modelValue, () => {
|
|
watch(() => props.modelValue, () => {
|
|
- inputData.value = <string>props.modelValue
|
|
|
|
|
|
+ if (props.select) {
|
|
|
|
+ let data = XEUtils.find(computedData.value, (item, key) => {
|
|
|
|
+ if (item.code === props.modelValue) {
|
|
|
|
+ theRowIsCurrentlySelected.value = {
|
|
|
|
+ row: item,
|
|
|
|
+ index: key
|
|
|
|
+ }
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ if (data) {
|
|
|
|
+ inputData.value = data.name
|
|
|
|
+ } else {
|
|
|
|
+ inputData.value = <string>modVal.value
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ inputData.value = <string>props.modelValue;
|
|
|
|
+ }
|
|
}, {immediate: true, deep: true})
|
|
}, {immediate: true, deep: true})
|
|
}
|
|
}
|
|
|
|
|