需求分析
- 点击首页搜索框,出现搜索页
- 点击搜索页,隐藏搜索页,展示首页
- 新建搜索页组件
- 实现效果
hooks介绍
理解
hooks 就是将去改变一个参数值时,页面也会更新对应的值的想法、抽象,用代码实现的地方
如何实现一个hooks
- 在src(source)目录下创建一个use文件夹用来存放hooks文件
- 在hooks文件中创建一个hooks
- 写一个函数并用export来导出给对应的组件使用。
- 该函数是用来接收和返回相关hooks的属性值或者函数、实例的
- hooks 函数需要返回一个对象,对象中可以包含一些响应式的数据和一些方法。
事件传递实现跨组件通信
理解
事件传递实现跨组件通信, 流程是先创建一个hooks 用来进行参数传递,在 父组件HomeView中 针对子组件 searchView 和 子组件theTop中的 子组件 opSearch 进行跨组件通信
在组件中使用hooks实现 事件传递实现跨组件通信
<script setup lang="ts"> // 引入hooks 和 组件 import { useToggle } from '@/use/useToggle'; import TheTop from './components/TheTop.vue' import SearchView from '@/views/search/SearchView.vue' const recomments = [ { value: 1, label: '牛腩' }, { value: 2, label: '红烧肉' }, { value: 3, label: '宫保鸡丁' } ] //获取hooks 中返回的属性值或者函数、实例,用来传递变更的值 // 实现事件传递实现跨组件通信, 流程是先创建一个hooks 用来进行参数传递,在 父组件HomeView中 针对子组件 searchView 和 子组件theTop中的 子组件 opSearch 进行跨组件通信 const [isSearchViewShown, toggleSearchView] = useToggle(false) </script> <template> <div class="home-page"> // 在组件 searchView 中定义cancel事件来获取 hooks 传递的值 <SearchView v-if="isSearchViewShown" @cancel="toggleSearchView"></SearchView> // 在组件 TheTop 中定义searchClick事件来获取 hooks 传递的值 <TheTop :recomments="recomments" @searchClick="toggleSearchView"/> </div> </template> <style> .test { font-size: 39px; } </style>
<script setup lang="ts"> // 声明事件接口,接口中属性值是一个函数,函数名是cancel,返回值是一个函数void interface IEmits { (e: 'cancel'): void } // 定义一个事件变量,用defineEmits方法实现,方法中引入声明的事件接口 const emits = defineEmits<IEmits>() </script> <template> // 模板代码中引入定义的事件,用来在父组件中使用对应的事件 调用事件变量,传入事件名cancel <div class="search-view" @click="emits('cancel')">搜索页</div> </template> <style lang="scss"> .search-view { position: absolute; top: 0; bottom: 0; right: 0; left: 0; background-color: white; z-index: 999; } </style>
<script setup lang="ts"> import type { ISearchRecomment } from '@/types' import OpSearch from '@/components/OpSearch.vue' import { ref } from 'vue' interface IProps { recomments: ISearchRecomment[] } 声明事件接口,接口中属性值是一个函数,函数名是searchClick,返回值是一个函数void interface IEmits { (e: 'searchClick'): void } defineProps<IProps>() 定义一个事件变量,用defineEmits方法实现,方法中引入声明的事件接口 const emits = defineEmits<IEmits>() </script> <template> <div class="home-top"> <div class="top"> <img class="location-icon" src="@/assets/imgs/index_page/location.png" /> <div class="location">幸福小区(东南门)</div> <img class="shopcart-icon" src="@/assets/imgs/index_page/shopcart.png" /> <img class="comments-icon" src="@/assets/imgs/index_page/comments.png" /> </div> <!-- <VanSearch shape="round" background="linear-gradient(to right, rgb(53,200,250), rgb(31,175,243))" placeholder="世界茶饮 35减2" > <template #right-icon> <div>搜索</div> </template> </VanSearch> --> <OpSearch shape="round" background="linear-gradient(to right, rgb(53,200,250), rgb(31,175,243))" placeholder="世界茶饮 35减2" <!-- 调用事件变量,传入事件名searchClick, 模板代码中引入定义的事件,用来在父组件中使用对应的事件 --> @inputClick="emits('searchClick')" > <template #right-icon> <div @click="emits('searchClick')">搜索</div> </template> </OpSearch> <div class="search-recomment"> <div v-for="v in recomments" :key="v.value" class="tag">{{ v.label }}</div> </div> </div> </template>