「网页开发|前端开发|Vue」05 Vue实战:从零到一实现一个网站导航栏

news2024/11/25 13:43:19

本文主要介绍如何从最开始的草图,通过确定基本结构、修改元素布局、美化外观来实现一个网站导航栏,从而熟悉网页开发的基本流程。同时,我们会把性能、规范性、可维护性方面的代码优化也考虑其中。

文章目录

  • 本系列前文传送门
  • 一、场景说明:设计目标
  • 二、确定基本结构
  • 三、修改布局
  • 四、外观美化
    • 安装css框架
      • npm 安装并引入组件库
      • CDN方式直接引入
    • 加入自定义样式
  • 五、代码优化
    • 减少重复代码
    • 性能优化
      • element-ui的el-link与vue-router的route-link结合
    • 分离HTML和CSS代码
  • 附录:源代码

本系列前文传送门

  • 「网页开发|前端开发|Vue」01 快速入门:快速写一个Vue的HelloWorld项目
  • 「网页开发|前端开发|Vue」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转
  • 「网页开发|前端开发|页面布局」03 学会够用的CSS,实现任意你想要的页面布局
  • 「网页开发|前端开发|Vue」04 快速掌握开发网站需要的Vue基础知识

一、场景说明:设计目标

我们在网站设计中,首页作为用户进入网站最先看到的页面,是网站比较重要的页面之一。而在首页的结构中,导航栏是一个重要的组成部分,甚至我们会在多个页面中复用导航栏。

于是,我们希望通过从零到一实现一个导航栏来熟悉网页开发的主要流程。

我们可以先观察一些常用网站的首页导航栏来确定我们的导航栏要设计成什么样子:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们可以看到导航栏大多可以分为三个部分,由左往右依次是:

  • 网站/品牌相关信息:网站logo以及网站名称的展示
  • 网站内容的展示以及导航:导航菜单/选项,以及可能提供了搜索栏帮助用户快速搜索内容
  • 用户相关的功能:主要是注册和登录按钮;如果考虑登录状态则应该是进入用户图标以及用户名。

所以我们可以设计我们的导航栏也是三个部分,从左往右是:

  • 第一部分:网站logo和网站名称
  • 第二部分:不同页面的跳转选项
  • 第三部分:注册和登录按钮

根据这个划分可以画出草图如下:
在这里插入图片描述

二、确定基本结构

根据草图,我们希望的导航分为三个部分,可以分别用三个<div>标签来承载:

  • 第一个部分包含一个logo图片和网站名称,可以使用<img><span>表示
  • 第二个部分是一些跳转标签,可以使用<ul>来表示
  • 第三个部分是用户登录和注册按钮,直接使用<button>表示

根据如上内容,我们可以写出以下代码:

    <div id="app">
        <div class="header">
            <div class="content-main">
                <div class="logo">
                    <img src="../assets/logo.png" />
                    <span>我的网站</span>
                </div>
                <ul>
                    <li>
                        <a href="#" target="_blank">
                            首页
                        </a>
                    </li>
                    <li>
                        <a href="#" target="_blank">
                            产品
                        </a>
                    </li>
                    <li>
                        <a href="#" target="_blank">
                            关于我们
                        </a>
                    </li>
                </ul>
                <div>
                    <button>注册</button>
                    <button>登录</button>
                </div>
            </div>
        </div>
    </div>

浏览器可以将上述代码渲染成如下页面:
在这里插入图片描述
根据之前在「网页开发|前端开发|页面布局」03 学会够用的CSS,实现任意你想要的页面布局中介绍的内容,我们可以知道:

  • 因为<div>是块级标签,所以三个<div>会各自独占整行,然后从上往下排列。
  • 而在第一个<div>中,因为<img><span>都是行内元素,所以两个元素会同处一行。
  • 在第二个<div>中只有一个<ul>,会独占整行。而在<ul>内部是三个<li>,因为<li>也是块级元素,所以会在<ul>占据的空间中从上往下排列。
  • 第三个<div>中有两个<button><button>是行内元素,所以两个按钮在同一行中并列排布。

接下来我们要将这些元素当前的布局修改成我们在草图中规划的布局。

三、修改布局

我们在「网页开发|前端开发|页面布局」03 学会够用的CSS,实现任意你想要的页面布局中介绍过,修改布局,主要可以靠修改display属性的值来实现。

首先我们希望三个<div>并排在一行中,所以需要把三个<div>display值改成inline-block,代码改动情况如下:在这里插入图片描述

然后可以在浏览器中看到页面的布局变化如下:
在这里插入图片描述
进一步,我们希望第二个<div>中的三个<li>也是在一行中并排,于是,我们也同样修改display属性为inline-block,如下:
在这里插入图片描述

然后我们就可以看到页面的布局已经变成了我们希望的并列一行:
在这里插入图片描述

四、外观美化

在美化页面元素的外观时,我们就可以直接用上一些现成的主流css框架了。这里使用的是element-ui,大家可以根据业务和设计需求选择不同的框架。

安装css框架

为了使用css框架,需要先将框架集成到我们的项目中,可以通过npm安装,也可以
通过CDN引入jscss文件。

npm 安装并引入组件库

推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。

  • 首先运行安装命令:npm i element-ui -S
  • 然后在src/main.js中增加如下导入代码:
    在这里插入图片描述

CDN方式直接引入

目前可以通过 unpkg.com/element-ui 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

然后我们就可以在页面代码中使用element-ui中已经编写好的元素了,具体使用方面就是使用element-ui的元素标签代替原生的html标签,并且修改元素属性来调整element-ui元素的具体样式,比如将按钮替换成element-ui的默认样式按钮(element-ui按钮的样式代码可以在官网文档的组件中查看),如下:
在这里插入图片描述

然后我们就可以在浏览器中看到我们的按钮已经变成了如下样式:
在这里插入图片描述

同样,我们可以对跳转链接做如下修改:
在这里插入图片描述
修改后页面渲染效果如下:
在这里插入图片描述

加入自定义样式

除了使用css框架中的样式元素之外,我们也可以加入一些自定义样式来满足定制化场景。比如:

  • 鼠标放到logo图片上要变成指针的样式
  • 把logo图片的尺寸改成20 x 20
  • 将网站名称进行加粗处理
  • logo图片和网站名称在同一条水平线上对齐;并且要有些间距
  • 三个<div>标签之间需要有些间距

于是我们在.vue文件中,给第一个<div>增加logoclass,给第三个<div>增加userclass,然后添加<style scoped></style>标签来编写我们对这个组件/这个页面的自定义样式,添加代码如下:

<style>
.logo {
    display: inline-block;
    cursor: pointer;
    margin-right: 46px;

    /* >img 表示 class='logo'的元素中的<img>标签 */
    >img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
        margin-right: 10px;
    }

    >span {
        font-weight: bold;
        vertical-align: middle;
    }
}

.user {
    display: inline-block;
    margin-left: 46px;

}
</style>

添加自定义样式后,页面效果如下:
在这里插入图片描述

五、代码优化

在代码的渲染效果符合我们的设计预期之后,我们可以对代码进行一些非功能上的优化,比如优化性能或者减少重复代码。

减少重复代码

我们可以看到我们的跳转链接,实际上是写了三遍,而这可以改成用一个列表来存储这些跳转链接的信息,然后用一个for循环的vue语法来展示各个跳转链接,如下:

  • 先添加一个<script></script>标签来放js代码,然后在js代码中定义要使用的跳转链接数据,如下:
    在这里插入图片描述

  • 然后将ul标签中的三个li改成用v-for指令生成,如下:
    在这里插入图片描述

这样修改之后,我们的代码更加简洁清晰,当我们回到浏览器刷新页面时发现,链接之间因为没有间距,所以三个链接挨在一起不太美观,如下:


我们添加一下margin属性来修复一下,如下:
在这里插入图片描述
修复后页面样式符合预期,如下:
在这里插入图片描述

性能优化

如果我们使用原生HTML<a>标签来实现跳转,则有些情况会出现不必要的页面加载。比如我们已经在首页了,点击跳转首页的链接仍然后会触发页面重新加载。
在这里插入图片描述

之前在 「网页开发|前端开发|Vue」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转中介绍<router-link>时提到了,<router-link>能够使得vue-router可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。减少页面的重新加载,从而提高网站的性能和用户在浏览和跳转过程中的体验。所以我们可以把代码中的<a>替换成<router-link>

element-ui的el-link与vue-router的route-link结合

因为我们是使用了element-ui封装好的文字链接元素<el-link>来进行跳转,相当于我们已经把<a>替换成<el-link>了,如果把<el-link>直接替换成<router-link>则会失去<el-link>的外观样式,为此,我们需要使用到vue-routerAPI形式以及vue绑定逻辑的v-on指令来实现router-link的功能,如下:
在这里插入图片描述

如此修改之后,我们再次在首页点击跳转首页的选项,已经不会有重新加载的情况出现了,并且其他跳转链接的功能一切正常。

分离HTML和CSS代码

还有一个比较明显的问题是,我们在最开始调整某些元素布局和样式的时候,直接在元素上使用了内嵌的css代码,同时也用<style>标签加入了自定义的样式,这会给代码的阅读带来一些麻烦,所以出于日后维护代码的考虑,我们需要将css都统一整理到<style>代码块中,如下:

<style>
li {
    display: inline-block;
    margin: 20px;
}

.nav-items {
    display: inline-block;
}

.logo {
    display: inline-block;
    cursor: pointer;
    margin-right: 46px;

    /* >img 表示 class='logo'的元素中的<img>标签 */
    >img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
        margin-right: 10px;
    }

    >span {
        font-weight: bold;
        vertical-align: middle;
    }
}

.user {
    display: inline-block;
    margin-left: 46px;

}
</style>

然后就可以删除所有html标签中的style="...."代码,并且在浏览器中验证页面的样式保持不变。

附录:源代码

<template>
    <div id="app">
        <div class="header">
            <div class="content-main">
                <div class="logo">
                    <img src="../assets/logo.png" />
                    <span>我的网站</span>
                </div>
                <ul class="nav-items">
                    <li v-for="item in  routerList " :key="item.id">
                        <el-link @click="$router.push({ path: item.path })" type="info">
                            {{ item.name }}
                        </el-link>
                    </li>
                </ul>
                <div class="user">
                    <el-button size="mini">注册</el-button>
                    <el-button size="mini">登录</el-button>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            routerList: [
                {
                    path: "/",
                    name: "首页",
                },
                {
                    path: "/product",
                    name: "产品",
                },
                {
                    path: "/about",
                    name: "关于我们",
                }
            ]
        }
    }
}

</script>

<style>
li {
    display: inline-block;
    margin: 20px;
}

.nav-items {
    display: inline-block;
}

.logo {
    display: inline-block;
    cursor: pointer;
    margin-right: 46px;

    /* >img 表示 class='logo'的元素中的<img>标签 */
    >img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
        margin-right: 10px;
    }

    >span {
        font-weight: bold;
        vertical-align: middle;
    }
}

.user {
    display: inline-block;
    margin-left: 46px;

}
</style>

至此我们的导航栏开发就完成了,我们将最开始画的草图和最终实现的页面效果放在一起感受一下:
在这里插入图片描述
在这里插入图片描述

(对自己感到满意(●ˇ∀ˇ●))芜湖~

写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇

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

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

相关文章

【LeetCode】双指针求解和为s的两个数字

Problem: 剑指 Offer 57. 和为s的两个数字 文章目录 题目解析算法思路分析复杂度Code 题目解析 首先来讲解一下本题的思路 我们看到本题的意思很简单&#xff0c;就是去这个nums这个数组中进行寻找&#xff0c;如果找到了两个数相加之和为target的话&#xff0c;那构成一个结果…

C++11新特性① | C++11 常用关键字实战详解

目录 1、引言 2、C11 新增关键字详解 2.1、auto 2.2、override 2.3、final 2.4、nullptr 2.5、使用delete阻止拷贝类对象 2.6、decltype 2.7、noexcept 2.8、constexpr 2.9、static_assert VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xf…

网络协议从入门到底层原理学习(二)—— Mac地址/IP地址

文章目录 网络协议从入门到底层原理学习&#xff08;二&#xff09;—— Mac地址/IP地址1、MAC地址2、MAC地址的表示格式3、MAC地址表4、MAC地址操作5、MAC地址的获取6、ARP7、ICMP8、IP地址9、IP地址的分类和格式10、不同分类的IP地址的范围11、特殊 IP 地址12、子网掩码13、子…

etcd分布式存储

etcd分布式存储 etcd简介etcd下载安装etcd常用命令etcd配置参数etcd集群golang操作etcd

C语言基础知识——枚举

1. 枚举 枚举&#xff08;Enumeration&#xff09;是一种用户自定义的数据类型&#xff0c;用于定义一组具有离散值的符号常量。枚举使得代码更加可读和易于理解&#xff0c;提高了代码的可读性和可维护性。 //枚举的语法 enum 枚举名称 {值1,值2,值3,... };1.1 枚举成员的类型…

C++中虚继承时的构造函数

在虚继承中,虚基类是由最终的派生类初始化的,换句话说,最终派生类的构造函数必须要调用虚基类的构造函数。对最终的派生类来说,虚基类是间接基类,而不是直接基类。这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。 下面…

react使用hook封装一个search+input+checkbox组件

目录 react使用hook封装一个searchinputcheckbox组件searchPro.jsx使用组件效果 react使用hook封装一个searchinputcheckbox组件 searchPro.jsx import { Checkbox, Input } from "antd"; import React, { useEffect, useState } from "react"; import S…

激活函数总结(二十七):激活函数补充(Multiquadratic、InvMultiquadratic)

激活函数总结&#xff08;二十七&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Multiquadratic激活函数2.2 InvMultiquadratic激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PReLU、Swish、ELU、SEL…

kubernetesl yaml deploy rancher server

文章目录 1. 简介2. 预备条件3. 创建存储目录4. 部署 rancher server5. 访问6. 加入集群 1. 简介 Rancher 是一个开源的企业级全栈化容器部署及管理平台。已有超过 1900 万次下载&#xff0c;4000 生产环境的应用。 简单的说&#xff0c;就是一个可以让你通过 web 界面管理 d…

78 # koa 中间件的实现

上上节实现了上下文的&#xff0c;上一节使用了一下中间件&#xff0c;这一节来实现 koa 的中间件这个洋葱模型。 思路&#xff1a; 储存用户所有的 callback将用户传递的 callback 全部组合起来&#xff08;redux 里的 compose&#xff09;组合成一个线性结构依次执行&#…

input输出的都是字符串,类似拼接的那种

input输出的都是字符串&#xff0c;类似拼接的那种 input()方法返回的所有的结果都是str字符串类型。

一个简单的文件系统(MinixFS)实现解析

1. Minix文件系统概要 Minix file system 是 Andrew S. Tanenbaum 在 1980 年代发明的文件系统, 并随着 Minix 操作系统一起于 1987 年发布。 Linus 编写 Linux 内核第一个版本的时候, 使用的也是 Minix FS, Linux 至今依然提供了对 Minix FS 的支持。Minix FS 结构简单, 易于…

【MyBatis篇】MyBatis框架基础知识笔记

目录 ORM思想&#xff08;对象关系映射思想&#xff09; ORM思想图解 初识MyBatis 什么是MyBatis呢&#xff1f; JDBC弊端 自己总结&#xff1a; chatGPT总结&#xff1a; MyBatis介绍以及本质分析 JDBC编程的劣势&#xff0c;MyBatis提供了以下解决方案&#xff0c;具…

星辰天合 CEO 胥昕受邀参加人民网 2023 “小巨人”发展论坛

为进一步推动专精特新“小巨人”企业高质量发展&#xff0c;近日&#xff0c;由人民网主办&#xff0c;人民网财经研究院、828 企业服务平台共同承办的 2023“小巨人”发展论坛在人民日报社新媒体大厦举行&#xff0c;星辰天合 CEO 胥昕受邀参加。 2023 “小巨人”发展论坛现场…

基于Pytorch构建Faster-RCNN网络进行目标检测的一段插曲-安装GPU环境

因工作原因&#xff0c;原来的台式机工作站发生了变更&#xff0c;除了GPU显卡&#xff08;NVIDIA GeForce GTX 1660显卡变成了NVIDIA Quadro P2200显卡&#xff09;以外&#xff0c;其他配置都差不多&#xff0c;从网上查阅NVIDIA Quadro P2200相当于NVIDIA GeForce GTX 1660显…

commet与websocket

commet与websocket Comet 前言 Comet是一种用于web的技术&#xff0c;能使服务器能实时地将更新的信息传送到客户端&#xff0c;而无须客户端发出请求&#xff0c;目前有两种实现方式&#xff0c;长轮询和iframe流。 实现方式 长轮询 长轮询是在打开一条连接以后保持&…

visual studio 2008 编译项目出现层次不穷问题枚举

文章目录 1、严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C1047 对象或库文件“.lib”是使用与其他对象(如“x64\Release\main.obj”)不同的1、错误原因 2、意外的预编译头错误,只需重新运行编译器就可能修复此问题3、 warning LNK4099: 未找到 PDB“vc90.pdb”(使用“..…

【数据结构与算法系列3】有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&#xff0c;数组变为 …

JavaScript学习笔记01

JavaScript笔记01 什么是 JavaScript JavaScript 是一门世界上最流行的脚本语言&#xff0c;它是一种弱类型的脚本语言&#xff0c;其代码不需要经过编译&#xff0c;而是由浏览器解释运行&#xff0c;用于控制网页的行为。 发展历史 参考&#xff1a;JavaScript的起源故事…

AbstractQueuedSynchronizer--AQS

概述&#xff1a;全称是 AbstractQueuedSynchronizer&#xff0c;是阻塞式锁和相关的同步器工具的框架特点&#xff1a; 用 state 属性来表示资源的状态&#xff08;分独占模式和共享模式&#xff09;&#xff0c;子类需要定义如何维护这个状态&#xff0c;控制如何获取锁和释放…