前端小练-仿掘金导航栏

news2024/9/22 23:25:24

文章目录

  • 前言
  • 项目结构
    • 导航实现
    • 创作中心
    • 移动小球
    • 消息提示
  • 完整代码

前言

闲的,你信嘛,还得开发一个基本的门户社区网站,来给到Hlang,不然我怕说工作量不够。那么这个的话,其实也很好办,主要是这个门户网站的UI写起来麻烦一点,其他的就直接套用组件,和以前的老代码就行了。为了快速开发,我直接用royi-cloud去做了。反正自己搭建一个也是这样,还要自己重新搭建环境,不如直接加速。像这种类型的网站,没有啥技巧,无法是做做防抖,节流,对接点啥支付等等的玩意。一个礼拜就能开发好,前提是前端好写。不过也确实不难,这种东西。其他的就是套用组件,没啥,后端的话,原来是整合人人开源一套的,但是MP,我实在是不喜欢,越写越觉得MP有点呆。懒得改写,不如直接换架构。这也是为啥直接用ruoyi了。

废话不多说,看看效果:
在这里插入图片描述

我甚至为此用New Bing生成了一个Logo。

首先,没错,我的临时毕设方案有两个部分:
1. 基于Python实现的中文编程解释器。因为主打的是教学,锻炼编程思维,因此不考虑任何性能,只考虑开发成本和周期,要是用C++怼,那我觉得我一开始的算法开发平台也不是不能做完。
2. 给这个玩意,做一个技术交流社区,这个社区的名字叫做Hlang,但是它不限于Hlang,其实就是个博客社区套壳。然后里面很多功能会直接套用白洞。但是所有内容会重构,反正现在开发一个这种玩意顶多一个礼拜(包括前端估计两个礼拜顶天了)

项目结构

废话不多说,先来看到我们的项目结构:
在这里插入图片描述
在这里导航栏是一个组件。
在App.vue里面直接调用:

<script setup>
import { RouterLink, RouterView } from 'vue-router'
import Header from './components/Header.vue';
</script>
<template>
  <header>
    <Header></Header>
  </header>
  <div class="main">
    <div class="placeholder"></div> 
    <RouterView />
  </div>
</template>

<style scoped>
  .main{
    width: 100%;
    background-color: rgb(242,243,245);
  }
  .placeholder{
    height: 80px;
    width: 100%;
  }
  header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 42px;
    background-color: #fff; /* 设置背景颜色 */
    padding: 20px; /* 添加内边距 */
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
    z-index: 999; /* 设置堆叠顺序,确保 header 位于其他内容之上 */
  }
</style>

这里注意的是,为了让head固定,我用fixed布局,然后的话为了避免挡住内容,于是在这里我用了一个div把main里面的东西顶下去。
就是这个:

    <div class="placeholder"></div> 

导航实现

那么接下来就是我们的导航了。
首先是这个导航的基本结构:

<template>
    <el-menu
      :default-active="activeIndex"
      class="el-menu-header"
      mode="horizontal"
      @select="handleSelect"
    
    >
      <!-- <span style="width: 50px;"></span> -->
      <el-menu-item index="1">
        <span>
           <img
             style="width: 50px;height: 50px"
             src="../../public/favicon.ico"
           >
        </span>
      </el-menu-item>


      <el-menu-item index="2">
        <template #title>社区</template>
      </el-menu-item>

      <el-menu-item index="3">
        <template #title>说说</template>
      </el-menu-item>

      <div class="h-search">
        <el-autocomplete
            style="height: 50px; width: 350px;margin-top: 12px;"
            v-model="state1"
            :fetch-suggestions="querySearch"
            clearable
            placeholder="探索社区"
            @select="handleSelect"
            />
        <el-button style="margin-top: 12px;margin-left: 5px;" :icon="Search" circle />
      </div>

      <div class="h-show">
        <div class="custom-loader"></div>
      </div>

      <el-sub-menu index="4">
        <template #title>
          <el-button type="primary">创作中心</el-button>
        </template>
        <div class="w-center">
          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/write.png">
            <div class="w-c-it-text">
              写文章
            </div>
          </div>

          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/shuoshuo.png">
            <div class="w-c-it-text">
              写说说
            </div>
          </div>

          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/chaogao.png">
            <div class="w-c-it-text">
              草稿箱
            </div>
          </div>

        </div>
      </el-sub-menu>

      <div class="message-tip">
        <el-badge :value="100" :max="10" class="item">
          <img class="message-img" src="~@/assets/image/notic.png">
        </el-badge>
      </div>

      <div class="avatar hover-rotate">
        <img class="avatar-img" src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg">
      </div>

    </el-menu>
  </template>

整体用到是flex布局:
在这里插入图片描述
然后的话,导航最外层用到还是element-plus的导航,但是里面的css重新改了一下。
首先是间隔,为了避免改动源代码出现问题,我直接在menu里面多了一个属性:


.el-menu-header{
    gap: 20px;
    padding-left: 100px;
}

然后在这里设置:
在这里插入图片描述
也可以实现效果。

创作中心

在这里的话,前面几个按钮都是直接使用的组件,主要是后面这个东西。借鉴了掘金的这个操作:
在这里插入图片描述
这部分代码结构是这样的:

   <el-sub-menu index="4">
        <template #title>
          <el-button type="primary">创作中心</el-button>
        </template>
        <div class="w-center">
          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/write.png">
            <div class="w-c-it-text">
              写文章
            </div>
          </div>

          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/shuoshuo.png">
            <div class="w-c-it-text">
              写说说
            </div>
          </div>

          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/chaogao.png">
            <div class="w-c-it-text">
              草稿箱
            </div>
          </div>

        </div>
      </el-sub-menu>

直接这样写,就可以实现那种自定义的效果。
那么css代码是这样的:

.w-c-it-img{
  margin-top: 10px;
  width: 40%;
  height: 40px;
}

.w-c-it-text{
  margin-top: 10px;
  width: 100%;
  height: 30px;
  font-size: 14px;
  text-align: center;
}
.w-c-item:hover{
  border-radius: 10px;
  -webkit-box-shadow: 5px 5px 50px 0px rgba(105,170,214,1);
  -moz-box-shadow: 5px 5px 50px 0px rgba(105,170,214,1);
  box-shadow: 5px 5px 50px 0px rgba(105,170,214,1);
}
.w-c-item{
  cursor: pointer;
  margin-top: 20px;
  width: 80px;
  height: 80px;
  display: flex;
  flex-direction: column;
  justify-items: center;
  align-items: center;
}
.w-center{
  border-radius: 30px;
  height: 120px;
  display: flex;
  padding-left: 60px;
  gap: 20px;
  width: 350px;
}

移动小球

这玩意其实就是这个:
在这里插入图片描述
这玩意会动。其实就是用来占位置的,实在是没有啥功能了。留个空,反正也是微服务架构,后面上个功能也好办。

  <div class="h-show">
        <div class="custom-loader"></div>
      </div>
.custom-loader {
  margin-top: 12px;
  width: 120px;
  height: 22px;
  border-radius: 40px;
  color: #E4E4ED;
  position: relative;
  overflow: hidden;
}

.custom-loader::before {
  content: "";
  position: absolute;
  margin: 2px;
  width: 14px;
  top: 0;
  bottom: 0;
  left: -20px;
  border-radius: inherit;
  background: #2898dd;
  box-shadow: -10px 0 12px 3px #83daf1;
  clip-path: polygon(0 5%, 100% 0,100% 100%,0 95%,-30px 50%);
  animation: ct4 1s infinite linear;
}

@keyframes ct4 {
  100% {left: calc(100% + 20px)}
}

消息提示

这个消息提示和头像是类似的,就一起说了。其实原来我一直用错了,就是那个消息提示显示的个数,原来做的时候忙个数老是和图标有很大间距。因为原来一直套用的是el-button 这个玩意样式不好改,于是直接在div上面加。

 <div class="message-tip">
        <el-badge :value="100" :max="10" class="item">
          <img class="message-img" src="~@/assets/image/notic.png">
        </el-badge>
</div>


.message-img{
  cursor: pointer;
  width: 25px;
  height: 30px;
}

.message-img:hover{
  border-radius: 10px;
  -webkit-box-shadow: 0px 0px 24px 6px rgba(5,143,235,1);
  -moz-box-shadow: 0px 0px 24px 6px rgba(5,143,235,1);
  box-shadow: 0px 0px 24px 6px rgba(5,143,235,1);
}

.message-tip{
  margin-top: 12px;
  width: 30px;
}

完整代码

okey,接下来是完整代码:

<template>
    <el-menu
      :default-active="activeIndex"
      class="el-menu-header"
      mode="horizontal"
      @select="handleSelect"
    
    >
      <!-- <span style="width: 50px;"></span> -->
      <el-menu-item index="1">
        <span>
           <img
             style="width: 50px;height: 50px"
             src="../../public/favicon.ico"
           >
        </span>
      </el-menu-item>


      <el-menu-item index="2">
        <template #title>社区</template>
      </el-menu-item>

      <el-menu-item index="3">
        <template #title>说说</template>
      </el-menu-item>

      <div class="h-search">
        <el-autocomplete
            style="height: 50px; width: 350px;margin-top: 12px;"
            v-model="state1"
            :fetch-suggestions="querySearch"
            clearable
            placeholder="探索社区"
            @select="handleSelect"
            />
        <el-button style="margin-top: 12px;margin-left: 5px;" :icon="Search" circle />
      </div>

      <div class="h-show">
        <div class="custom-loader"></div>
      </div>

      <el-sub-menu index="4">
        <template #title>
          <el-button type="primary">创作中心</el-button>
        </template>
        <div class="w-center">
          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/write.png">
            <div class="w-c-it-text">
              写文章
            </div>
          </div>

          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/shuoshuo.png">
            <div class="w-c-it-text">
              写说说
            </div>
          </div>

          <div class="w-c-item">
            <img class="w-c-it-img" src="~@/assets/image/chaogao.png">
            <div class="w-c-it-text">
              草稿箱
            </div>
          </div>

        </div>
      </el-sub-menu>

      <div class="message-tip">
        <el-badge :value="100" :max="10" class="item">
          <img class="message-img" src="~@/assets/image/notic.png">
        </el-badge>
      </div>

      <div class="avatar hover-rotate">
        <img class="avatar-img" src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg">
      </div>

    </el-menu>
  </template>


<script lang="ts" setup>
import { ref,onMounted } from 'vue'
import {Search} from '@element-plus/icons-vue'


const activeIndex = ref('1')
const state1 = ref('')

interface RestaurantItem {
  value: string
  link: string
}
const restaurants = ref<RestaurantItem[]>([])

const querySearch = (queryString: string, cb: any) => {
  const results = queryString
    ? restaurants.value.filter(createFilter(queryString))
    : restaurants.value
  // call callback function to return suggestions
  cb(results)
}
const createFilter = (queryString: string) => {
  return (restaurant: RestaurantItem) => {
    return (
      restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
    )
  }
}
const loadAll = () => {
  return [
    { value: 'vue', link: 'https://github.com/vuejs/vue' },
    { value: 'element', link: 'https://github.com/ElemeFE/element' },
    { value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
    { value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
    { value: 'vuex', link: 'https://github.com/vuejs/vuex' },
    { value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
    { value: 'babel', link: 'https://github.com/babel/babel' },
  ]
}



const handleSelect = (item: RestaurantItem) => {
  console.log(item)
}

onMounted(() => {
  restaurants.value = loadAll()
})
</script>


<style scoped>

.avatar{
  cursor: pointer;
  margin-left: 60px;
  width: 40px;
  height: 40px;
  border-radius: 100px;
}

.hover-rotate {
  transition: transform 0.5s ease-in-out;
}

.hover-rotate:hover {
  transform: rotate(360deg);
}

.avatar-img{
  border-radius: 100px;
  margin-top: 10px;
  width: 100%;
  height: 100%;
}
.message-img{
  cursor: pointer;
  width: 25px;
  height: 30px;
}

.message-img:hover{
  border-radius: 10px;
  -webkit-box-shadow: 0px 0px 24px 6px rgba(5,143,235,1);
  -moz-box-shadow: 0px 0px 24px 6px rgba(5,143,235,1);
  box-shadow: 0px 0px 24px 6px rgba(5,143,235,1);
}

.message-tip{
  margin-top: 12px;
  width: 30px;
}
.w-c-it-img{
  margin-top: 10px;
  width: 40%;
  height: 40px;
}

.w-c-it-text{
  margin-top: 10px;
  width: 100%;
  height: 30px;
  font-size: 14px;
  text-align: center;
}
.w-c-item:hover{
  border-radius: 10px;
  -webkit-box-shadow: 5px 5px 50px 0px rgba(105,170,214,1);
  -moz-box-shadow: 5px 5px 50px 0px rgba(105,170,214,1);
  box-shadow: 5px 5px 50px 0px rgba(105,170,214,1);
}
.w-c-item{
  cursor: pointer;
  margin-top: 20px;
  width: 80px;
  height: 80px;
  display: flex;
  flex-direction: column;
  justify-items: center;
  align-items: center;
}
.w-center{
  border-radius: 30px;
  height: 120px;
  display: flex;
  padding-left: 60px;
  gap: 20px;
  width: 350px;
}
.custom-loader {
  margin-top: 12px;
  width: 120px;
  height: 22px;
  border-radius: 40px;
  color: #E4E4ED;
  position: relative;
  overflow: hidden;
}

.custom-loader::before {
  content: "";
  position: absolute;
  margin: 2px;
  width: 14px;
  top: 0;
  bottom: 0;
  left: -20px;
  border-radius: inherit;
  background: #2898dd;
  box-shadow: -10px 0 12px 3px #83daf1;
  clip-path: polygon(0 5%, 100% 0,100% 100%,0 95%,-30px 50%);
  animation: ct4 1s infinite linear;
}

@keyframes ct4 {
  100% {left: calc(100% + 20px)}
}
.h-search{
    display: flex;
    
}
.el-menu-header{
    gap: 20px;
    padding-left: 100px;
}
</style>
  

后面多写写特效啥的,锻炼锻炼美感,可惜的就是,先前写的前端主页用不了了。可恶,没办法风格不合适。

真的有一说一,CSDN的页面设计实在是有点那啥,先前whitehole的页面设计就是照着csdn来的,写道后面发现不行,改成掘金的一些风格,结果有些地方不伦不类,写到后面有点像知乎页面。这次的话,就直接照着掘金借鉴了(狗头)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/814864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统_进程与线程(三)

目录 3. 同步与互斥 3.1 同步与互斥的基本概念 3.1.1 临界资源 3.1.2 同步 3.1.3 互斥 3.2 实现临界区互斥的基本方法 3.2.1 软件实现方法 3.2.1.1 算法一&#xff1a;单标志法 3.2.1.2 算法二&#xff1a;双标志法先检查 3.2.1.3 算法三&#xff1a;双标志法后检查 …

HarmonyOS/OpenHarmony元服务开发-卡片使用自定义绘制能力

ArkTS卡片开放了自定义绘制的能力&#xff0c;在卡片上可以通过Canvas组件创建一块画布&#xff0c;然后通过CanvasRenderingContext2D对象在画布上进行自定义图形的绘制&#xff0c;如下示例代码实现了在画布的中心绘制了一个笑脸。 Entry Component struct Card { private c…

如何把几个视频合并在一起?视频合并方法分享

当我们需要制作一个比较长的视频时&#xff0c;将多个视频进行合并可以使得整个过程更加高效。此外&#xff0c;合并视频还可以避免出现“剪辑断层”的情况&#xff0c;使得视频内容更加连贯&#xff0c;更加容易被观众理解和接受。再有&#xff0c;合并视频还可以减少视频文件…

第三方电容笔支持随手写吗?性价比高的触控笔推荐

在日常生活中&#xff0c;电容笔的用途非常广泛&#xff0c;无论是配上笔记本&#xff0c;还是配上ipad&#xff0c;又或者是配上手机&#xff0c;都是非常好用的办公利器。首先要明确自己的需要&#xff0c;然后才能选择适合自己的产品。苹果Pencil因为具有特殊的重力压感&…

数据结构07:查找[C++][顺序、分块、折半查找]

图源&#xff1a;文心一言 考研笔记整理~&#x1f95d;&#x1f95d; 在数据结构和算法中&#xff0c;查找是一种常见的操作&#xff0c;它的目的是在一个数据集合中找到一个满足条件的元素。本文将介绍三种常用的查找方法&#xff0c;分别是顺序查找、折半查找和分块查找~&a…

Unity实现在3D模型标记

Canvas 模式是UI与3D混合模式&#xff08;Render modelScreen space-Camera) 实现在3D模型标记&#xff0c;旋转跟随是UI不在3D物体下 代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public clas…

记一次sql注入分析与绕过【一】

下面是来自今天的项目&#xff0c;简单记录一下 手工注入 加单引号sql报错 sql语句如下&#xff0c;可见参数id原本未被引号包裹 SELECT DISTINCT u.* FROM t_user u WHERE u.name like %1% and u.account like %1% and u.state ? order by id desc limit 0,20 多方尝试…

warnings.filterwarnings(“ignore“) 是干嘛的

在python中运行代码经常会遇到的情况是——代码可以正常运行但是会提示警告 那么如何来控制警告输出呢&#xff1f;其实很简单&#xff0c;python通过调用warnings模块中定义的warn()函数来发出警告。我们可以通过警告过滤器进行控制是否发出警告消息 import warnings warnin…

数字工厂管理系统的实施步骤是什么

数字工厂管理系统是一种基于数字化技术和智能化设备的工厂管理系统&#xff0c;它可以实现工厂的全面、实时、动态管理&#xff0c;提高生产效率、降低成本、保证产品质量。实施数字工厂管理系统需要一系列的实施步骤&#xff0c;下面就数字工厂管理系统的实施步骤进行详细说明…

postgresql selected, no connection解决办法|armitage连接不上

postgresql selected, no connection 数据库没有连接&#xff0c;手动连接数据库即可。 手动连接数据库 msf > db_connect msf:admin127.0.0.1/msf 还是不行。 说明&#xff0c;数据库都连不上&#xff0c;先解决这个问题。 正文 看过很多&#xff0c;也试了很多&#xf…

05 http连接处理(中)

05 http连接处理&#xff08;中&#xff09; 流程图与状态机 从状态机负责读取报文的一行&#xff0c;主状态机负责对该行数据进行解析&#xff0c;主状态机内部调用从状态机&#xff0c;从状态机驱动主状态机 主状态机 三种状态&#xff0c;标识解析位置 CHECK_STATE_RE…

Python工具箱系列(三十九)

使用zlib对数据进行压缩 现实世界中&#xff0c;大量存在着对数据压缩的需求。为此&#xff0c;python内置了zlib压缩库&#xff0c;可以方便的对任意对象进行压缩。 下述代码演示了对字符串进行压缩&#xff1a; import zlib# 压缩一段中文 originstr 神龟虽寿&#xff0c…

风靡朋友圈的妙鸭相机,到底用了哪些底层技术?

不知道大家近期的朋友圈有没有被和海马体、天真蓝如出一辙的AI写真刷屏&#xff01; 这些面若桃花、精致到头发丝、光影充满氛围感的写真都是一款叫“妙鸭相机”的小程序生成的&#xff01;只要9.9&#xff0c;就能体验999写真&#xff01; 虽然只要9.9&#xff0c;但生成的照片…

Mac电脑目录

System&#xff08;系统&#xff09;Applications&#xff08;应用程序&#xff09;应用程序目录&#xff0c;默认所有的GUI应用程序都安装在这里User&#xff08;用户&#xff09;存放用户的个人资料和配置。每个用户有自己的单独目录Library&#xff08;资料库&#xff09;系…

定义dubbo自己的异常过滤器

起因 发现这个问题的起因是前端联调接口的时候发现统一的异常处理没有发挥作用,我们定义的处理的异常类型为AppException(国际惯例继承于RuntimeException),但是Dubbo服务端实际返回的异常变成了RuntimeException,我们自定义的异常处理没有发生作用&#xff0c;导致前端报500异…

恒运资本:A股、港股全线爆发,沪指突破3300点,恒指重返2万点上方

7月31日&#xff0c;两市股指高开高走&#xff0c;沪指在金融、地产、酿酒等权重板块的带动下一举突破3300点。截至发稿&#xff0c;沪指、深成指、创业板指涨幅均超1%&#xff0c;上证50指数涨近2%。Wind数据显现&#xff0c;北向资金净买入超25亿元。 职业方面&#xff0c;券…

清风徐来【个人】

清风徐来【个人】 前言版权清风徐来【个人】我的博客我的专栏我的粉丝我获得的奖品我的其他平台我的投稿 最后 前言 2023-7-29 10:57:54 花若向阳花自开 人若向暖清风徐来 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https…

笔记本数据恢复,这5个方法记好了!

我的笔记本从大学就开始用了&#xff0c;里面有很多重要的资料和文件。但昨天打开时&#xff0c;它突然卡着了&#xff0c;等到恢复过来之后&#xff0c;我发现我有些数据就是莫名其妙就消失了。有什么方法能帮我恢复笔记本的数据吗&#xff1f;” 随着笔记本电脑在我们生活中扮…

【LeetCode】不同路劲(动态规划)

不同路劲 题目描述算法流程编程代码 链接: 不同路劲 题目描述 算法流程 编程代码 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m 1,vector<int>(n 1));dp[1][0] 1;for(int i 1;i < m;i){for(int j 1;j < n…

【MySQL】存储过程(十一)

🚗MySQL学习第十一站~ 🚩本文已收录至专栏:MySQL通关路 ❤️文末附全文思维导图,感谢各位点赞收藏支持~ 一.引入 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程可以简化应用开发人员的工作,可以减少数据在数据库和应用服务器之间的传输,…