3、创建Cities Component
右击CitiesAngularApp,点击Open in Terminal
运行命令
ng g component Cities
得到如下文件
4、更新AppComponent
app-routing.module.ts添加路由
import { Routes } from '@angular/router';
import { CitiesComponent } from './cities/cities.component'
export const routes: Routes = [
{
path: "cities",
component: CitiesComponent
}];
app.component.ts第二行添加import并更新Component中的imports
如果遇到如下报错,就是因为RouterLink, RouterLinkActive没有导入导致的报错:
NG8002: Can't bind to 'routerLink' since it isn't a known property of 'a'.
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink, RouterLinkActive],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'CitiesAngularApp';
}
styles.css
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 18px;
background-color: #f7f7f7;
}
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
.container {
min-width: 500px;
}
.app-title {
font-size: 1.9em;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
margin-left: 4px;
}
.login-button {
margin-right: 16px;
}
.body {
padding: 20px;
padding-top: 10px;
}
.navbar {
padding: 10px;
}
.navbar > ul {
list-style-type: none;
width: 100%;
}
.navbar > ul > li {
width: 100%;
}
.navbar > ul > li > a:link, .navbar > ul > li > a:visited {
padding: 4px 8px;
cursor: pointer;
transition: background-color 0.4s;
display: inline-block;
margin: 0px 3px;
color: #0e5eba;
text-decoration: none;
}
.navbar > ul > li > a:hover {
background-color: #ffffff;
color: #086581;
}
.nav-active:before {
content: "";
position: absolute;
left: 15px;
bottom: -2px;
height: 1px;
width: 50%;
border-bottom: 2px solid #626262;
}
.nav-active {
position: relative;
}
.card-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.card {
flex: 1 0 300px;
padding: 20px;
border-radius: 10px;
border: 1px solid #cacaca;
max-width: 300px;
margin: 20px;
}
.page-content {
min-height: 90vh;
padding: 15px 20px;
}
.full-size-height {
min-height: 100vh;
}
.table-container {
padding: 15px;
background-color: #ffffff;
border-radius: 16px;
margin-top: 7px;
}
.table {
border-collapse: collapse;
margin: 10px 0px;
margin: auto;
}
.table thead {
font-weight: bold;
color: #000000;
text-align: left;
}
.table thead a:link, .table thead a:visited {
color: #000000;
text-decoration: none;
}
.table thead a:hover {
text-decoration: underline;
}
.table thead th {
padding: 5px 10px;
text-align: left;
border-bottom: 3px solid #efefef;
}
.table tbody td {
padding: 6px 10px;
}
.table tbody tr {
transition: background-color 0.4s, color 0.3s;
/*background-color: #efefef;*/
border-bottom: 1px solid #efefef;
}
.w-25 {
width: 25%;
}
.w-40 {
width: 40%;
}
.w-50 {
width: 50%;
}
.w-60 {
width: 60%;
}
.w-75 {
width: 75%;
}
.w-90 {
width: 90%;
}
.w-100 {
width: 100%;
}
.mt {
margin-top: 10px;
}
.mb {
margin-bottom: 10px;
}
.m {
margin: 10px;
}
.ml {
margin-left: 20px;
}
.mr {
margin-right: 10px;
}
.p {
padding: 10px;
}
.pt {
padding-top: 10px;
}
.pb {
padding-bottom: 10px;
}
.pl {
padding-left: 10px;
}
.pr {
padding-right: 10px;
}
.grey-back {
background-color: #dcdcdc;
}
.white-back {
background-color: #ffffff;
}
.text-blue {
color: #0349a3;
}
.text-green {
color: #0a8438;
}
.text-red {
color: #ff0000;
}
.text-grey {
color: #929292;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}
.text-large {
font-size: 2.5em;
margin-top: 30px;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
margin-bottom: 10px;
}
.margin-auto {
margin: auto;
}
.float-left {
float: left;
}
.clear {
clear: both;
}
.blue-back {
background-color: #9ad3f7;
}
.list-container {
margin-top: 9px;
}
.list {
list-style-type: none;
background-color: #ececec;
border: 1px solid #ececec;
border-radius: 8px;
}
.list > li {
padding: 8px 12px;
background-color: #ffffff;
margin: 3px 2px;
border-radius: 5px;
transition: background-color 0.3s, color 0.3s;
}
.list > li:hover {
background-color: #1383a4;
color: #ffffff;
}
.list a:link, .list a:visited {
color: initial;
text-decoration: none;
}
.footer-content {
background-color: #bfbfbf;
color: #000000;
padding: 20px;
text-align: center;
}
.header {
background-color: #055c87;
color: #ffffff;
padding: 20px;
text-align: center;
}
.border-bottom {
border-bottom: 2px solid #7a7a7a;
margin-bottom: 6px;
}
.border-top {
border-top: 2px solid #7a7a7a;
margin-top: 6px;
}
.border-left {
border-left: 1px solid #bfbfbf;
}
.border-right {
border-right: 1px solid #bfbfbf;
}
.box {
margin: 10px 20px;
padding: 15px;
border-radius: 8px;
border: 2px solid #d3d1d1;
box-shadow: 0px 0px 3px 2px #ffffff;
}
.flex-direction-vertical {
flex-direction: column;
}
.flex {
display: flex;
flex-wrap: wrap;
align-content: stretch;
align-items: stretch;
}
.flex > div {
padding: 4px;
}
.flex-1 {
flex: 1 auto;
}
.flex-2 {
flex: 2 auto;
}
.flex-3 {
flex: 3 auto;
}
.flex-4 {
flex: 4 auto;
}
.flex-5 {
flex: 5 auto;
}
.flex-6 {
flex: 6 auto;
}
a:link, a:visited {
color: blue;
}
a.link-hover:link {
padding: 5px;
border-radius: 9px;
transition: background-color 0.2s;
}
a.link-hover:hover {
background-color: #e5e5e5;
}
a.button-link:link, a.button-link:visited {
color: #ffffff;
padding: 8px 12px;
border: 2px solid #cacaca;
border-radius: 8px;
outline: 3px solid #ffffff;
font-size: 105%;
text-decoration: none;
display: inline-block;
}
.search-dropdown {
padding: 8px 12px;
font-size: 103%;
border-radius: 20px 0px 0px 20px;
border-top: 2px solid #cacaca;
border-bottom: 2px solid #cacaca;
border-left: 2px solid #cacaca;
border-right-style: none;
margin-right: 0px;
transition: box-shadow 0.2s;
}
.search-text {
padding: 8px 12px;
font-size: 105%;
border-radius: 0px 0px 0px 0px;
border-top: 2px solid #cacaca;
border-bottom: 2px solid #cacaca;
border-left-style: none;
border-right-style: none;
margin-right: 0px;
transition: box-shadow 0.2s;
position: relative;
left: -5px;
}
.search-button {
padding: 8px 12px;
border-top: 2px solid #cacaca;
border-bottom: 2px solid #cacaca;
border-right: 2px solid #cacaca;
border-radius: 0px 20px 20px 0px;
border-left-style: none;
/*outline: 3px solid #ffffff;*/
font-size: 105%;
position: relative;
left: -10px;
}
.button {
padding: 8px 12px;
border: 2px solid #cacaca;
border-radius: 8px;
font-size: 101%;
}
.button-blue-back {
background-color: #3a81bd;
color: #ffffff;
border: 2px solid #3f80ca;
}
.button-blue-back:hover {
background-color: #1274c7;
}
.button-green-back {
background-color: #088e36;
color: #ffffff;
border: 2px solid #73d695;
}
.button-green-back:hover {
background-color: #066627;
}
.button-red-back {
background-color: #cb511e;
color: #ffffff;
border: 2px solid #e49776;
}
.button-red-back:hover {
background-color: #96370f;
}
.button-panel {
margin-top: 20px;
}
.account-links {
display: block;
}
.pill {
background-color: #9e9e9eff;
color: #ffffff;
padding: 6px 12px;
border-radius: 10px;
margin: 7px 0px;
display: inline-block;
}
.form-input {
padding: 8px 10px;
font-size: 105%;
border-radius: 8px;
border: 1px solid #d0d0d0;
width: 100%;
transition: box-shadow 0.2s;
}
.form-input:focus {
outline: none;
border: 1px solid #245eb0;
box-shadow: 0px 0px 4px 0px #1383a4;
}
.form-label {
display: inline-block;
}
.center-box {
margin: auto;
width: 90%;
}
.form-field > div:first-child {
flex: 1;
width: auto;
}
.form-field > div:nth-child(2) {
flex: 1;
width: auto;
}
.margin-bottom {
margin-bottom: 5px;
}
.form-field {
flex-direction: column;
margin-bottom: 6px;
}
#top-bar-div {
flex-direction: column;
}
#search-box-div {
text-align: left;
padding-left: 15px;
padding-top: 10px;
padding-bottom: 10px;
}
.trading-button {
padding: 10px 15px;
margin-right: 20px;
cursor: pointer;
}
.stock {
margin-top: 20px;
}
.stock-title {
font-size: 2.2em;
color: #0a8ac6;
}
.stock-price {
font-size: 4.5em;
}
.trading-panel {
background-color: #f0f0f0;
}
#trade-button {
margin-top: 30px;
}
.trading-panel-flex {
flex-direction: column;
}
#stock-price-panel {
width: 100%;
max-width: 100%;
flex: 1 0 auto;
padding-right: 20px;
}
#new-order-panel {
padding-left: 5px;
padding-bottom: 20px;
padding-top: 50px;
padding-right: 5px;
flex: 1 0 auto;
border-left: 1px solid #bfbfbf;
}
.orders-list {
flex-direction: column;
}
#buy-orders-list, #sell-orders-list {
flex: 1 auto;
}
.stocks-list {
flex-direction: column;
}
#stocks-list {
min-width: 600px;
max-width: 700px;
}
.form-container {
background-color: #ffffff;
border-radius: 15px;
margin: auto;
width: 90%;
padding: 20px;
}
.inline-block {
display: inline-block;
}
@media screen and (min-width: 1000px) {
#top-bar-div {
flex-direction: row;
}
#search-box-div {
padding-top: 0px;
text-align: right;
}
.navbar > ul {
display: inline-block;
width: auto;
}
.navbar > ul > li {
display: inline-block;
width: auto;
}
#stock-price-panel {
flex: 2 0 auto;
max-width: 65%;
}
#new-order-panel {
padding-left: 90px;
padding-top: 220px;
flex: 1 0 auto;
}
.trading-panel-flex {
flex-direction: row;
/*color: */
}
.center-box {
width: 70%;
margin: auto;
}
.form-field > div {
padding: 15px !important;
}
.form-field > div:first-child {
flex: 1 !important;
}
.form-field > div:nth-child(2) {
flex: 3 !important;
}
.form-field {
flex-direction: row;
}
input.ng-valid:not(.ng-untouched) {
border: 1px solid #42A948; /* green */
}
input.ng-invalid:not(.ng-untouched) {
border: 1px solid #a94442; /* red */
}
input[disabled] {
background-color: #ffffff;
}
.border-less-textbox {
padding: 8px 10px;
font-size: 105%;
border: none;
width: 100%;
}
.orders-list {
flex-direction: row;
}
.stocks-list {
flex-direction: row;
}
.form-container {
padding: 20px;
}
.account-links {
display: inline-block;
}
}
app.component.html
<div>
Hello
</div>
CitiesAngularApp右击打开终端,执行如下命令
npm install
运行
ng serve //需要手动打开浏览器
ng serve --open //可直接打开浏览器
5、继续完善app.component.html
<div class="container">
<div class="page-content">
<div class="margin-bottom">
<div class="flex">
<div class="flex-1" id="top-bar-div">
<h2 class="app-title">
Cities Manager
</h2>
</div>
<div class="flex-1" id="search-box-div">
<div class="navbar account-links">
<ul>
<li>
<a [routerLink]="[ '/login' ]">Login</a>
<!--<a routerLink="/login">Login</a>-->
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="navbar mb">
<ul>
<li>
<a [routerLink]="[ '/cities']" [routerLinkActive]="[ 'nav-active']">Cities</a>
<!--<a routerLink="/cities" routerLinkActive="active">Cities</a>-->
</li>
</ul>
</div>
<div class="body">
<router-outlet></router-outlet>
</div>
</div>
</div>
ng serve --open运行程序后,点击Cities,显示如下
Gitee获取源码: