ksApp

使用的angularcli为1.7.3版本

ng new cloud --routing --style scss --skip-install

在package.json的"devDependencies"中增加

"@angular/cdk": "5.2.0",  // 在安装前加上这行
"date-fns": "^1.29.0", // 可以在报错的时候再行安装
npm i

安装完成后,通过npm start启动项目,查看是否运行正常!

添加antd的文件:
github中搜索ng-zorro-antd,查看releases,找到对应的版本(angular对应的antd的版本)

请注意: 由于 @angular/cli 的最新版本已经默认采用 angular 6.0 以上的版本,所以请使用 @angular/cli 1.7.4 及以下版本。
注意:antd:
1.x (支持 Angular 6.x & Ant Design 3.x) 即将放出
0.7.x (support Angular 5.x & Ant Design 3.x) 目前推荐版本
0.6.x (support Angular 5.x & Ant Design 2.x) 不再维护
我使用的是0.7.0版本的antd,下载后解压,components中就是对应的源码(我们可能会修改源码,所以放到了项目中)
放在app目录下,文件名字为ngdesign
antd最后会export一个模块:NgZorroAntdModule

注意.forRoot()

在app.module中引入该模块NgZorroAntdModule.forRoot();
重新编译
报错:
1.缺少date-fns,需要下载该依赖包
2.在ngdesign的组件中demo文件缺少ng-zorro-antd模块

npm install date-fns --save

删除demo文件(项目中没用)

npm WARN @angular/cdk@5.0.1 requires a peer of @angular/core@~5.1.0 but none is installed. You must install peer dependencies yourself.
npm WARN @angular/cdk@5.0.1 requires a peer of @angular/common@~5.1.0 but none is installed. You must install peer dependencies yourself.

===>说明cdk不能使用5.0.1的版本!(npm install 完成后需要看一下有什么需要注意的地方!!!)
ng2:https://www.cnblogs.com/RainingNight/p/getting-started-in-angular.html

修改了angular-cli.json文件,需要重新编译,要不然不会执行

在这里增加了antd的less文件,引入antd的样式

 "styles": [
    "styles.scss",
    "app/ngdesign/ng-zorro-antd.less"
  ],

其中:app开头,不用../src等

选用的cdk为5.2.0
app.module中:NgZorroAntdModule.forRoot()

在main.ts中:
if生产环境:

window.console.log=function(){};
  window.console.info=function(){};
  window.console.warn=function(){};
  window.console.error=function(){};
  window.console.debug=function(){};

这些函数不执行
在index.html中:

 <app-root></app-root>

就是app.component.ts的selector

app.routing文件:内部文件注释,改为:

export const routes: Routes = [
  {path: '', redirectTo: 'auth', pathMatch: 'full'},
  {path: '**', redirectTo: 'auth'},
];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes, {useHash: false});

app.module中引入routing(imports)

新建pages模块:
代码丢失,补上

ng g module pages --routing -d
ng g c pages --view-encapsulation None

新建auth模块:

 ng g m pages/auth --routing
ng g c pages/auth --view-encapsulation None

新建auth内部组件:

ng g c pages/auth/components/login --view-encapsulation None

新建设备管理模块:

ng g m pages/device-mgmt --routing
ng g c pages/device-mgmt --view-encapsulation None

新建device-mgmt内部组件页面:

ng g c pages/device-mgmt/components/overview --view-encapsulation None

模块不会自动加载在模块中,所以在app.module中依赖pages.module

重新routing文件,并在module中引入routing:
pages.routing:

export const routes: Routes = [
  {
    path: 'auth',
    loadChildren: 'app/pages/auth/auth.module#AuthModule'
  },
  {
    path: 'pages',
    component: PagesComponent,
    children: [
      {path: '', redirectTo: 'device-mgmt', pathMatch: 'full'},
      {
        path: 'device-mgmt',
        loadChildren: 'app/pages/device-mgmt/device-mgmt.module#DeviceMgmtModule'
      }
    ]
  }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);

auth.routing:

export const routes: Routes = [
  {
    path: '',
    component: AuthComponent,
    children: [
      {path: '', redirectTo: 'login', pathMatch: 'full'},
      {path: 'login', component: LoginComponent}
    ]
  }
];
export const routing: ModuleWithProviders = RouterModule.forChild(routes);

device-mgmt.routing:

export const routes: Routes = [
  {
    path: '',
    component: DeviceMgmtComponent,
    children: [
      {path: '', redirectTo: 'overview', pathMatch: 'full'},
      {path: 'overview', component: OverviewComponent}
    ]
  }
];

export const routing: ModuleWithProviders = RouterModule.forChild(routes);

重写html文件:
app.html,pages.html,auth.html,device-mgmt.html:

<router-outlet></router-outlet>

注意:错误提示:Error: Component AuthComponent is not part of any NgModule or the module has not been imported into your module.
我的错误是因为:我本地有两个项目,在加载模块的时候,默认加载的是另外一个项目的路径!应该加载自己本项目的文件的路径!
eg:

import {PagesComponent} from "./pages.component";  // 正确的
// import {PagesComponent} from "../../../../cloud/src/app/pages/pages.component"; // 错误的

安装jquery和bootstrap(实际上我们只用bs就够了)
安装bootstrap地址

npm install bootstrap --save
npm install @types/bootstrap --save-dev

安装normalize.css

npm install --save normalize.css

styles.scss中:

@import "../node_modules/normalize.css/normalize.css";
@import "../node_modules/bootstrap/scss/bootstrap.scss";

angular-cli.json中styles:

     "app/theme/theme.scss",
        "styles.scss",
        "app/ngdesign/ng-zorro-antd.less"

注意错误分析:

[WDS] Errors while compiling. Reload prevented.
Cannot read property ‘replace’ of null
或者:
ERROR Error: Uncaught (in promise): TypeError: webpack_require.e is not a function
TypeError: webpack_require.e is not a function
at webpackAsyncContext (eval at ./src/$$_lazy_route_resource lazy recursive (main.bundle.js:13), :15:29)
路由写错字了,改正确后需要重新编译,要不然就是第二种错误!!!!

login页面中:外盒子auto,内盒子hidden

.login-container {
  width: 100%;
  height: 100%;
  min-height: 700px;
  overflow: auto;
  .login{
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #F2FBFF;
    position: relative;

footer用fixed就可以了!

把form表单复制进来,需要导入formModule的
app.module

 BrowserAnimationsModule,
    BrowserModule,
    HttpModule,
    RouterModule,
    FormsModule,
    ReactiveFormsModule,
    NgaModule.forRoot(),
    NgZorroAntdModule.forRoot({extraFontName:'anticon',extraFontUrl:'../assets/iconfont/iconfont'}),
    PagesModule,
    routing

auth.module,device-mgmt.module:

 CommonModule,
    FormsModule,
    ReactiveFormsModule,
    AppTranslationModule,
    NgaModule,
    NgZorroAntdModule,
    routing

antd中form表单拿过来使用,此时需要接口了
用base.service和模块的service

environment.ts中:

export const environment = {
  production: false,
  getServer: function () {
    return '';
  }
};

new Headers();
错误:

src/app/pages/base-service.ts(26,42): error TS2345: Argument of type ‘{ search: any; headers: Headers; }’ is not assignable to parameter of type ‘RequestOptionsArgs’.
import { Headers} from ‘@angular/http’; // 增加这个!

错误提示:

ERROR Error: StaticInjectorError(AppModule)[AuthService -> HttpClient]:
StaticInjectorError(Platform: core)[AuthService -> HttpClient]:
NullInjectorError: No provider for HttpClient!

因为:在baseService中使用了HttpClient,所以需要在app.module中用:HttpClientModule

新建了base-service和auth.service的文件

需要代理:增加:proxy.json文件

 {
     "/auth": {
        "target": "http://xxxxxxx.com",
        "secure": false,
        "changeOrigin": true,
        "pathRewrite": {
            "^/auth": "/auth"
        }
    }
 }

package.json中:修改:

  "start": "ng serve --proxy-config proxy.conf.json",

字体图标没有生效,如何配置????

成功res返回数据结构:
res对象格式:
其中:
headers:是let myHeader: Headers = new Headers();这种格式,在使用headers.toJSON()后,是map格式!

只能使用toJSON()方法!JSON.parse()或者.json()是错误的!!!!

headers:Headers {_headers: Map(13), _normalizedNames: Map(13)}
ok:true
status:200
statusText:"OK"
type:2
url:"http://localhost:4200/auth/verify-token"
_body:"{↵  "transit" : false↵}"

其中:_headers:

_headers
:
Map(13) {"pragma" => Array(1), "date" => Array(1), "x-content-type-options" => Array(1), "server" => Array(1), "x-powered-by" => Array(1), …}

map对象格式

在项目中使用base64:
方法1:
base64的使用方法
方法2:
app/widget/script下,放入base64.js

import '../widget/script/base64.js';
declare var Base64: any;

new Base64().encode('dankogai'); //使用: 

3des的使用:

 npm i crypto-js    // 安装
 import * as CryptoJS from 'crypto-js';   // 使用

使用AppCommon:
widget/script/sessionStorage.ts

export class session{
    static set(key:string, value:any) {
        sessionStorage.setItem(key, JSON.stringify(value));
    }
    static get(key:string) {
        var d = sessionStorage.getItem(key);
        if (!d) return d;
        return !!d?JSON.parse(d):"";
    }

    static remove(key:string) {
        sessionStorage.removeItem(key);
    }

    static clear() {
        sessionStorage.clear();
    } 
    //如果设置为length,转为js时会报错
    static count(){
        return sessionStorage.length;
    } 

}

app-common.ts

import { session } from '../widget/script/sessionStorage';
export class AppCommon{
   // 租户
    private static _tenants;
   // 获取租户信息
    static get tenants() {
        if (!this._tenants) {
            this._tenants = session.get("_tenants");
        }
        return this._tenants
    }
    // 设置租户信息
    static set tenants(value) {
        this._tenants = value;
        session.set("_tenants", value);
    }
}

在每个模块中都需要引入antd!

登录成功后调用一系列接口,同时在session中存储信息

菜单部分:
html写死数据是么有问题的,但是菜单单独出来后,在收回状态时有问题的!
菜单一级和二级的问题解决了:

<div>
    <ul nz-menu [nzTheme]="'dark'" [nzMode]="'inline'"
        [nzInlineCollapsed]="isCollapsed">
      <div *ngFor="let item1 of menus">
        <li *ngIf="item1.isLeaf=='0'" nz-submenu>
          <span title>
              <i
                class="anticon {{item1.iconClass}}"></i>
              <span>{{item1.nameCn}}</span>
          </span>
          <ul>
            <li nz-menu-item *ngFor="let item2 of item1.children"
                [routerLink]="[item2.url]"
                routerLinkActive="active">
              {{item2.nameCn}}
            </li>
          </ul>
        </li>
        <li *ngIf="item1.isLeaf!='0'" nz-menu-item
            [routerLink]="[item1.url]"
            routerLinkActive="active">
          <span title>
            <i class="anticon {{item1.iconClass}}"></i>
            <span>{{item1.nameCn}}</span>
          </span>
        </li>
      </div>
    </ul>
</div>

在li外面套一层div,循环,那么nz-submenu或者nz-menu-item可以使用了!
ts:

public menus = [
      {
        isLeaf: '0',
        level: 1,
        nameCn: '设备1',
        iconClass: 'anticon-api',
        children: [
          {
            isLeaf: '1',
            level: 2,
            nameCn: '概览',
            url: '/pages/device-mgmt/overview'
          },
          {
            isLeaf: '1',
            level: 2,
            nameCn: '趋势',
            url: '/pages/device-mgmt/trend'
          },
          {
            isLeaf: '1',
            level: 2,
            nameCn: '日志',
            url: '/pages/device-mgmt/log'
          },
        ]
      },
       {
        isLeaf: '0',
        level: 1,
        nameCn: '团队',
        iconClass: 'anticon-usergroup-delete',
        children: [
          {
            isLeaf: '1',
            level: 2,
            nameCn: '团队1',
            url: '/pages/device-mgmt/team1'
          },
          {
            isLeaf: '0',
            level: 2,
            nameCn: '团队2',
            iconClass: 'anticon-user',
            url: '/pages/device-mgmt/team2',
            /*children: [
              {
                isLeaf: '1',
                level: 3,
                nameCn: '团队2-a',
                url: '/pages/device-mgmt/team2-a'
              },
              {
                isLeaf: '1',
                level: 3,
                nameCn: '团队2-b',
                url: '/pages/device-mgmt/team2-b'
              }
            ]*/
          }
        ]
      },
       {
        aliasName: '用户',
        isLeaf: '1',
        level: 1,
        nameCn: '用户',
        iconClass: 'anticon-android-o',
        url: '/pages/device-mgmt/user'
      }

    ];

菜单没有正常显示样式问题分析:
1.是否折叠别用nzTrigger了,自己用isCollapsed来传递!
2.上面我用了div包裹了一层,所以默认样式中用子类选择器无效,修改源码:
在:src/app/ngdesign/menu/style/index.less

 &-inline-collapsed {
    width: @menu-collapsed-width;
    > .@{menu-prefix-cls}-item,
    > .@{menu-prefix-cls}-item-group > .@{menu-prefix-cls}-item-group-list > .@{menu-prefix-cls}-item,
    > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title {

这些子类选择器修改为后代选择器!
3.修改菜单的w:
在src/app/ngdesign/style/themes/default.less中:

@menu-collapsed-width: 64px; // 折叠后菜单的w,自动可以居中,计算css值了的

且需要:
src/app/ngdesign/layout/nz-sider.component.ts

  @Input() nzWidth = 200;
  @Input() nzCollapsedWidth = 80;   // 修改值

左上角图片:
.logo:overflow:hidden,要不然图片会换行!

[ngClass]="{'marginleft5':isCollapsed}"  // 要不然折叠时候,小图片没有居中

最终:pages.html:

<div class="page-container">
  <nz-layout style="height: 100%;">
    <!--左边栏-菜单-->
    <nz-sider nzCollapsible [(nzCollapsed)]="isCollapsed"
               [nzTrigger]="null" >
      <div class="logo">
        <img [ngClass]="{'marginleft15':isCollapsed}" src="../../assets/images/basic/xxx.png" alt=""><img *ngIf="!isCollapsed" src="../../assets/images/basic/xxx.png" alt="">
      </div>
      <app-ks-page-menu [isCollapsed]="isCollapsed"></app-ks-page-menu>
    </nz-sider>
    <!--右侧部分-->
    <nz-layout style="height: 100%;">
      <!--折叠按钮-->
      <nz-header style="background: #fff; padding:0;">
        <i class="anticon trigger" [class.anticon-menu-fold]="!isCollapsed"
           [class.anticon-menu-unfold]="isCollapsed"
           (click)="collapseFuc();"></i>
             </nz-header>
      <nz-content style="margin:0 16px;height: calc(100% - 133px);">
        <nz-breadcrumb style="margin:16px 0;">
          <nz-breadcrumb-item>User</nz-breadcrumb-item>
          <nz-breadcrumb-item>Bill</nz-breadcrumb-item>
        </nz-breadcrumb>
        <div style="padding:24px; background: #fff; min-height: 360px;height: 100%;">
          <router-outlet></router-outlet>
        </div>
      </nz-content>
      <nz-footer style="text-align: center;">Ant Design ©2017 Implement By Angular
      </nz-footer>
    </nz-layout>
  </nz-layout>
</div>

pages.scss

.page-container {
  height: 100%;
  // 菜单折叠按钮 样式
  .trigger {
    font-size: 28px;
    line-height: 64px;
    padding: 0 24px;
    cursor: pointer;
    transition: color .3s;
  }
  .trigger:hover {
    color: #1890ff;
  }

  .logo {
    height: 64px;
    overflow: hidden;
    margin-top: 7px;
    .marginleft15 {
      margin-left: 15px;
    }
  }
}

page-menu.html:

<ul nz-menu [nzTheme]="'dark'" [nzMode]="'inline'"
    [nzInlineCollapsed]="isCollapsed">
  <div *ngFor="let item1 of menus">
    <li *ngIf="item1.isLeaf=='0'" nz-submenu>
          <span title>
              <i
                class="anticon {{item1.iconClass}}"></i>
              <span>{{item1.nameCn}}</span>
          </span>
      <ul>
        <li nz-menu-item *ngFor="let item2 of item1.children"
            [routerLink]="[item2.url]"
            routerLinkActive="active">
          {{item2.nameCn}}
        </li>
      </ul>
    </li>
    <li *ngIf="item1.isLeaf!='0'" nz-menu-item
        [routerLink]="[item1.url]"
        routerLinkActive="active">
          <span title>
            <i class="anticon {{item1.iconClass}}"></i>
            <span>{{item1.nameCn}}</span>
          </span>
    </li>
  </div>
</ul>

html默认字体14px,不是我们想要的:
src/app/ngdesign/style/themes/default.less

@font-size-base         : 14px; // 修改!

在page中:
padding和margin去掉,我们在自己的 页面要写面包屑的!

pages.html:

<div class="page-container">
  <nz-layout style="height: 100%;overflow: hidden;">
    <!--左边栏-菜单-->
    <nz-sider nzCollapsible [(nzCollapsed)]="isCollapsed"
               [nzTrigger]="null" >
      <div class="logo">
        <img [ngClass]="{'marginleft15':isCollapsed}" src="../../assets/images/basic/new-logo-close.png" alt=""><img *ngIf="!isCollapsed" src="../../assets/images/basic/new-logo-open.png" alt="">
      </div>
      <app-ks-page-menu [isCollapsed]="isCollapsed"></app-ks-page-menu>
    </nz-sider>
    <!--右侧部分-->
    <nz-layout style="height: 100%;overflow: hidden;">
    <!--折叠按钮-->
      <nz-header style="background: #fff; padding:0;border-bottom: 1px solid #D8D8D8;  ">
        <i class="anticon trigger" [class.anticon-menu-fold]="!isCollapsed"
           [class.anticon-menu-unfold]="isCollapsed"
           (click)="collapseFuc();"></i>
      </nz-header>
      <nz-content style="margin:0;height: 100%;overflow-y: auto;">
        <div style="height: 100%;">
          <router-outlet></router-outlet>
        </div>
      </nz-content>
      <nz-footer style="text-align: center;z-index: 1;">Ant Design ©2017 Implement By Angular
      </nz-footer>
    </nz-layout>
  </nz-layout>
</div>

pages.scss:

.page-container {
  height: 100%;
  // 菜单折叠按钮 样式
  .trigger {
    font-size: 28px;
    line-height: 64px;
    padding: 0 24px;
    cursor: pointer;
    transition: color .3s;
  }
  .trigger:hover {
    color: #1890ff;
  }

  .logo {
    height: 64px;
    overflow: hidden;
    margin-top: 7px;
    .marginleft15 {
      margin-left: 15px;
    }
  }
}

overview.html:

<div class="overview-container">
  <div class="overview">

    <!----------面包屑 开始------------>
    <nz-breadcrumb>
      <nz-breadcrumb-item>
        一级菜单
      </nz-breadcrumb-item>
      <nz-breadcrumb-item>
        <a>二级菜单</a>
      </nz-breadcrumb-item>
    </nz-breadcrumb>
    <!-----------面包屑 结束------------>

    <div class="content-box">
      <div class="search-container">
        <div nz-row>
          <div nz-col [nzSpan]="6">
            <div nz-row class="ks-item">
              <div nz-col [nzSpan]="8" class="ks-label">
                label标签:
              </div>
              <div nz-col [nzSpan]="16" class="ks-form">
                <nz-select style="width: 100%;"></nz-select>
              </div>
            </div>
          </div>
           <div nz-col [nzSpan]="6">
            <div nz-row class="ks-item">
              <div nz-col [nzSpan]="8" class="ks-label">
                label标签2:
              </div>
              <div nz-col [nzSpan]="16" class="ks-form">
                <!--<nz-input [(ngModel)]="abc" placeholder="'请输入'"></nz-input>-->
                <input [(ngModel)]="abc" placeholder="请输入" nz-input>
              </div>
            </div>
          </div>
          <!--查询和重置-->
          <div nz-col [nzSpan]="6">
            <div nz-row class="ks-item">
              <button nz-button [nzType]="'primary'" class="search-btn"
                      (click)="search(true);">
                <span>搜索</span>
              </button>
              <button nz-button [nzType]="'default'" class="reset-btn"
                      (click)="reset();">
                <span>重置</span>
              </button>
            </div>

          </div>
        </div>
      </div>
      <div class="table-container">
        <nz-table #basicTable [nzData]="dataSet">
          <thead>
          <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Address</th>
            <th>Action</th>
          </tr>
          </thead>
          <tbody>
          <tr *ngFor="let data of basicTable.data">
            <td>{{data.name}}</td>
            <td>{{data.age}}</td>
            <td>{{data.address}}</td>
            <td>
              <a>Action 一 {{data.name}}</a>
              <nz-divider nzType="vertical"></nz-divider>
              <a>Delete</a>
            </td>
          </tr>
          </tbody>
        </nz-table>
      </div>
    </div>
  </div>
</div>

overview.scss:

.overview-container{
  width: 100%;
  height: 100%;
  .overview{
    width: 100%;
    height: 100%;
    .ant-breadcrumb {
      height: 40px;
      line-height: 40px;
      background: #fff;
      padding-left: 20px;
      // 面包屑的每一项
      .ant-breadcrumb-link {
        color: blue;
      }
      // 面包屑的“/”分隔符
      .ant-breadcrumb-separator {
        color: blue;
      }
      // 最后一项 item里面的 改变样式,注意自己调试的样式bug问题
      //.ant-breadcrumb-link:last-of-type{
      nz-breadcrumb-item:last-child {
        // 在获取到标签,再取里面的类
        .ant-breadcrumb-link {
          font-weight: normal;
          color: red;
        }
      }
    }
    .content-box{
      padding: 20px;
      .search-container{
        padding: 20px 20px 0 0;
        background: #fff;
        // 多选select的h,多了后滚动
        .ant-select-selection--multiple {
          height: 32px;
          overflow: auto;
        }
        .ks-item {
          margin-bottom: 20px;
          .ks-label {
            height: 32px; // 行高32px
            line-height: 32px;
            text-align: right;
            font-size: 12px;
            color: rgba(0, 0, 0, 0.85);
          }
          .ks-form {
            .ant-input { // input的样式设置
              height: 32px;
            }
            .ant-select-selection__rendered { // 多选select的样式
              height: 30px;
              line-height: 30px;

            }
            .ant-select-selection--multiple > ul > li, // 多选select的样式
            .ant-select-selection--multiple .ant-select-selection__rendered > ul > li {
              height: 24px;
              line-height: 24px;

            }
            .ant-select-selection--single { // 单选 select的样式
              height: 32px;
            }
          }
        }
        .search-btn { // 搜索按钮
          width: 67px;
          height: 30px;
          margin-top: 1px;
          margin-left: 15px;
        }
        .reset-btn { // 重置按钮
          width: 67px;
          height: 30px;
          margin-top: 1px;
          margin-left: 5px;
        }
      }
       .table-container{
        margin-top: 8px;
        padding: 0 20px 20px;
        background: #fff;
        color: #222;
      }
    }

  }
}

此时:菜单还没有滚动条:
给菜单的url加上:

    height: calc(100% - 64px);
    overflow: auto;

style.scss:

// 左右中的对齐方式
.tac {
  text-align: center;
}

.tal {
  text-align: left;
}

.tar {
  text-align: right;
}

// cursorpointer的样式
.cursor-pointer {
  cursor: pointer;
}

// textarea不可以缩放
textarea {
  resize: none;
}
// form表单:必填项的*的颜色
.color-require {
  font-size: 14px;
  color: rgba(255, 0, 0, 0.85);
  vertical-align: middle;
}

:focus {
  outline: none;
}
.hyper-link {
  cursor: pointer;
  color: #2D9AFF;
}

.hyper-link:hover {
  color: #0973D6;
}
// "..."的样式,用类表示; 配合w来使用=》可以使用百分比
.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

猜你喜欢

转载自blog.csdn.net/weixin_42995876/article/details/82389257
SPP
今日推荐