使用Nuxt3开发网址导航(下,完结)

上篇文章写完了后端接口的开发,本篇就开始写前端的开发了。

效果:www.zngg.net/nav 开源地址:github.com/ZN-GG/ZNGG-...

上篇文章传送门:juejin.cn/post/726030...

整理上回思路:

  1. 所有导航信息使用一个json

这就说明一个问题:所有分类相关的切换均由前端完成,一次请求后不再与后端交互。

页面制作

抛开逻辑不谈,静态的html展示肯定是要先做到位的,现在我直接拿成品图来展示:

1134031880924954624.png

根据这个图片来写前端,实际上并不难。看下这个页面结构:

  1. 顶部Toolbar
  2. 一个标题
  3. 分类条
  4. 网址条目

顶部Toolbar

1134102423489478656.png

其中顶部Toolbar和标题较为简单,我目前已经可以在已有的框架中开发了,我封装好了顶部Toolbar,并且外层默认layout已经带有Toolbar了,所以这步就省略了。 这是默认layout:

html 复制代码
<template>
    <div>
        <Toolbar />
        <NuxtLoadingIndicator />
        <NuxtPage class="mt-20" />
    </div>
</template>

其中已经有Toolbar了。

一个标题

这个使用tailwindcss的container和样式mx-auto,即可把文字放在中间容器的左侧,随后略微调整一下字体即可:

html 复制代码
<section class="bg-gray-100">
    <div class="container px-4 mx-auto">
        <div class="md:flex md:-mx-4 md:items-center py-8">
            <div class="md:w-1/2 px-4">
                <p class="text-2xl text-black">优质网址导航</p>
            </div>
        </div>
    </div>
</section>

轻松搞定!

分类条

页面制作

分类条的设计我使用flex布局,方便垂直居中对齐。第一步肯定还是需要创建一个container样式的div,这样可以把内容聚集到中间容器中来;第二步就是在里面写一个父布局(flex),并设置overflow-auto,方便右侧超出后可以出现滚动条。第三步就是在这个flex布局里填充分类按钮,并稍微来点样式: tailwind.css:

css 复制代码
  .btn-2 {
    @apply bg-gray-100 custom-font-12 leading-5 py-1 px-4 rounded-md whitespace-nowrap cursor-pointer hover:bg-blue-600 hover:text-white mx-1;
  }

页面:

html 复制代码
<div class="bg-white">
    <div class="container mx-auto px-4">
        <div class="flex py-3 space-x-4 flex-none overflow-auto">
            <div class="bg-blue-600 text-white btn-2">分类</div>
            <div class="btn-2">分类</div>
            <div class="btn-2">分类</div>
            <div class="btn-2">分类</div>
            <div class="btn-2">分类</div>
        </div>
    </div>
</div>

样式写好了就要开始写逻辑了,要用网络数据代替这些写死的数据。

逻辑

分类逻辑很简单:获取网络数据data ,使用v-for遍历这个data 即可。稍微需要思考一下的就是这个已选择的分类,我决定默认选择第一个分类为已选择分类,这里需要添加一个变量categoryId(不够严谨),这个变量默认为1,点击分类时修改categoryId的值即可。

首先使用Nuxt3获取网络数据:

typescript 复制代码
import { api } from "~/api/api";
let categoryId = ref(0)

const { data: navLinks, pending, refresh, error } = await useAsyncData("web_NavLinks", () => api.web.getNavInfo());
if (navLinks.value!.success) {
    console.log(navLinks.value);

}

async function selectCategoryId(id: number) {
    categoryId.value = id
}

这里我封装了一下网络请求,具体封装代码可以看:github.com/ZN-GG/ZNGG-...

上述代码中定义了一个navLinks常量存储json数据,并且将数据打印出来。这里定义了一个变量categoryId和一个函数selectCategoryId,下面会用到

随后将分类相关的html代码修改成动态的值:

html 复制代码
<div class="bg-white">
    <div class="container mx-auto px-4">
        <div 
            class="flex py-3 space-x-4 flex-none overflow-auto">
            <div v-for="(item, index) in navLinks?.data" :key="index" @click="selectCategoryId(index)"
                class="btn-2" :class="categoryId == index ? 'bg-blue-600 text-white' : ''">
                {{ item.name }}
            </div>
        </div>
    </div>
</div>

上面的代码中使用v-for循环遍历我们的内容navLinks,并且将index设置为索引,当categoryIdindex相等时,给按钮增加一个选中的样式(背景变蓝色,字变成白色),并且使用@click让分类被点击时调用selectCategoryId函数修改categoryId的值。

写到这里,分类相关功能就已经全部完成了,接下来只需要根据categoryId来展示网址即可。

网址条目

根据已选择分类展示网址,开始之前思考一个问题,就是如何才能根据选择的分类展示这个分类下的网址信息呢?我的答案是"categId",这里的categoryId是真正的categoryId,就是那个雪花算法生成的id,并不是上面说到的index索引,那么如果这样做的话,就会需要两层遍历(因为json只能遍历),首先在完成遍历出正确的categoryId==categoryId,之后在内部遍历itemList,这样会不会麻烦一点呢?或者有没有更简单的办法呢?这就是我想到的第二个办法:index。

json想要直接拿到某一条数据,那么只有一个办法,就是知道这个数据的位置(position),因此我上面代码里的categoryId其实代表的是position,分类的位置。这样我就可以直接通过json[xxx].itemList的方式拿到网址数据,具体请看代码:

ini 复制代码
<div class="container px-4 mx-auto">
    <div class="py-5">
        <ul class="w-full flex flex-wrap">
            <li v-for="item in navLinks?.data[categoryId].itemList" class="w-full md:w-4/12">
                <div class="transition duration-300 ease-in-out p-2">
                    <a :href="item.url" target="_blank">
                        <div class="bg-white rounded px-3 py-4 nav-item-anim">
                            <div class="flex">
                                <div class="w-2/12 flex items-center">
                                    <img class="w-8 h-8 mx-auto" :src="item.img" alt="" srcset="">
                                </div>
                                <div class="px-2">

                                    <div class="flex items-start">
                                        <div class="grow">
                                            <p class="text-gray-800 mb-1">{{ item.title }}</p>
                                            <p class="text-gray-400 text-xs">
                                                {{ item.description }}
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </a>
                </div>
            </li>
        </ul>
    </div>
</div>

归纳总结

这篇文章的categoryId意思表达的不算好,如果不理解的话只能多看看代码了。

完整代码地址:github.com/ZN-GG/ZNGG-...

到此,导航就已经制作完毕了,我将整个制作过程完完整整的记录了下来,也许几年以后再来看这些代码,就会觉得是一堆垃圾,但好在现在我觉得这代码可优化的地方并不算多。整个导航我大概花了一个下午的时间,这里很感谢我的女朋友可以在难得周末抽出一个下午的时间让我好好享受这写代码的过程,看一看时间,再不午休下午可就要犯困了~

相关推荐
长天一色4 分钟前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_23422 分钟前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河24 分钟前
CSS总结
前端·css
BigYe程普1 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H1 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍1 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai1 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端
流烟默1 小时前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch
2401_857297912 小时前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
茶卡盐佑星_2 小时前
meta标签作用/SEO优化
前端·javascript·html