|
@@ -1,5 +1,19 @@
|
|
<script>
|
|
<script>
|
|
-import { defineProps, ref, reactive, computed, provide, getCurrentInstance, watch, nextTick, onMounted, isReactive, readonly, toRefs, unref } from 'vue'
|
|
|
|
|
|
+import {
|
|
|
|
+ defineProps,
|
|
|
|
+ ref,
|
|
|
|
+ reactive,
|
|
|
|
+ computed,
|
|
|
|
+ provide,
|
|
|
|
+ getCurrentInstance,
|
|
|
|
+ watch,
|
|
|
|
+ nextTick,
|
|
|
|
+ onMounted,
|
|
|
|
+ isReactive,
|
|
|
|
+ readonly,
|
|
|
|
+ toRefs,
|
|
|
|
+ unref
|
|
|
|
+} from 'vue'
|
|
import { ClickOutside as vClickOutside } from 'element-plus'
|
|
import { ClickOutside as vClickOutside } from 'element-plus'
|
|
import hooks from '@ER/hooks'
|
|
import hooks from '@ER/hooks'
|
|
import _ from 'lodash-es'
|
|
import _ from 'lodash-es'
|
|
@@ -8,28 +22,28 @@ import { areaList } from '@vant/area-data'
|
|
import Region from './Region'
|
|
import Region from './Region'
|
|
import Store from './store'
|
|
import Store from './store'
|
|
export default {
|
|
export default {
|
|
- name: 'EverrightRegion'
|
|
|
|
|
|
+ name: 'EverrightRegion'
|
|
}
|
|
}
|
|
</script>
|
|
</script>
|
|
<script setup>
|
|
<script setup>
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
- multiple: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false
|
|
|
|
- },
|
|
|
|
- modelValue: {
|
|
|
|
- type: Array
|
|
|
|
- },
|
|
|
|
- placeholder: {
|
|
|
|
- type: String
|
|
|
|
- }
|
|
|
|
|
|
+ multiple: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+ modelValue: {
|
|
|
|
+ type: Array
|
|
|
|
+ },
|
|
|
|
+ placeholder: {
|
|
|
|
+ type: String
|
|
|
|
+ }
|
|
})
|
|
})
|
|
const emit = defineEmits(['update:modelValue', 'change'])
|
|
const emit = defineEmits(['update:modelValue', 'change'])
|
|
let inputInitialHeight = 0
|
|
let inputInitialHeight = 0
|
|
const pressDeleteCount = 0
|
|
const pressDeleteCount = 0
|
|
const region = new Region(areaList, {
|
|
const region = new Region(areaList, {
|
|
- isFilter: true,
|
|
|
|
- selectType: 3
|
|
|
|
|
|
+ isFilter: true,
|
|
|
|
+ selectType: 3
|
|
})
|
|
})
|
|
const tooltipRef = ref()
|
|
const tooltipRef = ref()
|
|
const tagWrapper = ref()
|
|
const tagWrapper = ref()
|
|
@@ -41,398 +55,379 @@ const filtering = ref(false)
|
|
const presentTags = ref([])
|
|
const presentTags = ref([])
|
|
const inputHover = ref(false)
|
|
const inputHover = ref(false)
|
|
const popperPaneRef = computed(() => {
|
|
const popperPaneRef = computed(() => {
|
|
- return _.get(unref(tooltipRef), 'popperRef.contentRef', '')
|
|
|
|
|
|
+ return _.get(unref(tooltipRef), 'popperRef.contentRef', '')
|
|
})
|
|
})
|
|
const store = new Store(region.getAll(), {
|
|
const store = new Store(region.getAll(), {
|
|
- value: 'value',
|
|
|
|
- label: 'label',
|
|
|
|
- children: 'children',
|
|
|
|
- disabled: 'disabled',
|
|
|
|
- multiple: props.multiple
|
|
|
|
|
|
+ value: 'value',
|
|
|
|
+ label: 'label',
|
|
|
|
+ children: 'children',
|
|
|
|
+ disabled: 'disabled',
|
|
|
|
+ multiple: props.multiple
|
|
})
|
|
})
|
|
const state = reactive({
|
|
const state = reactive({
|
|
- Namespace: 'region',
|
|
|
|
- menus: [{
|
|
|
|
- label: '全部',
|
|
|
|
- name: 'all',
|
|
|
|
- nodes: store.getNodes()
|
|
|
|
- }],
|
|
|
|
- popperVisible: false,
|
|
|
|
- activeName: 'all',
|
|
|
|
- value0: '',
|
|
|
|
- checkedValue: []
|
|
|
|
|
|
+ Namespace: 'region',
|
|
|
|
+ menus: [
|
|
|
|
+ {
|
|
|
|
+ label: '全部',
|
|
|
|
+ name: 'all',
|
|
|
|
+ nodes: store.getNodes()
|
|
|
|
+ }
|
|
|
|
+ ],
|
|
|
|
+ popperVisible: false,
|
|
|
|
+ activeName: 'all',
|
|
|
|
+ value0: '',
|
|
|
|
+ checkedValue: []
|
|
})
|
|
})
|
|
const ns = hooks.useNamespace('Main', state.Namespace)
|
|
const ns = hooks.useNamespace('Main', state.Namespace)
|
|
provide('Everright', {
|
|
provide('Everright', {
|
|
- state
|
|
|
|
|
|
+ state
|
|
})
|
|
})
|
|
-const getFlattedNodes = (leafOnly) => {
|
|
|
|
- return store.getFlattedNodes(leafOnly)
|
|
|
|
|
|
+const getFlattedNodes = leafOnly => {
|
|
|
|
+ return store.getFlattedNodes(leafOnly)
|
|
}
|
|
}
|
|
-const getCheckedNodes = (leafOnly) => {
|
|
|
|
- return getFlattedNodes(leafOnly).filter((node) => node.checked !== false)
|
|
|
|
|
|
+const getCheckedNodes = leafOnly => {
|
|
|
|
+ return getFlattedNodes(leafOnly).filter(node => node.checked !== false)
|
|
}
|
|
}
|
|
const calculateCheckedValue = (isFire = true) => {
|
|
const calculateCheckedValue = (isFire = true) => {
|
|
- const newNodes = getCheckedNodes(false)
|
|
|
|
- state.checkedValue = newNodes
|
|
|
|
- if (!multiple.value) {
|
|
|
|
- if (state.checkedValue.length) {
|
|
|
|
- state.value0 = state.checkedValue[0].calcText('/')
|
|
|
|
- } else {
|
|
|
|
- state.value0 = ''
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- state.value0 = state.checkedValue.length ? ' ' : ''
|
|
|
|
- }
|
|
|
|
- isFire && emit('update:modelValue', newNodes.map(e => e.value))
|
|
|
|
|
|
+ const newNodes = getCheckedNodes(false)
|
|
|
|
+ state.checkedValue = newNodes
|
|
|
|
+ if (!multiple.value) {
|
|
|
|
+ if (state.checkedValue.length) {
|
|
|
|
+ state.value0 = state.checkedValue[0].calcText('/')
|
|
|
|
+ } else {
|
|
|
|
+ state.value0 = ''
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ state.value0 = state.checkedValue.length ? ' ' : ''
|
|
|
|
+ }
|
|
|
|
+ isFire &&
|
|
|
|
+ emit(
|
|
|
|
+ 'update:modelValue',
|
|
|
|
+ newNodes.map(e => e.value)
|
|
|
|
+ )
|
|
}
|
|
}
|
|
const multiple = computed(() => !!props.multiple)
|
|
const multiple = computed(() => !!props.multiple)
|
|
const clearBtnVisible = computed(() => {
|
|
const clearBtnVisible = computed(() => {
|
|
- // return inputHover.value || !!state.checkedValue.length
|
|
|
|
- if (
|
|
|
|
- filtering.value ||
|
|
|
|
- !inputHover.value
|
|
|
|
- ) { return false }
|
|
|
|
|
|
+ // return inputHover.value || !!state.checkedValue.length
|
|
|
|
+ if (filtering.value || !inputHover.value) {
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
|
|
- return !!state.checkedValue.length
|
|
|
|
|
|
+ return !!state.checkedValue.length
|
|
})
|
|
})
|
|
-const genTag = (node) => {
|
|
|
|
- return {
|
|
|
|
- node,
|
|
|
|
- key: node.uid,
|
|
|
|
- text: node.calcText('/'),
|
|
|
|
- hitState: false,
|
|
|
|
- closable: !node.isDisabled,
|
|
|
|
- isCollapseTag: false
|
|
|
|
- }
|
|
|
|
|
|
+const genTag = node => {
|
|
|
|
+ return {
|
|
|
|
+ node,
|
|
|
|
+ key: node.uid,
|
|
|
|
+ text: node.calcText('/'),
|
|
|
|
+ hitState: false,
|
|
|
|
+ closable: !node.isDisabled,
|
|
|
|
+ isCollapseTag: false
|
|
|
|
+ }
|
|
}
|
|
}
|
|
const calculatePresentTags = () => {
|
|
const calculatePresentTags = () => {
|
|
- if (!multiple.value) return
|
|
|
|
|
|
+ if (!multiple.value) return
|
|
|
|
|
|
- const nodes = state.checkedValue
|
|
|
|
- const tags = []
|
|
|
|
|
|
+ const nodes = state.checkedValue
|
|
|
|
+ const tags = []
|
|
|
|
|
|
- const allTags = []
|
|
|
|
- nodes.forEach((node) => allTags.push(genTag(node)))
|
|
|
|
- allPresentTags.value = allTags
|
|
|
|
|
|
+ const allTags = []
|
|
|
|
+ nodes.forEach(node => allTags.push(genTag(node)))
|
|
|
|
+ allPresentTags.value = allTags
|
|
|
|
|
|
- if (nodes.length) {
|
|
|
|
- const [first, ...rest] = nodes
|
|
|
|
- const restCount = rest.length
|
|
|
|
|
|
+ if (nodes.length) {
|
|
|
|
+ const [first, ...rest] = nodes
|
|
|
|
+ const restCount = rest.length
|
|
|
|
|
|
- tags.push(genTag(first))
|
|
|
|
|
|
+ tags.push(genTag(first))
|
|
|
|
|
|
- if (restCount) {
|
|
|
|
- tags.push({
|
|
|
|
- key: -1,
|
|
|
|
- text: `+ ${restCount}`,
|
|
|
|
- closable: false,
|
|
|
|
- isCollapseTag: true
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (restCount) {
|
|
|
|
+ tags.push({
|
|
|
|
+ key: -1,
|
|
|
|
+ text: `+ ${restCount}`,
|
|
|
|
+ closable: false,
|
|
|
|
+ isCollapseTag: true
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- presentTags.value = tags
|
|
|
|
|
|
+ presentTags.value = tags
|
|
}
|
|
}
|
|
const handleEvent = (type, node, index, checked) => {
|
|
const handleEvent = (type, node, index, checked) => {
|
|
- const {
|
|
|
|
- multiple
|
|
|
|
- } = props
|
|
|
|
- if (type === 'click') {
|
|
|
|
- // eslint-disable-next-line
|
|
|
|
|
|
+ const { multiple } = props
|
|
|
|
+ if (type === 'click') {
|
|
|
|
+ // eslint-disable-next-line
|
|
if (index === -1 || node.isLeaf || !node.isLeaf && node.level === index) {
|
|
if (index === -1 || node.isLeaf || !node.isLeaf && node.level === index) {
|
|
- } else {
|
|
|
|
- state.menus.forEach((e, i) => {
|
|
|
|
- if (i > index + 1) {
|
|
|
|
- state.menus[i] = []
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- state.menus[index + 1] = {
|
|
|
|
- label: node.label,
|
|
|
|
- name: node.value,
|
|
|
|
- // nodes: [node].concat(node.children)
|
|
|
|
- nodes: node.children
|
|
|
|
- }
|
|
|
|
- state.activeName = node.value
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (type === 'checkbox') {
|
|
|
|
- if (checked === node.checked) return
|
|
|
|
- if (props.multiple) {
|
|
|
|
- node.doCheck(checked)
|
|
|
|
- } else {
|
|
|
|
- getCheckedNodes().forEach((e) => {
|
|
|
|
- e.doCheck(false)
|
|
|
|
- })
|
|
|
|
- node.doCheck(checked)
|
|
|
|
- }
|
|
|
|
- calculateCheckedValue()
|
|
|
|
- }
|
|
|
|
|
|
+ } else {
|
|
|
|
+ state.menus.forEach((e, i) => {
|
|
|
|
+ if (i > index + 1) {
|
|
|
|
+ state.menus[i] = []
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ state.menus[index + 1] = {
|
|
|
|
+ label: node.label,
|
|
|
|
+ name: node.value,
|
|
|
|
+ // nodes: [node].concat(node.children)
|
|
|
|
+ nodes: node.children
|
|
|
|
+ }
|
|
|
|
+ state.activeName = node.value
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (type === 'checkbox') {
|
|
|
|
+ if (checked === node.checked) return
|
|
|
|
+ if (props.multiple) {
|
|
|
|
+ node.doCheck(checked)
|
|
|
|
+ } else {
|
|
|
|
+ getCheckedNodes().forEach(e => {
|
|
|
|
+ e.doCheck(false)
|
|
|
|
+ })
|
|
|
|
+ node.doCheck(checked)
|
|
|
|
+ }
|
|
|
|
+ calculateCheckedValue()
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-const togglePopperVisible = (visible) => {
|
|
|
|
- if (visible !== state.popperVisible) {
|
|
|
|
- state.popperVisible = visible
|
|
|
|
- if (!visible) {
|
|
|
|
- hideSuggestionPanel()
|
|
|
|
- if (multiple.value) {
|
|
|
|
- searchInputValue.value = ''
|
|
|
|
- } else {
|
|
|
|
- state.checkedValue[0] && (state.value0 = state.checkedValue[0].calcText('/'))
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+const togglePopperVisible = visible => {
|
|
|
|
+ if (visible !== state.popperVisible) {
|
|
|
|
+ state.popperVisible = visible
|
|
|
|
+ if (!visible) {
|
|
|
|
+ hideSuggestionPanel()
|
|
|
|
+ if (multiple.value) {
|
|
|
|
+ searchInputValue.value = ''
|
|
|
|
+ } else {
|
|
|
|
+ state.checkedValue[0] && (state.value0 = state.checkedValue[0].calcText('/'))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
const updatePopperPosition = () => {
|
|
const updatePopperPosition = () => {
|
|
- nextTick(() => {
|
|
|
|
- tooltipRef.value.updatePopper()
|
|
|
|
- })
|
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ tooltipRef.value.updatePopper()
|
|
|
|
+ })
|
|
}
|
|
}
|
|
-const deleteTag = (tag) => {
|
|
|
|
- const node = tag.node
|
|
|
|
- node.doCheck(false)
|
|
|
|
- calculateCheckedValue()
|
|
|
|
|
|
+const deleteTag = tag => {
|
|
|
|
+ const node = tag.node
|
|
|
|
+ node.doCheck(false)
|
|
|
|
+ calculateCheckedValue()
|
|
}
|
|
}
|
|
-const inCheckedPath = (node) => {
|
|
|
|
- return state.checkedValue.some(e => _.intersection(node.pathValues, e.pathValues).length === node.level)
|
|
|
|
|
|
+const inCheckedPath = node => {
|
|
|
|
+ return state.checkedValue.some(e => _.intersection(node.pathValues, e.pathValues).length === node.level)
|
|
}
|
|
}
|
|
const updateStyle = () => {
|
|
const updateStyle = () => {
|
|
- const inputInner = input.value.input
|
|
|
|
- const tagWrapperEl = tagWrapper.value
|
|
|
|
- if (tagWrapperEl) {
|
|
|
|
- const { offsetHeight } = tagWrapperEl
|
|
|
|
- const height =
|
|
|
|
- presentTags.value.length > 0
|
|
|
|
- ? `${Math.max(offsetHeight + 6, inputInitialHeight)}px`
|
|
|
|
- : `${inputInitialHeight}px`
|
|
|
|
- inputInner.style.height = height
|
|
|
|
- updatePopperPosition()
|
|
|
|
- }
|
|
|
|
|
|
+ const inputInner = input.value.input
|
|
|
|
+ const tagWrapperEl = tagWrapper.value
|
|
|
|
+ if (tagWrapperEl) {
|
|
|
|
+ const { offsetHeight } = tagWrapperEl
|
|
|
|
+ const height = presentTags.value.length > 0 ? `${Math.max(offsetHeight + 6, inputInitialHeight)}px` : `${inputInitialHeight}px`
|
|
|
|
+ inputInner.style.height = height
|
|
|
|
+ updatePopperPosition()
|
|
|
|
+ }
|
|
}
|
|
}
|
|
const handleClear = () => {
|
|
const handleClear = () => {
|
|
- getCheckedNodes().forEach((e) => {
|
|
|
|
- e.doCheck(false)
|
|
|
|
- })
|
|
|
|
- calculateCheckedValue()
|
|
|
|
- togglePopperVisible(false)
|
|
|
|
|
|
+ getCheckedNodes().forEach(e => {
|
|
|
|
+ e.doCheck(false)
|
|
|
|
+ })
|
|
|
|
+ calculateCheckedValue()
|
|
|
|
+ togglePopperVisible(false)
|
|
}
|
|
}
|
|
-const searchKeyword = computed(() =>
|
|
|
|
- multiple.value ? searchInputValue.value : state.value0
|
|
|
|
-)
|
|
|
|
|
|
+const searchKeyword = computed(() => (multiple.value ? searchInputValue.value : state.value0))
|
|
const filterMethod = (node, keyword) => {
|
|
const filterMethod = (node, keyword) => {
|
|
- return node.text.includes(keyword)
|
|
|
|
|
|
+ return node.text.includes(keyword)
|
|
}
|
|
}
|
|
const calculateSuggestions = () => {
|
|
const calculateSuggestions = () => {
|
|
- const res = getFlattedNodes(false).filter((node) => {
|
|
|
|
- if (node.isDisabled) return false
|
|
|
|
- node.calcText('/')
|
|
|
|
- return filterMethod(node, searchKeyword.value.trim())
|
|
|
|
- })
|
|
|
|
- filtering.value = true
|
|
|
|
- suggestions.value = res
|
|
|
|
- updatePopperPosition()
|
|
|
|
|
|
+ const res = getFlattedNodes(false).filter(node => {
|
|
|
|
+ if (node.isDisabled) return false
|
|
|
|
+ node.calcText('/')
|
|
|
|
+ return filterMethod(node, searchKeyword.value.trim())
|
|
|
|
+ })
|
|
|
|
+ filtering.value = true
|
|
|
|
+ suggestions.value = res
|
|
|
|
+ updatePopperPosition()
|
|
}
|
|
}
|
|
const handleFilter = _.debounce(() => {
|
|
const handleFilter = _.debounce(() => {
|
|
- const { value } = searchKeyword
|
|
|
|
|
|
+ const { value } = searchKeyword
|
|
|
|
|
|
- if (!value) return
|
|
|
|
- calculateSuggestions()
|
|
|
|
|
|
+ if (!value) return
|
|
|
|
+ calculateSuggestions()
|
|
})
|
|
})
|
|
const hideSuggestionPanel = () => {
|
|
const hideSuggestionPanel = () => {
|
|
- filtering.value = false
|
|
|
|
|
|
+ filtering.value = false
|
|
}
|
|
}
|
|
const handleInput = (val, e) => {
|
|
const handleInput = (val, e) => {
|
|
- state.popperVisible.value && togglePopperVisible(true)
|
|
|
|
|
|
+ state.popperVisible.value && togglePopperVisible(true)
|
|
|
|
|
|
- if (e && e.isComposing) return
|
|
|
|
- val.trim() ? handleFilter() : hideSuggestionPanel()
|
|
|
|
|
|
+ if (e && e.isComposing) return
|
|
|
|
+ val.trim() ? handleFilter() : hideSuggestionPanel()
|
|
}
|
|
}
|
|
-watch(() => props.modelValue, (newVal) => {
|
|
|
|
- // const nodes = props.multiple ? newVal : [newVal]
|
|
|
|
- const nodes = newVal
|
|
|
|
- if (nodes.length) {
|
|
|
|
- nodes.forEach((e) => {
|
|
|
|
- store.getNodeByValue(e).doCheck(true)
|
|
|
|
- })
|
|
|
|
- } else {
|
|
|
|
- getCheckedNodes().forEach((e) => {
|
|
|
|
- e.doCheck(false)
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- calculateCheckedValue(false)
|
|
|
|
- calculatePresentTags()
|
|
|
|
-}, { immediate: true, deep: true })
|
|
|
|
-watch(presentTags, () => {
|
|
|
|
- nextTick(() => updateStyle())
|
|
|
|
-}, { immediate: true })
|
|
|
|
|
|
+watch(
|
|
|
|
+ () => props.modelValue,
|
|
|
|
+ newVal => {
|
|
|
|
+ // const nodes = props.multiple ? newVal : [newVal]
|
|
|
|
+ const nodes = newVal
|
|
|
|
+ if (nodes.length) {
|
|
|
|
+ nodes.forEach(e => {
|
|
|
|
+ store.getNodeByValue(e).doCheck(true)
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ getCheckedNodes().forEach(e => {
|
|
|
|
+ e.doCheck(false)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ calculateCheckedValue(false)
|
|
|
|
+ calculatePresentTags()
|
|
|
|
+ },
|
|
|
|
+ { immediate: true, deep: true }
|
|
|
|
+)
|
|
|
|
+watch(
|
|
|
|
+ presentTags,
|
|
|
|
+ () => {
|
|
|
|
+ nextTick(() => updateStyle())
|
|
|
|
+ },
|
|
|
|
+ { immediate: true }
|
|
|
|
+)
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
- const inputEl = input.value.$el
|
|
|
|
- inputInitialHeight = inputEl.offsetHeight
|
|
|
|
|
|
+ const inputEl = input.value.$el
|
|
|
|
+ inputInitialHeight = inputEl.offsetHeight
|
|
})
|
|
})
|
|
</script>
|
|
</script>
|
|
<template>
|
|
<template>
|
|
- <div
|
|
|
|
- :class="[ns.b()]"
|
|
|
|
- >
|
|
|
|
- <el-tooltip
|
|
|
|
- ref="tooltipRef"
|
|
|
|
- :popper-class="[ns.e('dropdown')]"
|
|
|
|
- effect="light"
|
|
|
|
- placement="bottom-start"
|
|
|
|
- :visible="state.popperVisible"
|
|
|
|
- >
|
|
|
|
- <div
|
|
|
|
- :class="[ns.e('regin')]"
|
|
|
|
- v-click-outside:[popperPaneRef]="() => togglePopperVisible(false)"
|
|
|
|
- @mouseenter="inputHover = true"
|
|
|
|
- @mouseleave="inputHover = false"
|
|
|
|
- @click="() => togglePopperVisible(true)"
|
|
|
|
- >
|
|
|
|
- <el-input
|
|
|
|
- :readonly="multiple"
|
|
|
|
- ref="input"
|
|
|
|
- :placeholder="searchInputValue ? '' : placeholder"
|
|
|
|
- v-model="state.value0"
|
|
|
|
- @input="handleInput"
|
|
|
|
- >
|
|
|
|
- <template #suffix>
|
|
|
|
- <el-icon
|
|
|
|
- v-if="clearBtnVisible"
|
|
|
|
- key="clear"
|
|
|
|
- :class="[ns.e('icon'), 'icon-circle-close']"
|
|
|
|
- @click.stop="handleClear"
|
|
|
|
- >
|
|
|
|
- <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728=""><path fill="currentColor" d="m466.752 512-90.496-90.496a32 32 0 0 1 45.248-45.248L512 466.752l90.496-90.496a32 32 0 1 1 45.248 45.248L557.248 512l90.496 90.496a32 32 0 1 1-45.248 45.248L512 557.248l-90.496 90.496a32 32 0 0 1-45.248-45.248L466.752 512z"></path><path fill="currentColor" d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z"></path></svg>
|
|
|
|
- </el-icon>
|
|
|
|
- <el-icon
|
|
|
|
- v-else
|
|
|
|
- key="arrow-down"
|
|
|
|
- :class="[
|
|
|
|
- ns.e('icon'),
|
|
|
|
- 'icon-arrow-down',
|
|
|
|
- state.popperVisible && ns.e('reverse')
|
|
|
|
- ]"
|
|
|
|
- @click.stop="togglePopperVisible()"
|
|
|
|
- >
|
|
|
|
- <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728=""><path fill="currentColor" d="M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z"></path></svg>
|
|
|
|
- </el-icon>
|
|
|
|
- </template>
|
|
|
|
- </el-input>
|
|
|
|
- <div v-if="multiple" ref="tagWrapper" :class="ns.e('tagsWrap')">
|
|
|
|
- <el-tag
|
|
|
|
- v-for="tag in presentTags"
|
|
|
|
- :key="tag.key"
|
|
|
|
- type="info"
|
|
|
|
- size="default"
|
|
|
|
- :closable="tag.closable"
|
|
|
|
- disable-transitions
|
|
|
|
- @close="deleteTag(tag)"
|
|
|
|
- >
|
|
|
|
- <template v-if="tag.isCollapseTag === false">
|
|
|
|
- <span>{{ tag.text }}</span>
|
|
|
|
- </template>
|
|
|
|
- <template v-else>
|
|
|
|
- <el-tooltip
|
|
|
|
- :teleported="false"
|
|
|
|
- :disabled="state.popperVisible"
|
|
|
|
- :fallback-placements="['bottom', 'top', 'right', 'left']"
|
|
|
|
- placement="bottom"
|
|
|
|
- effect="light"
|
|
|
|
- >
|
|
|
|
- <template #default>
|
|
|
|
- <span>{{ tag.text }}</span>
|
|
|
|
- </template>
|
|
|
|
- <template #content>
|
|
|
|
- <div :class="ns.e('collapse-tags')">
|
|
|
|
- <div
|
|
|
|
- v-for="(tag2, idx) in allPresentTags.slice(1)"
|
|
|
|
- :key="idx"
|
|
|
|
- :class="ns.e('collapse-tag')"
|
|
|
|
- >
|
|
|
|
- <el-tag
|
|
|
|
- :key="tag2.key"
|
|
|
|
- class="in-tooltip"
|
|
|
|
- type="info"
|
|
|
|
- size="default"
|
|
|
|
- :closable="tag2.closable"
|
|
|
|
- disable-transitions
|
|
|
|
- @close="deleteTag(tag2)"
|
|
|
|
- >
|
|
|
|
- <span>{{ tag2.text }}</span>
|
|
|
|
- </el-tag>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </el-tooltip>
|
|
|
|
- </template>
|
|
|
|
- </el-tag>
|
|
|
|
- <input
|
|
|
|
- v-model="searchInputValue"
|
|
|
|
- type="text"
|
|
|
|
- :class="ns.e('search-input')"
|
|
|
|
- @input="(e) => handleInput(searchInputValue, e)"
|
|
|
|
- @click.stop="togglePopperVisible(true)"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <template #content>
|
|
|
|
- <div>
|
|
|
|
- <el-tabs v-show="!filtering" v-model="state.activeName" class="demo-tabs">
|
|
|
|
- <el-tab-pane v-for="(item, index) in state.menus" :key="item.name" :label="item.label" :name="item.name">
|
|
|
|
- <el-scrollbar
|
|
|
|
- tag="ul"
|
|
|
|
- :wrap-class="ns.e('wrap')"
|
|
|
|
- :view-class="ns.e('list')"
|
|
|
|
- >
|
|
|
|
- <li
|
|
|
|
- v-for="node in item.nodes"
|
|
|
|
- :key="node.value"
|
|
|
|
- :class="[inCheckedPath(node) && ns.is('Selected')]"
|
|
|
|
- @click.stop="() => handleEvent('click', node, index)">
|
|
|
|
- <el-checkbox
|
|
|
|
- :disabled="node.isDisabled"
|
|
|
|
- :model-value="node.checked"
|
|
|
|
- @click.stop
|
|
|
|
- @update:model-value="(val) => handleEvent('checkbox', node, index, val)"
|
|
|
|
- />
|
|
|
|
- <span :class="[ns.e('label')]">{{node.label}}</span>
|
|
|
|
- <template v-if="!node.isLeaf">
|
|
|
|
- <el-icon :class="['arrow-right', ns.e('postfix')]">
|
|
|
|
- <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728=""><path fill="currentColor" d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z"></path></svg>
|
|
|
|
- </el-icon>
|
|
|
|
- </template>
|
|
|
|
- </li>
|
|
|
|
- </el-scrollbar>
|
|
|
|
- </el-tab-pane>
|
|
|
|
- </el-tabs>
|
|
|
|
- <el-scrollbar
|
|
|
|
- v-show="filtering"
|
|
|
|
- ref="suggestionPanel"
|
|
|
|
- tag="ul"
|
|
|
|
- :wrap-class="ns.e('wrap')"
|
|
|
|
- :view-class="ns.e('list')"
|
|
|
|
- >
|
|
|
|
- <template v-if="suggestions.length">
|
|
|
|
- <li
|
|
|
|
- v-for="node in suggestions"
|
|
|
|
- :class="[inCheckedPath(node) && ns.is('Selected')]"
|
|
|
|
- :key="node.value">
|
|
|
|
- <el-checkbox
|
|
|
|
- :disabled="node.isDisabled"
|
|
|
|
- @update:model-value="(val) => handleEvent('checkbox', node, -1, val)"
|
|
|
|
- :model-value="node.checked"
|
|
|
|
- @click.stop
|
|
|
|
- />
|
|
|
|
- <span :class="[ns.e('label')]">{{node.text}}</span>
|
|
|
|
- </li>
|
|
|
|
- </template>
|
|
|
|
- <slot v-else name="empty">
|
|
|
|
- <li class="el-cascader__empty-text">
|
|
|
|
- No matching data
|
|
|
|
- </li>
|
|
|
|
- </slot>
|
|
|
|
- </el-scrollbar>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </el-tooltip>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div :class="[ns.b()]">
|
|
|
|
+ <el-tooltip ref="tooltipRef" :popper-class="[ns.e('dropdown')]" effect="light" placement="bottom-start" :visible="state.popperVisible">
|
|
|
|
+ <div
|
|
|
|
+ v-click-outside:[popperPaneRef]="() => togglePopperVisible(false)"
|
|
|
|
+ :class="[ns.e('regin')]"
|
|
|
|
+ @mouseenter="inputHover = true"
|
|
|
|
+ @mouseleave="inputHover = false"
|
|
|
|
+ @click="() => togglePopperVisible(true)"
|
|
|
|
+ >
|
|
|
|
+ <el-input ref="input" v-model="state.value0" :readonly="multiple" :placeholder="searchInputValue ? '' : placeholder" @input="handleInput">
|
|
|
|
+ <template #suffix>
|
|
|
|
+ <el-icon v-if="clearBtnVisible" key="clear" :class="[ns.e('icon'), 'icon-circle-close']" @click.stop="handleClear">
|
|
|
|
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
|
|
|
|
+ <path
|
|
|
|
+ fill="currentColor"
|
|
|
|
+ d="m466.752 512-90.496-90.496a32 32 0 0 1 45.248-45.248L512 466.752l90.496-90.496a32 32 0 1 1 45.248 45.248L557.248 512l90.496 90.496a32 32 0 1 1-45.248 45.248L512 557.248l-90.496 90.496a32 32 0 0 1-45.248-45.248L466.752 512z"
|
|
|
|
+ ></path>
|
|
|
|
+ <path fill="currentColor" d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z"></path>
|
|
|
|
+ </svg>
|
|
|
|
+ </el-icon>
|
|
|
|
+ <el-icon
|
|
|
|
+ v-else
|
|
|
|
+ key="arrow-down"
|
|
|
|
+ :class="[ns.e('icon'), 'icon-arrow-down', state.popperVisible && ns.e('reverse')]"
|
|
|
|
+ @click.stop="togglePopperVisible()"
|
|
|
|
+ >
|
|
|
|
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
|
|
|
|
+ <path
|
|
|
|
+ fill="currentColor"
|
|
|
|
+ d="M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ </el-icon>
|
|
|
|
+ </template>
|
|
|
|
+ </el-input>
|
|
|
|
+ <div v-if="multiple" ref="tagWrapper" :class="ns.e('tagsWrap')">
|
|
|
|
+ <el-tag
|
|
|
|
+ v-for="tag in presentTags"
|
|
|
|
+ :key="tag.key"
|
|
|
|
+ type="info"
|
|
|
|
+ size="default"
|
|
|
|
+ :closable="tag.closable"
|
|
|
|
+ disable-transitions
|
|
|
|
+ @close="deleteTag(tag)"
|
|
|
|
+ >
|
|
|
|
+ <template v-if="tag.isCollapseTag === false">
|
|
|
|
+ <span>{{ tag.text }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ :teleported="false"
|
|
|
|
+ :disabled="state.popperVisible"
|
|
|
|
+ :fallback-placements="['bottom', 'top', 'right', 'left']"
|
|
|
|
+ placement="bottom"
|
|
|
|
+ effect="light"
|
|
|
|
+ >
|
|
|
|
+ <template #default>
|
|
|
|
+ <span>{{ tag.text }}</span>
|
|
|
|
+ </template>
|
|
|
|
+ <template #content>
|
|
|
|
+ <div :class="ns.e('collapse-tags')">
|
|
|
|
+ <div v-for="(tag2, idx) in allPresentTags.slice(1)" :key="idx" :class="ns.e('collapse-tag')">
|
|
|
|
+ <el-tag
|
|
|
|
+ :key="tag2.key"
|
|
|
|
+ class="in-tooltip"
|
|
|
|
+ type="info"
|
|
|
|
+ size="default"
|
|
|
|
+ :closable="tag2.closable"
|
|
|
|
+ disable-transitions
|
|
|
|
+ @close="deleteTag(tag2)"
|
|
|
|
+ >
|
|
|
|
+ <span>{{ tag2.text }}</span>
|
|
|
|
+ </el-tag>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </template>
|
|
|
|
+ </el-tag>
|
|
|
|
+ <input
|
|
|
|
+ v-model="searchInputValue"
|
|
|
|
+ type="text"
|
|
|
|
+ :class="ns.e('search-input')"
|
|
|
|
+ @input="e => handleInput(searchInputValue, e)"
|
|
|
|
+ @click.stop="togglePopperVisible(true)"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <template #content>
|
|
|
|
+ <div>
|
|
|
|
+ <el-tabs v-show="!filtering" v-model="state.activeName" class="demo-tabs">
|
|
|
|
+ <el-tab-pane v-for="(item, index) in state.menus" :key="item.name" :label="item.label" :name="item.name">
|
|
|
|
+ <el-scrollbar tag="ul" :wrap-class="ns.e('wrap')" :view-class="ns.e('list')">
|
|
|
|
+ <li
|
|
|
|
+ v-for="node in item.nodes"
|
|
|
|
+ :key="node.value"
|
|
|
|
+ :class="[inCheckedPath(node) && ns.is('Selected')]"
|
|
|
|
+ @click.stop="() => handleEvent('click', node, index)"
|
|
|
|
+ >
|
|
|
|
+ <el-checkbox
|
|
|
|
+ :disabled="node.isDisabled"
|
|
|
|
+ :model-value="node.checked"
|
|
|
|
+ @click.stop
|
|
|
|
+ @update:model-value="val => handleEvent('checkbox', node, index, val)"
|
|
|
|
+ />
|
|
|
|
+ <span :class="[ns.e('label')]">{{ node.label }}</span>
|
|
|
|
+ <template v-if="!node.isLeaf">
|
|
|
|
+ <el-icon :class="['arrow-right', ns.e('postfix')]">
|
|
|
|
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728="">
|
|
|
|
+ <path
|
|
|
|
+ fill="currentColor"
|
|
|
|
+ d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ </el-icon>
|
|
|
|
+ </template>
|
|
|
|
+ </li>
|
|
|
|
+ </el-scrollbar>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ <el-scrollbar v-show="filtering" ref="suggestionPanel" tag="ul" :wrap-class="ns.e('wrap')" :view-class="ns.e('list')">
|
|
|
|
+ <template v-if="suggestions.length">
|
|
|
|
+ <li v-for="node in suggestions" :key="node.value" :class="[inCheckedPath(node) && ns.is('Selected')]">
|
|
|
|
+ <el-checkbox
|
|
|
|
+ :disabled="node.isDisabled"
|
|
|
|
+ :model-value="node.checked"
|
|
|
|
+ @update:model-value="val => handleEvent('checkbox', node, -1, val)"
|
|
|
|
+ @click.stop
|
|
|
|
+ />
|
|
|
|
+ <span :class="[ns.e('label')]">{{ node.text }}</span>
|
|
|
|
+ </li>
|
|
|
|
+ </template>
|
|
|
|
+ <slot v-else name="empty">
|
|
|
|
+ <li class="el-cascader__empty-text">No matching data</li>
|
|
|
|
+ </slot>
|
|
|
|
+ </el-scrollbar>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|