vue3-select-linkage
Version:
vue3 下拉框联动组件
104 lines (98 loc) • 2.74 kB
text/typescript
import { defineComponent, ref, reactive, PropType, watch } from 'vue'
export default defineComponent({
name: 'VSelect',
props: {
options: {
type: Array as PropType<ICascadeOptions[]>,
default: () => []
},
value: {
type: Array as PropType<IBaseOption[]>,
default: () => []
},
fieldNames: {
type: Object as PropType<IFileOption>,
default: () => {
return {
label: 'name',
value: 'value',
children: 'children'
}
}
}
},
setup(props, context) {
const columns = ref<ICascadeOptions[][]>([])
const selectValue = reactive<ISelectOption>([])
const trueValue = ref<IBaseOption[]>(props.value || [])
const fieldNames = ref<IFileOption>(props.fieldNames)
const options = ref<ICascadeOptions[]>(props.options || [])
watch(
trueValue,
newVal => {
console.log(newVal)
context.emit('update:value', newVal)
context.emit('change', newVal)
},
{
deep: true
}
)
const findColumn = (
value: IBaseOption,
index: number,
options = props.options
) => {
if (options.length) {
for (const item of options) {
if (item[fieldNames.value.value] === value) {
columns.value[index] = options
selectValue[index] = item
break
}
if (item[fieldNames.value.children]?.length) {
findColumn(value, index, item[fieldNames.value.children])
}
}
}
}
const refreshColumns = (value: IBaseOption[]) => {
if (value.length) {
for (let a = 0; a < value.length; a++) {
findColumn(value[a], a)
}
}
}
const itemClick = (e: MouseEvent, index: number): void => {
const target: INewHTMLElement = e.target as INewHTMLElement
const item: ICascadeOptions = columns.value[index][target.selectedIndex]
trueValue.value[index] = item[fieldNames.value.value]
trueValue.value.length = index + 1
if (item[fieldNames.value['children']]?.length) {
columns.value[index + 1] = item[fieldNames.value['children']]
columns.value.length = index + 2
} else {
columns.value.length = index + 1
}
}
if (trueValue.value.length) {
refreshColumns(trueValue.value)
}
watch(
options,
() => {
if (options.value?.length) {
columns.value[0] = options.value
}
},
{
deep: true
}
)
return {
columns,
selectValue,
itemClick
}
}
})