vue3 + naiveui | 自动填充 Auto Complete 组件二次封装

905 阅读1分钟

抛出问题

AutoComplete组件当搜索结果为空时,没有相关的提示,故在此基础上添加一个搜索内容为空的提示。

效果如下:

image.png

image.png

组件封装

image.png

index.vue

<script setup lang="ts">
  import nodatabg from '@/assets/images/no-search-data.png'
  defineOptions({
    name: 'AutoCompleteSearch',
  })
  const props = defineProps<{
    emptyVisible?: boolean
    placeholder?: string
    clearable?: boolean
    emptyDescription?: string
  }>()
</script>

<template>
  <n-el class="flex justify-center items-center relative">
    <n-auto-complete
      ref="searchRef"
      :placeholder="props.placeholder || '请输入关键词'"
      :clearable="props.clearable || true"
      v-bind="$attrs"
    >
       <!-- 注:v-bind="$attrs" “继承“ n-auto-complete 原有组件所有的属性 -->
      <template #prefix>
        <i-carbon:search />
      </template>
       <!-- 根据业务场景所设置的前缀图标,可自行修改 -->
      <template v-for="(slot, slotName) in $slots" #[slotName]>
        <slot :name="slotName" />
      </template>
      <!-- 保留组件自身的插槽 -->
    </n-auto-complete>
    <n-el
      v-if="props.emptyVisible || false"
      class="custom-empty h-30 flex flex-col justify-center items-center w-full bg-white rounded-md absolute top-9.5 left-0 z-99"
    >
      <slot><n-image :src="nodatabg" class="w-12 h-12"></n-image></slot>
      <n-el class="mt-1 text-[#999999] text-[14px]">
        {{ props.emptyDescription || '暂无数据' }}
      </n-el>
      <!-- 其他内容(比如按钮) -->
      <slot name="extra"></slot>
    </n-el>
  </n-el>
</template>

<style lang="less" scoped>
  .custom-empty {
    box-shadow: 0 3px 6px -4px rgb(0 0 0 / 12%), 0 6px 16px 0 rgb(0 0 0 / 8%),
      0 9px 28px 8px rgb(0 0 0 / 5%);
  }
</style>

index.ts

export { default } from './index.vue'

组件引用

<template>
.....
<AutoCompleteSearch
      v-model:value="searchText"
      :options="searchOptions"
      :empty-visible="noSearchFlag"
      @select="handleSelect"
      @blur="handleBlur"
 />
......
</template>

<script setup lang="ts">
import { watch } from 'vue'

const searchText =  ref('')
const noSearchFlag = ref(false)

const handleSelect = () => {
  //下拉选中项的逻辑
}

const handleBlur = () => {
 if (searchText.value.length == 0 || !searchText.value) {
     searchOptions.value = []
   }
}

const updateTreeSearchList = (value:string) => {
  //根据输入值去调用相关接口,获取下拉数据
  ......
}

// 监听输入框值的变化
  watch(
    () => searchText.value,
    (value: string) => {
      if (value.length !== 0) {
        //先清空下拉的数据,避免空数据样式闪烁的问题
        searchOptions.value = []
        updateTreeSearchList(value)
      } else {
        noSearchFlag.value = false
      }
    }
  )
 
</script> 

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情