layout—模块静态模版搭建
一般情况下我们会有nav区域,header区域,二级路由出口区域以及footer区域,如图
我们在开发的时候先把大模块搭建起来,再一步一步填充小模块
在layout下建文件,目录如下
在index.vue中把上面文件引入进来
<script setup>
import LayoutNav from './components/LayoutNav.vue'
import LayoutHeader from './components/LayoutHeader.vue'
import LayoutFooter from './components/LayoutFooter.vue'
</script><template><LayoutNav /><LayoutHeader /><RouterView /><LayoutFooter />
</template>
layout—字体图标引入
阿里的字体图标库支持多种引入方式,项目里采用的是font-class引用的方式
index.html
<link rel="stylesheet" href="//at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">
layout— 一级导航渲染
apis/layout.js
//导入封装好的http请求 可以看上一章发布的内容项目起步
import httpInstance from "@/utils/http"
export function getCategoryAPI () {return httpInstance({url: '/home/category/head'})
}
layout/layoutHeader
<script setup>import { getCategoryAPI } from '@/apis/layout'import { onMounted, ref } from 'vue'const categoryList = ref([])const getCategory = async () => {const res = await getCategoryAPI()categoryList.value = res.result}onMounted(() => getCategory())</script><template><header class='app-header'><div class="container"><h1 class="logo"><RouterLink to="/">小兔鲜</RouterLink></h1><ul class="app-header-nav"><li class="home" v-for="item in categoryList" :key="item.id"><RouterLink to="/">{{ item.name }}</RouterLink></li></ul><div class="search"><i class="iconfont icon-search"></i><input type="text" placeholder="搜一搜"></div><!-- 头部购物车 --></div></header>
</template>
layout—吸顶导航交互实现
需求:浏览器在上下滚动的过程中,如果距离顶部的滚动距离大于78px,吸顶导航显示,小于78px隐藏
安装vueuse插件
npm i @vueuse/core
//用里面的useScorll来解决滚动问题
layout/components/layoutFixed.vue
<script setup>
import LayoutHeaderUl from './LayoutHeaderUl.vue'
// vueUse
import { useScroll } from '@vueuse/core'
const { y } = useScroll(window)
</script>
<template><div class="app-header-sticky" :class="{ show: y > 78 }"><div class="container"><RouterLink class="logo" to="/" /><!-- 导航区域 --><ul class="app-header-nav "><li class="home"><RouterLink to="/">首页</RouterLink></li><li><RouterLink to="/">居家</RouterLink></li><li><RouterLink to="/">美食</RouterLink></li><li><RouterLink to="/">服饰</RouterLink></li><li><RouterLink to="/">母婴</RouterLink></li><li><RouterLink to="/">个护</RouterLink></li><li><RouterLink to="/">严选</RouterLink></li><li><RouterLink to="/">数码</RouterLink></li><li><RouterLink to="/">运动</RouterLink></li><li><RouterLink to="/">杂项</RouterLink></li></ul><div class="right"><RouterLink to="/">品牌</RouterLink><RouterLink to="/">专题</RouterLink></div></div></div>
</template><style scoped lang='scss'>
.app-header-sticky {width: 100%;height: 80px;position: fixed;left: 0;top: 0;z-index: 999;background-color: #fff;border-bottom: 1px solid #e4e4e4;// 此处为关键样式!!!// 状态一:往上平移自身高度 + 完全透明transform: translateY(-100%);opacity: 0;// 状态二:移除平移 + 完全不透明&.show {transition: all 0.3s linear;transform: none;opacity: 1;}.container {display: flex;align-items: center;}.logo {width: 200px;height: 80px;background: url("@/assets/images/logo.png") no-repeat right 2px;background-size: 160px auto;}.right {width: 220px;display: flex;text-align: center;padding-left: 40px;border-left: 2px solid $xtxColor;a {width: 38px;margin-right: 40px;font-size: 16px;line-height: 1;&:hover {color: $xtxColor;}}}
}.app-header-nav {width: 820px;display: flex;padding-left: 40px;position: relative;z-index: 998;li {margin-right: 40px;width: 38px;text-align: center;a {font-size: 16px;line-height: 32px;height: 32px;display: inline-block;&:hover {color: $xtxColor;border-bottom: 1px solid $xtxColor;}}.active {color: $xtxColor;border-bottom: 1px solid $xtxColor;}}
}
</style>
layout/index.vue
//导入
import LayoutFixed from './components/LayoutFixed.vue'
layout— Pinia优化重复请求
项目中有两种导航,一种普通导航一种吸顶导航
stores/category.js
import { ref } from 'vue'
import { defineStore } from 'pinia'
import { getCategoryAPI } from '@/apis/layout'
export const useCategoryStore = defineStore('category', () => {// 导航列表的数据管理// state 导航列表数据const categoryList = ref([])// action 获取导航数据的方法const getCategory = async () => {const res = await getCategoryAPI()categoryList.value = res.result}return {categoryList,getCategory}
})
layout/index.vue
// 触发获取导航列表的actionimport { useCategoryStore } from '@/stores/categoryStore'
import { onMounted } from 'vue'const categoryStore = useCategoryStore()onMounted(() => categoryStore.getCategory())
layout/components/layoutNav
// 触发获取导航列表的action
<script setup>
import { useCategoryStore } from '@/stores/categoryStore'
const categoryStore = useCategoryStore()
</script><template><ul class="app-header-nav"><li class="home"><RouterLink to="/">首页</RouterLink></li><li class="home" v-for="item in categoryStore.categoryList" :key="item.id"><RouterLink active-class="active" :to="`/category/${item.id}`">{{ item.name }}</RouterLink></li></ul>
</template><style lang="scss">
.app-header-nav {width: 820px;display: flex;padding-left: 40px;position: relative;z-index: 998;li {margin-right: 40px;width: 38px;text-align: center;a {font-size: 16px;line-height: 32px;height: 32px;display: inline-block;&:hover {color: $xtxColor;border-bottom: 1px solid $xtxColor;}}.active {color: $xtxColor;border-bottom: 1px solid $xtxColor;}}
}
</style>