|
|
@@ -0,0 +1,139 @@
|
|
|
+<template>
|
|
|
+ <div class="xc-select-v3__main">
|
|
|
+ <div>
|
|
|
+ <el-input ref="inputRef" @focus="focus" @blur="blur"/>
|
|
|
+ </div>
|
|
|
+ <div class="xc-select-v3-ui__main">
|
|
|
+ <el-scrollbar @scroll="scroll">
|
|
|
+ <div
|
|
|
+ v-show="isShow"
|
|
|
+ :style="{
|
|
|
+ height:virtualizationHeight
|
|
|
+ }">
|
|
|
+ <ul :style="{transform: `translateY(${translateY})`}">
|
|
|
+ <li v-for="(item,index) in tempData"
|
|
|
+ :title="item.name"
|
|
|
+ @mouseover="mouseover($event)">
|
|
|
+ <slot name="defalut" :item="item" v-if="isSlot"/>
|
|
|
+ <span v-else>
|
|
|
+ {{ item.name }}
|
|
|
+ </span>
|
|
|
+
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </el-scrollbar>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup name='XcSelectV2' lang="ts">
|
|
|
+import {ref, watch, defineProps, nextTick, computed, onMounted, useSlots} from 'vue'
|
|
|
+import {Ref} from "vue";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ data: {
|
|
|
+ type: Array,
|
|
|
+ default: []
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const inputRef: Ref<HTMLElement> = ref({})
|
|
|
+const isShow = ref(true)
|
|
|
+const virtualizationHeight = ref('400px')
|
|
|
+const itemHeight = 34
|
|
|
+const startIndex = ref(0)
|
|
|
+const displayNumber = ref(10)
|
|
|
+const translateY = ref('0px')
|
|
|
+const isSlot = ref(false)
|
|
|
+
|
|
|
+const focus = () => {
|
|
|
+ isShow.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const blur = () => {
|
|
|
+ // isShow.value = false
|
|
|
+}
|
|
|
+
|
|
|
+const mouseover = (e) => {
|
|
|
+ // console.log(e)
|
|
|
+}
|
|
|
+
|
|
|
+const tempData = computed(() => {
|
|
|
+ return props.data.slice(startIndex.value, startIndex.value + displayNumber.value)
|
|
|
+})
|
|
|
+
|
|
|
+const scroll = ({scrollTop}) => {
|
|
|
+ translateY.value = scrollTop + 'px'
|
|
|
+ startIndex.value = Math.floor(scrollTop / itemHeight)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+watch(() => props.data, async () => {
|
|
|
+ await nextTick()
|
|
|
+ virtualizationHeight.value = props.data.length * itemHeight + 'px'
|
|
|
+}, {immediate: true})
|
|
|
+
|
|
|
+const node = ref(null)
|
|
|
+onMounted(() => {
|
|
|
+ try {
|
|
|
+ isSlot.value = !!useSlots().defalut;
|
|
|
+ console.log(!!useSlots().defalut)
|
|
|
+ console.log(isSlot.value)
|
|
|
+ // node.value = useSlots().defalut()[0]
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e)
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(isSlot.value)
|
|
|
+})
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.xc-select-v3__main {
|
|
|
+ width: max-content;
|
|
|
+ position: absolute;
|
|
|
+}
|
|
|
+
|
|
|
+.xc-select-v3-ui__main {
|
|
|
+ overflow: hidden;
|
|
|
+ background-color: white;
|
|
|
+ color: black;
|
|
|
+ height: 170px;
|
|
|
+ position: relative;
|
|
|
+ top: 4px;
|
|
|
+
|
|
|
+ .xc-select-v3__list {
|
|
|
+ position: relative;
|
|
|
+ will-change: transform;
|
|
|
+ direction: ltr;
|
|
|
+ height: 100%;
|
|
|
+ width: 214px;
|
|
|
+ list-style: none;
|
|
|
+ padding: 6px 0;
|
|
|
+ margin: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ li {
|
|
|
+ padding: 0 32px 0 20px;
|
|
|
+ position: relative;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ color: #606266;
|
|
|
+ height: 34px;
|
|
|
+ line-height: 34px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .option_hover {
|
|
|
+ background-color: #f5f7fa !important;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+</style>
|