|
@@ -0,0 +1,194 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="d-flex align-center search" v-if="search.show">
|
|
|
|
+ <ct-text-field
|
|
|
|
+ v-model="searchValue"
|
|
|
|
+ elevation="0"
|
|
|
|
+ density="compact"
|
|
|
|
+ hide-details
|
|
|
|
+ variant="text"
|
|
|
|
+ clear-icon="mdi-close-circle"
|
|
|
|
+ append-inner-icon="mdi-magnify"
|
|
|
|
+ placeholder="搜索职位/公司"
|
|
|
|
+ class="search-fullHeight"
|
|
|
|
+ type="text"
|
|
|
|
+ clearable
|
|
|
|
+ @click:append="sendMessage"
|
|
|
|
+ @click:append-inner="toggleMarker"
|
|
|
|
+ @click:clear="clearMessage"
|
|
|
|
+ @click:prepend="changeIcon"
|
|
|
|
+ >
|
|
|
|
+ <template v-slot:append>
|
|
|
|
+ <div class="full">
|
|
|
|
+ <ct-btn class="search-fullHeight search-btn" block width="100" elevation="0" @click="handleSearch">搜索</ct-btn>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ </template>
|
|
|
|
+ <template v-slot:prepend v-if="list.key">
|
|
|
|
+ <ct-menu :close-on-content-click="false">
|
|
|
|
+ <template v-slot:activator="{ props }">
|
|
|
|
+ <ct-btn
|
|
|
|
+ class="full"
|
|
|
|
+ color="primary"
|
|
|
|
+ variant="text"
|
|
|
|
+ v-bind="props"
|
|
|
|
+ >
|
|
|
|
+ {{ selectValue }}
|
|
|
|
+ <ct-icon right>mdi-menu-down</ct-icon>
|
|
|
|
+ </ct-btn>
|
|
|
|
+ </template>
|
|
|
|
+ <div class="list d-flex" @mouseleave="itemChildren = {}">
|
|
|
|
+ <div class="list-left py-2">
|
|
|
|
+ <div
|
|
|
|
+ v-for="(item, index) in list.data"
|
|
|
|
+ :key="'list' + index"
|
|
|
|
+ class="list-left-item d-flex justify-space-between pa-2"
|
|
|
|
+ :class="{ hover: itemChildren.value === item.value }"
|
|
|
|
+ @mousemove="handleMousemove(item)"
|
|
|
|
+ >
|
|
|
|
+ {{ item.label }}
|
|
|
|
+ <ct-icon v-if="item.children && item.children.length">mdi-menu-right</ct-icon>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="list-right pa-2 ml-1" v-show="itemChildren.children && itemChildren.children.length">
|
|
|
|
+ <div class="text-h6">{{ itemChildren.label }}</div>
|
|
|
|
+ <div v-for="item in itemChildren.children" :key="item.value" class="d-flex">
|
|
|
|
+ <div class="list-right-title"></div>
|
|
|
|
+ <div class="list-right-body"></div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </ct-menu>
|
|
|
|
+ </template>
|
|
|
|
+ </ct-text-field>
|
|
|
|
+ </div>
|
|
|
|
+ <slot name="search-next"></slot>
|
|
|
|
+ <div>
|
|
|
|
+ <div v-for="item in option" :key="'search' + item.label" class="option">
|
|
|
|
+ <div class="option-label">{{ item.label }}</div>
|
|
|
|
+ <div class="option-value" @click="handleClick(item)">{{ item.items.find(e => e.value === item.value).label }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script setup>
|
|
|
|
+import { ref, computed } from 'vue'
|
|
|
|
+defineOptions({ name: 'ct-search'})
|
|
|
|
+const props = defineProps({
|
|
|
|
+ search: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: () => {
|
|
|
|
+ return {
|
|
|
|
+ show: true,
|
|
|
|
+ placeholder: 'Search...'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ list: {
|
|
|
|
+ type: Object,
|
|
|
|
+ default: () => {
|
|
|
|
+ return {
|
|
|
|
+ key: 'test',
|
|
|
|
+ value: null,
|
|
|
|
+ itemLabel: 'label',
|
|
|
|
+ itemValue: 'value',
|
|
|
|
+ data: []
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ option: {
|
|
|
|
+ type: Array,
|
|
|
|
+ default: () => []
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const itemChildren = ref({})
|
|
|
|
+
|
|
|
|
+const searchValue = ref(null)
|
|
|
|
+
|
|
|
|
+const selectValue = computed(() => {
|
|
|
|
+ const label = props.list.itemLabel ?? 'label'
|
|
|
|
+ const value = props.list.itemValue ?? 'value'
|
|
|
|
+ const item = props.list.data.find(_e => _e.value === props.list[value])
|
|
|
|
+ return item[label]
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const handleMousemove = (item) => {
|
|
|
|
+ const value = props.list.itemValue ?? 'value'
|
|
|
|
+ if (itemChildren.value[value] === item.value) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ itemChildren.value = item
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const handleSearch = () => {
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.full {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+}
|
|
|
|
+.search {
|
|
|
|
+ height: 50px;
|
|
|
|
+ width: 800px;
|
|
|
|
+ margin: 0 auto;
|
|
|
|
+ border: 2px solid var(--v-primary-base);
|
|
|
|
+ border-radius: 5px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+
|
|
|
|
+ &-fullHeight {
|
|
|
|
+ height: 50px;
|
|
|
|
+ }
|
|
|
|
+ &-btn {
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ color: #fff;
|
|
|
|
+ background-color: var(--v-primary-base);
|
|
|
|
+ }
|
|
|
|
+ :deep(.v-field__input) {
|
|
|
|
+ padding: 0;
|
|
|
|
+ height: 100%;
|
|
|
|
+ padding-left: 20px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.hover {
|
|
|
|
+ color: var(--v-primary-base);
|
|
|
|
+ background-color: #f8f8f8;
|
|
|
|
+}
|
|
|
|
+.list {
|
|
|
|
+ height: 242px;
|
|
|
|
+ &:hover {
|
|
|
|
+ .list-right {
|
|
|
|
+ display: block;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ &-left {
|
|
|
|
+ background: #FFF;
|
|
|
|
+ height: 100%;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+ }
|
|
|
|
+ &-right {
|
|
|
|
+ background: #FFF;
|
|
|
|
+ display: none;
|
|
|
|
+ width: 525px;
|
|
|
|
+ height: 100%;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+::-webkit-scrollbar {
|
|
|
|
+ width: 4px;
|
|
|
|
+ height: 10px;
|
|
|
|
+}
|
|
|
|
+::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
|
|
|
|
+ // 滚动条-颜色
|
|
|
|
+ background: #c3c3c379;
|
|
|
|
+}
|
|
|
|
+::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
|
|
|
|
+ // 滚动条-底色
|
|
|
|
+ background: #e5e5e58f;
|
|
|
|
+}
|
|
|
|
+</style>
|