Angular实现一个简单的带tabs选项卡切换的首页导航功能

news2024/12/25 9:31:37

Angular版本:16.1.1

 项目结构:

angular.json配置:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angular-router": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/angular-router",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": [
              "zone.js"
            ],
            "tsConfig": "tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "angular-router:build:production"
            },
            "development": {
              "browserTarget": "angular-router:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "angular-router:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": [
              "zone.js",
              "zone.js/testing"
            ],
            "tsConfig": "tsconfig.spec.json",
            "inlineStyleLanguage": "scss",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          }
        }
      }
    }
  }
}

 package.json:

{
  "name": "angular-router",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^16.1.0",
    "@angular/common": "^16.1.0",
    "@angular/compiler": "^16.1.0",
    "@angular/core": "^16.1.0",
    "@angular/forms": "^16.1.0",
    "@angular/platform-browser": "^16.1.0",
    "@angular/platform-browser-dynamic": "^16.1.0",
    "@angular/router": "^16.1.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.13.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^16.1.1",
    "@angular/cli": "~16.1.1",
    "@angular/compiler-cli": "^16.1.0",
    "@types/jasmine": "~4.3.0",
    "jasmine-core": "~4.6.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.1.3"
  }
}

tsconfig.app.json:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

tsconfig.json:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": [
      "ES2022",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

styles.scss全局样式表清除部分默认样式

/* You can add global styles to this file, and also import other style files */
*{
    margin: 0;
    padding: 0;
    border: 0;
}

一、ng命令添加4个页面组件(tabs,tab1,tab2,tab3,info),angular会自动把组件导入到app.module.ts中

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
// 所有页面导入根模块
import { TabsComponent } from './tabs/tabs.component';
import { Tab1Component } from './tab1/tab1.component';
import { Tab2Component } from './tab2/tab2.component';
import { Tab3Component } from './tab3/tab3.component';
import { InfoComponent } from './info/info.component';

@NgModule({
  declarations: [
    AppComponent,
    TabsComponent,//声明所有页面组件
    Tab1Component,
    Tab2Component,
    Tab3Component,
    InfoComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

二、在app.component.html里添加路由占位标签,根据路由规则,会把路由匹配的页面插入到这里显示,这里的<router-outlet></router-outlet>会将路由规则中一级路由匹配到的组件插入,因为app.component.html是项目根模块中的页面

<!-- index.html加载本页面组件,本页面只有一个路由占位标签 -->
<!-- 路由占位,会将本模块(这里是根模块)的一级路由对应页面插入进来显示 -->
<!-- 这里会将我们的一级路由的页面插入进来显示,当路由到tabs页面时也就是带导航选项卡的页面 -->
<!-- 本案例的一级路由有2个页面,分别是tabs和info,输入http://localhost:port/默认导航到tabs/tab1显示导航页,这个在定义的路由规则中可以看到 -->
<!-- 可以看到tabs页面组件中同样存在此占位标签,将tabs子路由的页面插入到tabs页面中<router-outlet></router-outlet>显示 -->
<router-outlet></router-outlet>

app.component.scss和app.component.ts默认无修改内容

三、在app.routing.module.ts里编写路由规则

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TabsComponent } from './tabs/tabs.component';
import { Tab1Component } from './tab1/tab1.component';
import { Tab2Component } from './tab2/tab2.component';
import { Tab3Component } from './tab3/tab3.component';
import { InfoComponent } from './info/info.component';
// 一级路由匹配到的页面在定义该路由规则所在的模块的组件中的<router-outlet></router-outlet>中插入显示
//相应的,一级路由下匹配到的页面的子路由在相应页面的<router-outlet></router-outlet>中显示
//这里一级路径在app模块(本项目根模块)中定义,则一级路由页面插入到app.component.html里的<router-outlet></router-outlet>中
// 这里一级路由有2个分别为tabs和info页面,tabs页面的子路由匹配到的页面插入到tabs页面组件中的<router-outlet></router-outlet>中显示
// tabs子路由有三个页面,在tabs中通过路由指令routerLink指定路径,配合tabs页面的<router-outlet></router-outlet>即实现首页导航
const routes: Routes = [
  // 一级路由,输入http://localhost:port/默认导航到/tabs/tab1,
  //tabs是首页,带多个导航选项卡,点击切换不同内容
  //输入http://localhost:port/info则进入info页面,也可通过
 
  { 
    path:"tabs",
    component:TabsComponent,
    children:[
      //tabs的子路由,实现了一个首页导航tab切换选项卡,
      //输入http://localhost:port默认导航到/tabs/tab1页面
      {
        path:"tab1",
        component:Tab1Component
      },
      {
        path:"tab2",
        component:Tab2Component
      },
      {
        path:"tab3",
        component:Tab3Component
      },
      {//这里路径为空则会重定向到tabs/tab1
        //比如http://localhost:port/tabs就会默认到http://localhost:port/tabs/tab1
        path:"",
        redirectTo:"tabs/tab1",
        pathMatch:"full"
        
      }
    ]
  },
  {
    path:"info",
    component:InfoComponent
  },
  //这里路径为空就会重定向到tabs/tab1
  //比如http://localhost:port就会默认到http://localhost:port/tabs/tab1
  {
    path:"",
    redirectTo:"tabs/tab1",
    pathMatch:"full"
  }
 
 
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

四、在tabs.component.html里编写页面,显示三个导航切换卡,tabs中的<router-outlet></router-outlet>标签会根据tabs组件子路由的规则插入组件显示,实现顶部<a></a>标签中的路由指令routerLink切换底部不同组件内容显示


<nav>
    <a routerLink="/tabs/tab1">tab1</a>
    <a routerLink="/tabs/tab2">tab2</a>
    <a routerLink="/tabs/tab3">tab3</a>
</nav>
<!-- 路由占位,将tabs的子路由匹配到的页面插入到这里,上面a标签中的routerLink指令即是路由指令 -->
<!-- 点击上面任意a标签根据路由指令路径匹配到相关页面后插入到这里显示,即实现导航页 -->
<!-- 本页面有三个导航切换标签,点击tab1或其他会相应在<router-outlet></router-outlet>插入tab1页面或其他页面显示,这里实现了顶部导航切换,底部相应内容显示 -->
<!-- 在tab1中设置了一个按钮,点击会跳转到info页面,info和tabs为一级路由中定义的路由页面,会在app.component.html里的<router-outlet></router-outlet>中显示,即离开导航页,也就看不到导航选项卡 -->
<router-outlet></router-outlet>

tabs.component.scss


nav{
    width: 100%;
    height: 60px;
    background-color: antiquewhite;
    display: flex;
}
a{
    flex: 1;
    text-align: center;
    height: 60;
    line-height: 60px;
    text-decoration:none;
}

tabs.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-tabs',
  templateUrl: './tabs.component.html',
  styleUrls: ['./tabs.component.scss']
})
export class TabsComponent {
  
}

五、编写tab1,tab2,tab3,info页面组件

1、tab1

tab1.component.html

<p>tab1 works!</p>
<button (click)="go()">点击跳转info页面</button>

tab1.component.scss

button{
    width: 100px;
    height: 100px;
}

tab1.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-tab1',
  templateUrl: './tab1.component.html',
  styleUrls: ['./tab1.component.scss']
})
export class Tab1Component {
  constructor(private router:Router){

  }
  go(){
    this.router.navigateByUrl("info");
  }
}

2、tab2

tab2.component.html

<p>tab2 works!</p>

tab2.component.scss和tab2.component.ts默认无修改内容

3、tab3

tab3.component.html

<p>tab3 works!</p>

tab3.component.scss和tab3.component.ts默认无修改内容

4、info

info.component.html

<p>info works!</p>

info.component.scss和info.component.ts默认无修改内容

至此全部编写完成,执行ng serve运行,默认首页http://localhost:4200/tabs/tab1,点击不同导航选项卡,下面显示不同组件的内容,点击tab1下的按钮会直接跳转到http://localhost:4200/info,info组件会替换tabs组件在app.component.html中显示,也就不会有顶部导航选项卡,因为导航选项卡是tabs组件中的

 

 

 Angular实现简单的首页顶部导航tabs切换

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

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

相关文章

自定义双亲委派-JVM(三)

上篇文章说了java类加载源码&#xff0c;双亲委派的加载。 JVM类加载&双亲委派-JVM&#xff08;二&#xff09; 自定义类加载器 全盘负责委托机制 “全盘委托”指当一个classLoader装载一个类时&#xff0c;除非显示的使用另外一个classLoader加载&#xff0c;否则该类…

如何使用命令提示符重新启动Windows 资源管理器?

电脑资源管理器出现问题&#xff0c;导致电脑黑屏&#xff0c;如何使用命令提示符重新启动Windows 资源管理器呢&#xff1f;出现这个问题的时候&#xff0c;不要慌&#xff0c;按照下面的操作步骤&#xff0c;大概率是可以复原的&#xff0c;当然你觉得这样比较麻烦&#xff0…

C语言offsetof宏的使用与模拟实现

⭐️ 往期文章 ✨链接1&#xff1a;C语言文件打开关闭详解、文件顺序读写详解。 ✨链接2&#xff1a;C语言文件随机读写详解(fseek、ftell、rewind)。 ✨链接3&#xff1a;C语言scanf/fscanf/sscnaf和printf/fprintf/sprintf的区别。 ✨链接4&#xff1a;C语言打开文件一次既可…

论文不详细解读(二)——SimCLR系列

1. SimCLR v1 论文名称&#xff1a; A Simple Framework for Contrastive Learning of Visual Representations 开源地址&#xff1a;https://github.com/google-research/simclr 大佬论文解读&#xff1a;https://zhuanlan.zhihu.com/p/378953015 highlight&#xff1a;更多…

机器学习10:正则化-Regularization

目录 1.什么是正则化&#xff1f; 2.简化正则化&#xff1a;Lambda 3.两个练习 3.1 问题一 3.2 问题二 4.参考文献 1.什么是正则化&#xff1f; 考虑以下泛化曲线&#xff0c;它显示了训练集和验证集相对于训练迭代次数的损失。 图 1. 训练集和验证集的损失 图 1 显示了…

Docker数据卷与容器的挂载

什么是Docker数据卷: 数据卷&#xff08;Volumes&#xff09;是宿主机中的一个目录或文件&#xff0c;当容器目录和数据卷目录绑定后&#xff0c;对方的修改会立即同步。一个数据卷可以被多个容器同时挂载&#xff0c;一个容器也可以被挂载多个数据卷。简单来说数据卷本质其实是…

面试之谈谈你对SpringMVC的理解:

1.把传统的MVC架构里面的Controller控制器进行了拆分。分成了前端控制器的DispatcherServlteth和后端控制器的Controoler. 2.吧Model模型拆分成了业务层Service和数据访问层Repository 3.在试图层&#xff0c;可以支持不同的试图&#xff0c;比图Freemakr,volocity,JSP等等。 所…

【多维Dij+DP】牛客小白月赛75 D

D-矩阵_牛客小白月赛75 (nowcoder.com) 题意&#xff1a; 思路&#xff1a; 首先&#xff0c;对于这种类似于多维BFS的东西&#xff0c;我们一定需要判断是否必要加上新的一维&#xff0c;即我们需要判断新的一维对决策有没有影响 在这道题中&#xff0c;如果把某一个位置取…

MySql脚本 asc 排序字段空值条目靠后的写法

场景&#xff1a; mysql中如果使用正序 asc 排序&#xff0c;那么默认是把排序字段值为空的条目数据&#xff0c;优先排到前面&#xff0c;这明显不符合需求&#xff0c;解决如下 一、重现问题 -- 按排序号-正序 select shop_id,sort_num,update_time from t_shop_trend_conte…

详解c++---哈希闭散列

目录标题 一道题了解哈希哈希的实现原理方法一方法二 准备工作insertfind函数erase函数检测代码 一道题了解哈希 点击此处来尝试做这道题 首先题目告诉我们这个字符串中只含有小写的英文字母而小写的英文字母只有26个&#xff0c;所以我们可以创建一个大小为26的字符数组用来记…

【python爬虫应用03】csdn个人所有文章质量分查询

&#x1f6e0;️ 环境准备 在开始编写代码之前&#xff0c;我们需要进行一些环境准备。以下是所需的环境和库&#xff1a; 操作系统&#xff1a;Windows编程语言&#xff1a;Python 3编辑器&#xff1a;VSCode&#xff08;可选&#xff09; 安装所需的库&#xff1a; reque…

2023年最新IDEA中 Java程序 | Java+Kotlin混合开发的程序如何打包成jar包和exe文件(gradle版本)

文章内容&#xff1a; 一. JAVA | JAVA和Kotlin混开开发的程序打包成jar方法 1.1 方法一 &#xff1a;IDEA中手动打包 1.2 方法二 &#xff1a;build.gradle中配置后编译时打包 二. JAVA | JAVA和Kotlin混合开发的程序打包成exe的方法 一. JAVA | JAVA和Kotlin混开开发的程序…

Javalin:一个轻量的 Web Framework

说起 Java 语言下的 Web 框架那就非 Spring Framework 不可了&#xff0c;但是今天在和别人在聊天的过程中发现了一个新奇的项目 Javalin。Javalin 是一个轻量的 Web 框架。支持 WebSocket, HTTP2 和异步请求。简单的看了一下官方的说明文档&#xff0c;确实非常轻量&#xff0…

【ISO26262】汽车功能安全第5部分:硬件层面

对于每种方法,应用相关方法的推荐等级取决于 ASIL等级,分类如下: ———“”表示对于指定的 ASIL等级,高度推荐该方法; ———“”表示对于指定的 ASIL等级,推荐该方法; ———“o”表示对于指定的 ASIL等级,不推荐也不反对该方法。 表2 硬件设计的安全分析 单点故障度量 图 C.…

共享平台用户行为研究

背景 “促进平台经济、共享经济健康发展”是我国第十四个五年规划和二〇三五年远景目标中的重要内容。 研究工作概述 围绕共享平台和双边用户价值创造一般理论和实践&#xff0c;本研究综合多种方法&#xff08;LDA、社会网络分析、计量经济模型等&#xff09;和多种数据源交…

chatgpt赋能python:用Python编写SEO文章的技巧

用Python编写SEO文章的技巧 SEO&#xff08;Search Engine Optimization&#xff09;是优化网站以在搜索引擎中获得更高排名的过程。编写有趣、有价值且SEO友好的内容是重要的一环。在这篇文章中&#xff0c;我们将探讨使用Python编写SEO文章的技巧。 着重标记加粗的标题 搜…

[Eigen中文文档] 在 BLAS/LAPACK 、英特尔® MKL 和 CUDA 中使用 Eigen

文档总目录 本文目录 在BLAS/LAPACK使用 Eigen在英特尔 MKL使用 Eigen链接 在 CUDA 内核中使用 Eigen 在BLAS/LAPACK使用 Eigen 英文原文(Using BLAS/LAPACK from Eigen) 自Eigen 3.3版本以及以后&#xff0c;任何F77兼容的BLAS或LAPACK库都可以用作稠密矩阵乘积和稠密矩阵分…

第九十四天学习记录:C++核心:类和对象Ⅲ(五星重要)

深拷贝与浅拷贝 深浅拷贝是面试经典问题&#xff0c;也是常见的一个坑 浅拷贝&#xff1a;简单的赋值拷贝操作 深拷贝&#xff1a;在堆区重新申请空间&#xff0c;进行拷贝操作 #define _CRT_SECURE_NO_WARNINGS 1#include<iostream> using namespace std;class Perso…

简述环保用电监管云平台

1、概述 推进打赢蓝天保卫战&#xff0c;打好碧水保卫战&#xff0c;打胜净土保卫战&#xff0c;加快生态环境保护、建设美丽中国&#xff0c;各省市结合物联网和大数据政策&#xff0c;也相继颁布有关污染治理设施用电监管平台等相关政策。针对企业内的环保设施、设备运行状况…

Spring Boot中Elasticsearch的连接配置、原理与使用

Spring Boot中Elasticsearch的连接配置、原理与使用 引言 Elasticsearch是一种开源的分布式搜索和数据分析引擎&#xff0c;它可用于全文搜索、结构化搜索、分析等应用场景。在Spring Boot中&#xff0c;我们可以通过Elasticsearch实现对数据的搜索和分析。本文将介绍Spring …