书接上回
上一次在文章中,我们讲解了Vue前端的容器搭建,在本文中,我们将继续细化设计,逐步完成一个较为完善的导航栏。
组件引用
组件引用是为了在较大规模开发时避免代码塞在一个文件里边,增加可读性。
在引用的主文件里的 js部分import,然后直接在 tmplate部分调用即可,代码如下
<template><div><navigator></navigator></div>
</template><style scoped></style><script setup>
// 导入组件
import navigator from "@/page/navigator/navigator.vue"
</script>
在需要被调用的组件中,记得一定要有<script setup>部分
<template><div class="navigator"></div>
</template><style scoped></style><script setup></script>
调试浏览器,发现调用成功
导航栏框架搭建
这里提供一个简单的导航栏框架设计,本文将详细讲解微调过程。
先展示初版效果:
提几个要点:
- 导航栏可以做个下端阴影,这样就算全白也会有区分度,看起来比较舒服
- 搜索框的border可以粗一点弄成圆的,用的element-plus组件所以需要使用::deep贯穿
<template><div class="navigator"><div class="logo"><img src="../../asset/board/logo.png" style="height:400%;margin-top: -21%;margin-left: 15%;user-select: none;"></div><div class="search"><el-inputv-model="keyword"placeholder="请输入搜索内容"suffix-icon="Search"class="round-input"style="width:100%; height:60%; margin-top:3%"></el-input></div><div class="selectionSet"><el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" style="margin-top: 3%;margin-left: 10%"><el-tab-pane label="首页" name="first"> </el-tab-pane><el-tab-pane label="资料库" name="second"> </el-tab-pane><el-tab-pane label="讨论区" name="third"> </el-tab-pane><el-tab-pane label="收藏夹" name="fourth"> </el-tab-pane></el-tabs><img src="../../asset/board/碳治郎1.png"style="height:90%;margin-left: 10%;margin-top: 0.5%"></div></div>
</template><style scoped>
.navigator {display: flex;align-items: center;/* background-color: #d5e4f4;*/background-color: #ffffff;height: 9%;/* 添加底部阴影效果 */box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}.logo {width: 30%;height: 100%;display: flex;padding-left: 3%;
}.search {display: flex;width: 30%;height: 100%;
}:deep(.round-input .el-input__wrapper) {border-radius: 20px !important;background-color: #FFFFFF;box-shadow: 0 0 0 1.5px rgb(210, 203, 241) !important;
}.selectionSet {display: flex;width: 40%;height: 100%;
}:deep(.el-tabs__item) {color: #000000;font-size: 25px;transition: color 0.3s ease;
}::v-deep .el-tabs__active-bar {background-color: #064fe1 !important;
}:deep(.el-tabs__nav-wrap::after) {position: static !important;
}
</style><script setup>
import { ref } from 'vue';const keyword = ref('');
const activeName = ref('first');const handleClick = (tab) => {console.log(' 当前选中标签:', tab.name);
};
</script>
图片文字取消点击光标闪烁
比如点击右上tab,发现光标是闪烁的,看的很不舒服,这里可以内联为元素设置一下
之后就不可选中了,图像貌似不可以这样解决,可以给图像设计一个点击跳转或点击放大,就不会出现光标闪烁了
user-select: none
输入框偏斜
如题所示,解决方案为在外边包的div上设置user-select:none ;这个偏斜实际上是选中了这个div
输入框悬停和聚焦流光动画
以下展示为全代码,方便CV
<template><div class="navigator"><div class="logo"><img src="../../asset/board/logo.png" style="height:100%;margin-left: 20%;"></div><div class="search"><el-inputv-model="keyword"placeholder=" biuuuu~ 灵 光 乍 现"suffix-icon="Search":class="{ 'round-input':true,'animated-placeholder': isSearchHover,'is-focused': isFocused }"style="width:100%; height:60%; margin-top:3%"@focus="handleFocus"@blur="handleBlur"></el-input></div><div class="selectionSet"><el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" style="margin-top: 3%;margin-left: 13%"><el-tab-pane label="首页" name="first"> </el-tab-pane><el-tab-pane label="资料库" name="second"> </el-tab-pane><el-tab-pane label="讨论区" name="third"> </el-tab-pane><el-tab-pane label="收藏夹" name="fourth"> </el-tab-pane></el-tabs><img src="../../asset/board/碳治郎1.png"style="height:90%;margin-left: 10%;margin-top: 0.5%;user-select: none;"></div></div>
</template><style scoped>
.navigator {display: flex;align-items: center;background-color: #ffffff;height: 9%;/* 添加底部阴影效果 */box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}.logo {width: 30%;height: 100%;display: flex;padding-left: 3%;
}.search {display: flex;width: 30%;height: 100%;user-select: none;
}:deep(.round-input .el-input__wrapper) {border-radius: 20px !important;background-color: #FFFFFF;box-shadow: 0 0 0 1.5px rgb(210, 203, 241) !important;
}.selectionSet {display: flex;width: 40%;height: 100%;
}:deep(.el-tabs__item) {color: #000000;font-size: 20px;transition: color 0.4s ease;user-select: none;
}::v-deep .el-tabs__active-bar {background-color: rgb(2, 90, 255) !important;
}:deep(.el-tabs__nav-wrap::after) {position: static !important;
}@keyframes placeholderSlide {0% { transform: translateX(0); opacity: 0.6 }100% { transform: translateX(-10px); opacity: 0.2 }
}:deep(.round-input .el-input__wrapper) {transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); /* 平滑过渡 */
}/* 悬停状态增强 */
:deep(.round-input:hover .el-input__wrapper) {box-shadow: 0 0 0 2px rgba(2, 90, 255, 0.3) !important;transform: scale(1.02);
}/* 聚焦状态动画 */
:deep(.round-input.is-focused .el-input__wrapper) {box-shadow: 0 0 0 3px rgba(2, 90, 255, 0.2) !important;background-color: #f8f9fa;
}/* 动态placeholder动画 */
.animated-placeholder::placeholder {font-size: 14px;transition: all 0.3s ease;text-align: center;
}/* 悬停时placeholder动画 */
:deep(.round-input:hover) .animated-placeholder::placeholder {animation: placeholderSlide 0.8s infinite alternate;text-align: left;padding-left: 28px;
}/* 聚焦时placeholder消失动画 */
:deep(.round-input:focus-within) .animated-placeholder::placeholder {opacity: 0;transform: translateX(20px);transition: all 0.2s ease;
}
@keyframes streaming-light {0% { background-position: 0% 50%; }50% { background-position: 100% 50%; }100% { background-position: 0% 50%; }
}/* 流光容器 */
:deep(.round-input) .el-input__wrapper {position: relative;overflow: hidden;transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}/* 流光伪元素 */
:deep(.round-input) .el-input__wrapper::after {content: '';position: absolute;top: -2px;left: -2px;right: -2px;bottom: -2px;background: linear-gradient(45deg,rgba(2,90,255,0.1) 0%,rgba(255,255,255,0.8) 25%,rgba(2,90,255,0.3) 50%,rgba(255,255,255,0.8) 75%,rgba(2,90,255,0.1) 100%);background-size: 400% 400%;opacity: 0;z-index: 1;transition: opacity 0.8s ease;pointer-events: none;border-radius: 22px;
}/* 触发动画的条件 */
:deep(.round-input.is-focused) .el-input__wrapper::after,
:deep(.round-input:hover) .el-input__wrapper::after {opacity: 1;animation: streaming-light 8s linear infinite;
}/* 输入框内容层提升层级 */
:deep(.el-input__inner) {position: relative;z-index: 2;background: transparent !important;
}
</style><script setup>
import { ref } from 'vue';let isSearchHover=ref(false);
let isFocus=ref(false);
const keyword = ref('');
const activeName = ref('first');const isFocused = ref(false);const handleFocus = () => {isFocused.value = true;
};
const handleBlur = () =>
{isFocused.value = false;
};
</script>
总结
本文中实现了一个前端代码比较完善的Nav开发,展示了各种可能遇到的问题,希望能对读者有所帮助