Vue3 小兔鲜4:Layout-静态模版结构搭建

news/2024/11/22 11:58:40/

Vue3 小兔鲜4:Layout-静态模版结构搭建

Date: May 31, 2023


目标效果:

分成Nav、Heade、二级路由出口、Footer区域

Untitled




组件结构快速搭建

Nav

<script setup></script><template><nav class="app-topnav"><div class="container"><ul><template v-if="true"><li><a href="javascript:;"><i class="iconfont icon-user"></i>周杰伦</a></li><li><el-popconfirm title="确认退出吗?" confirm-button-text="确认" cancel-button-text="取消"><template #reference><a href="javascript:;">退出登录</a></template></el-popconfirm></li><li><a href="javascript:;">我的订单</a></li><li><a href="javascript:;">会员中心</a></li></template><template v-else><li><a href="javascript:;">请先登录</a></li><li><a href="javascript:;">帮助中心</a></li><li><a href="javascript:;">关于我们</a></li></template></ul></div></nav>
</template><style scoped lang="scss">
.app-topnav {background: #333;ul {display: flex;height: 53px;justify-content: flex-end;align-items: center;li {a {padding: 0 15px;color: #cdcdcd;line-height: 1;display: inline-block;i {font-size: 14px;margin-right: 2px;}&:hover {color: $xtxColor;}}~li {a {border-left: 2px solid #666;}}}}
}
</style>

Header

<script setup></script><template><header class='app-header'><div class="container"><h1 class="logo"><RouterLink to="/">小兔鲜</RouterLink></h1><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></ul><div class="search"><i class="iconfont icon-search"></i><input type="text" placeholder="搜一搜"></div><!-- 头部购物车 --></div></header>
</template><style scoped lang='scss'>
.app-header {background: #fff;.container {display: flex;align-items: center;}.logo {width: 200px;a {display: block;height: 132px;width: 100%;text-indent: -9999px;background: url('@/assets/images/logo.png') no-repeat center 18px / contain;}}.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;}}}.search {width: 170px;height: 32px;position: relative;border-bottom: 1px solid #e7e7e7;line-height: 32px;.icon-search {font-size: 18px;margin-left: 5px;}input {width: 140px;padding-left: 5px;color: #666;}}.cart {width: 50px;.curr {height: 32px;line-height: 32px;text-align: center;position: relative;display: block;.icon-cart {font-size: 22px;}em {font-style: normal;position: absolute;right: 0;top: 0;padding: 1px 6px;line-height: 1;background: $helpColor;color: #fff;font-size: 12px;border-radius: 10px;font-family: Arial;}}}
}
</style>

Footer

<template><footer class="app_footer"><!-- 联系我们 --><div class="contact"><div class="container"><dl><dt>客户服务</dt><dd><i class="iconfont icon-kefu"></i> 在线客服</dd><dd><i class="iconfont icon-question"></i> 问题反馈</dd></dl><dl><dt>关注我们</dt><dd><i class="iconfont icon-weixin"></i> 公众号</dd><dd><i class="iconfont icon-weibo"></i> 微博</dd></dl><dl><dt>下载APP</dt><dd class="qrcode"><img src="@/assets/images/qrcode.jpg" /></dd><dd class="download"><span>扫描二维码</span><span>立马下载APP</span><a href="javascript:;">下载页面</a></dd></dl><dl><dt>服务热线</dt><dd class="hotline">400-0000-000 <small>周一至周日 8:00-18:00</small></dd></dl></div></div><!-- 其它 --><div class="extra"><div class="container"><div class="slogan"><a href="javascript:;"><i class="iconfont icon-footer01"></i><span>价格亲民</span></a><a href="javascript:;"><i class="iconfont icon-footer02"></i><span>物流快捷</span></a><a href="javascript:;"><i class="iconfont icon-footer03"></i><span>品质新鲜</span></a></div><!-- 版权信息 --><div class="copyright"><p><a href="javascript:;">关于我们</a><a href="javascript:;">帮助中心</a><a href="javascript:;">售后服务</a><a href="javascript:;">配送与验收</a><a href="javascript:;">商务合作</a><a href="javascript:;">搜索推荐</a><a href="javascript:;">友情链接</a></p><p>CopyRight © 小兔鲜儿</p></div></div></div></footer>
</template><style scoped lang='scss'>
.app_footer {overflow: hidden;background-color: #f5f5f5;padding-top: 20px;.contact {background: #fff;.container {padding: 60px 0 40px 25px;display: flex;}dl {height: 190px;text-align: center;padding: 0 72px;border-right: 1px solid #f2f2f2;color: #999;&:first-child {padding-left: 0;}&:last-child {border-right: none;padding-right: 0;}}dt {line-height: 1;font-size: 18px;}dd {margin: 36px 12px 0 0;float: left;width: 92px;height: 92px;padding-top: 10px;border: 1px solid #ededed;.iconfont {font-size: 36px;display: block;color: #666;}&:hover {.iconfont {color: $xtxColor;}}&:last-child {margin-right: 0;}}.qrcode {width: 92px;height: 92px;padding: 7px;border: 1px solid #ededed;}.download {padding-top: 5px;font-size: 14px;width: auto;height: auto;border: none;span {display: block;}a {display: block;line-height: 1;padding: 10px 25px;margin-top: 5px;color: #fff;border-radius: 2px;background-color: $xtxColor;}}.hotline {padding-top: 20px;font-size: 22px;color: #666;width: auto;height: auto;border: none;small {display: block;font-size: 15px;color: #999;}}}.extra {background-color: #333;}.slogan {height: 178px;line-height: 58px;padding: 60px 100px;border-bottom: 1px solid #434343;display: flex;justify-content: space-between;a {height: 58px;line-height: 58px;color: #fff;font-size: 28px;i {font-size: 50px;vertical-align: middle;margin-right: 10px;font-weight: 100;}span {vertical-align: middle;text-shadow: 0 0 1px #333;}}}.copyright {height: 170px;padding-top: 40px;text-align: center;color: #999;font-size: 15px;p {line-height: 1;margin-bottom: 20px;}a {color: #999;line-height: 1;padding: 0 10px;border-right: 1px solid #999;&:last-child {border-right: none;}}}
}
</style>

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>



字体图标渲染

效果:

Untitled

具体操作:

  1. 在index.html中导入图标库

    字体图标采用的是阿里的字体图标库,样式文件已经准备好,在 index.html文件中引入即可

  <link rel="stylesheet" href="//at.alicdn.com/t/font_2143783_iq6z4ey5vu.css"> 
  1. 在标签中具体使用即可

Untitled




一级导航渲染

使用后端接口渲染一级路由导航:

image-20230601170144844

实现步骤

  1. 封装接口函数
  2. 调用接口函数
  3. v-for渲染模版

代码落地

import httpInstance from '@/utils/http'
export function getCategoryAPI () {  return httpInstance({   url: '/home/category/head'  })
}
<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>



吸顶导航交互实现

吸顶交互要求

页面在上下滚动的过程中,如果距离顶部的滚动距离大手78pX,吸顶导航显示,小于78px隐藏

实现思路

准备吸顶导航组件⇒获取滚动距离⇒以滚动距离做判断条件控制组件盒子展示隐藏

1. 准备组件静态结构

实现步骤:

  1. 搞定顶吸组件:LayoutFixed.vue
<script setup>// vueUseimport { useScroll } from '@vueuse/core'const { y } = useScroll(window) // 这里的y就是滚动时的实时距离
</script>

效果:

Untitled



2. 渲染基础数据

原始代码:

  • Code

    <script setup></script><template><div class="app-header-sticky"><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>
    

这里我们修改一下,通过v-for进行循环:

LayoutFixed.vue

<li class="home" v-for="item in categoryList" :key="item.id"><RouterLink to="/">{{ item.name }}</RouterLink>
</li>


3. 实现吸顶交互

核心逻辑:根据滚动距离判断当前show类名是否显示,大于78显示,小于78,不显示

<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>
</template>



Pinia优化重复请求

问题:

两个导航中的列表是完全一致的,但是要发送两次网络请求,存在浪费。

Untitled

Untitled

优化方式:

通过Pinia集中管理数据,再把数据给组件使用。值的注意的是,我们会在两个子组件的公共父组件中把action触发起来,这样能够保证这个action只会触发一次。

Untitled

代码:

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  }
})

http://www.ppmy.cn/news/146134.html

相关文章

企业开发前端框架2023最新前沿技术vue3+vite+vuetify+js+Tailwind Css

文章目录 前言创建项目1、打开vuetify的官网下载项目2、下载依赖3、添加tailwindcss依赖 结束 前言 最近需要开发新的项目&#xff0c;正好学习了Tailwindcss&#xff0c;所以就想着集成到新项目里来&#xff0c;一来可以精进项目经验&#xff0c;也可以感受一下tailwindcss的…

RocksDB笔记 -- 整体架构

RocksDB是由Facebook开发的存储引擎, 它最初的目标是用于快速存储, 特别是Flash存储. 一个基于C开发keys-values存储引擎库. 整体架构 RocksDB由这三个基本结构组成: memtable, sstfile 和 logfile. 其中: memtable是一个内存数据结构, 新的写入会插入到memtable中, 同时可选…

bing必应壁纸下载器

自己写的一个简单的必应壁纸获取工具&#xff0c;可以自动获取必应壁纸并设置为桌面。 界面如图 下载地址 https://wjk.lanzous.com/ibf8xyb

大写数字时钟电脑壁纸下载

壁纸名称&#xff1a;冷高轮时间 壁纸样式&#xff1a;梵高数字动态时钟&#xff0c;王思聪吃热狗数字动态时钟&#xff0c;手势数字动态时钟&#xff0c;大写数字动态时钟&#xff0c;中文汉字动态时钟&#xff0c;麻将数字动态时钟&#xff0c;扑克数字动态时钟 电脑壁纸下…

HarmonyOS | 鸿蒙系统内置原生壁纸下载

点击上方蓝字 关注后回复 壁纸 获取所有精美壁纸 下载方式 长按二维码关注 逆锋起笔 回复【壁纸】立刻获取高清壁纸

iOS 15 内置原生壁纸下载

iOS 15 2048PX x 2048PX 下载方式 长按二维码关注 逆锋起笔 回复【壁纸】立刻获取高清壁纸

苹果 iPhone 13 内置原生壁纸下载

下载方式 长按二维码关注 逆锋起笔 回复【壁纸】立刻获取高清壁纸 iOS 15 内置原生壁纸下载 macOS 12 内置原生壁纸下载 Windows 10 最新版壁纸下载 17 张程序员壁纸&#xff08;使用频率很高&#xff09; 华为 MatePad 系列&#xff1a;绝版精美壁纸一套 今日福利 赠送如下书籍…

下载王者壁纸

王者英雄都非常绚丽夺目&#xff0c;下面就是爬取壁纸的源码&#xff1a; ​ ​ import requests import os import json from lxml import etree from fake_useragent import UserAgent import logginglogging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelna…