vue3 + ts 如何实现调用子组件的方法时自动补全

我想在父组件中直接调用子组件的方法,子组件通过ref获取,但是目前调用子组件的方法时不能自动补全,并且子组件方法的的参数类型限制也没有了,求问有什么办法能实现自动补全吗?并使子组件的ts类型限制生效

父组件代码

import { defineComponent, ref, watch, onMounted } from 'vue'
import Styles from './index.module.scss'
import { storeToRefs } from 'pinia'
import { useSearchState } from '../../../store/Search'
import Dropdown from '../../common/Dropdown'
import { requestHotSearch } from '../../../api/Search'
import { HotSearchItem } from '../../../types/Search'
import HotSearch from './HotSearch'
import SearchHistory from './SearchHistory'

export default defineComponent({
  name: 'Search',
  setup() {
    const dropdownShow = ref(true)
    const searchRef = ref<HTMLElement>()
    // 用户输入的搜索关键词
    const userKeyword = ref('')
    const searchState = useSearchState()
    const { defaultSearch } = storeToRefs(searchState)
    const hotSearchList = ref<HotSearchItem[]>([])
    const searchHistoryRef = ref()

    // 搜索框回车事件
    function onInputEnter(e: KeyboardEvent) {
      if (e.code !== 'Enter') {
        return
      }

      if (userKeyword.value) {
        // 用户关键词发起搜索
      } else if (defaultSearch.value.realkeyword) {
        // 默认关键词发起搜索
        userKeyword.value = defaultSearch.value.realkeyword
        console.log(defaultSearch.value.realkeyword)
      }

      searchHistoryRef.value.setHistory(userKeyword.value)
    }

    async function inputFocus() {
      try {
        // todo 怎么自动补全子组件的方法
        searchHistoryRef.value.getHistory()

        hotSearchList.value = await requestHotSearch()
        dropdownShow.value = true
      } catch(e) {
        //
      }
    }

    onMounted(() => {
      searchState.getDefaultSearch()
      
    })

    return {
      onInputEnter,
      inputFocus,
      defaultSearch,
      userKeyword,
      dropdownShow,
      searchRef,
      hotSearchList,
      searchHistoryRef
      // searchHistory
    }
  },
  render() {
    return (
      <div class={ Styles.container }>
        {/* 搜索框 - begin */}
        <div class={ Styles.searchContainer }>
          <span class={['iconfont', 'icon-sousuo', Styles.icon]}></span>
          <input 
            placeholder={ this.defaultSearch.showKeyword }
            v-model={ this.userKeyword }
            onKeydown={ this.onInputEnter }
            onFocus={ this.inputFocus }
            ref="searchRef"
            />
            {/* 搜索框的下拉框 - begin */}
            <Dropdown 
              v-model:show={ this.dropdownShow } 
              trigger={ this.searchRef }
              destroy={ false }
              class={ Styles.searchDropdown }
              >
              <SearchHistory ref="searchHistoryRef" />
              <HotSearch hotSearchList={ this.hotSearchList } />
            </Dropdown>
            {/* 搜索框的下拉框 - end */}
        </div>
        {/* 搜索框 - end */}

        {/* 听歌识曲 */}
        <span class={['iconfont', 'icon-tinggeshiqu', Styles.tinggeshiqu]}></span>
      </div>
    )
  }
})

子组件代码

import { defineComponent, ref } from 'vue'
import Judge from '../../../utils/judge'
import LocalStorage from '../../../utils/Storage/LocalStorage'
import Styles from './SearchHistory.module.scss'

// 搜索历史缓存,Search History Storage
const SHStorage = new LocalStorage<string[]>('SearchHistory')

export default defineComponent({
  name: 'SearchHistory',
  setup() {
    const searchHistory = ref<string[]>([])
    
    function getHistory() {
      const storage = SHStorage.get()
      if (Judge.isArray(storage)) {
        searchHistory.value = storage
      }
    }

    function setHistory(keyword: string) {
      searchHistory.value.unshift(keyword)
      // 最多存 20 个历史记录,所以将20个往后的删除 
      searchHistory.value.splice(19)
      SHStorage.set(searchHistory.value)
    }

    return {
      getHistory,
      setHistory,
      searchHistory
    }
  },
  render() {
    const getSearchHistoryElements = () => {
      return this.searchHistory.map((keyword) => {
        return (
          <span class="border rounded-full inline-block px-2 py-1">{ keyword }</span>
        )
      })
    }

    return (
      <div class={ Styles.searchHistory }>
        <div class={ Styles.titleBar }>
          <h3>搜索历史</h3>
          <span class={['iconfont', 'icon-shanchu', Styles.deleteIcon]} title="清空全部"></span>
          <span class={ Styles.lookAll }>查看全部</span>
        </div>
        <div>
          { getSearchHistoryElements() }
        </div>
      </div>
    )
  }
})
阅读 3k
1 个回答

我想可能是因为泛型,你可以试试这样。至少在我这里写能够正常给到提示

const searchHistoryRef = ref<InstanceType<typeof searchHistory>>()
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题