• Angular


    https://cloud.tencent.com/developer/devdocs

    1.设计原则
    (1)YAGNI
    You Aren't Gonna Need It,你不会需要它;不写不需要的功能

    (2)KISS
    Keep It Simple and Stupid,让你的代码越简单/傻瓜越好
    (3)OCP
    Open Close Principle,开闭原则,对外界修改封闭(不允许修改已有代码),对外界的扩展开放

    (4)High Cohesion, Low Coupling

    高聚合,低耦合;功能相关代码紧密在一起;功能不相干代码拆分越明确越好

    (5)迪米特法则/最少知识原则
    一个对象/组件,数据/操作越少越好

     Angular

    Angular由Google在2009年创建的MVVM框架,适用于中大型的企业级SPA应用。

    V1.x官网: https://angularjs.org/
    Angularjs用JS编写
    V2.x~8.x官网: https://angular.io/ Angular 用TS编写
    V2.x~8.x中文网: https://angular.cn/
    提示: V1到V2的升级变化非常大!
    注意: Angular 8.x要求Node.js版本必须是10.9以上!

    3.创建第一个 Angular项目
    ①安装Node.js和NPM
    Node.js版本必须>=10.9
    ②安装全局的Angular脚手架工具
    npm i  -g  @angular/cli

    提示:如果使用NPM从官方网站下载NPM包总是失败,可以把默
    认下载地址改为国内淘宝网镜像:
    查看当前下载地址:
    npm config get registry
    默认值为: https://registry.npmjs.org/

    修改为淘宝网NPM镜像:
    npm  config  set  registry= https://registry.npm.taobao.org/

    默认会在C:UserswebAppDataRoaming pm目录下安装ng.cmd可执行文件及其相关文件
    ③运行全局脚手架,创建一个 Angular空白项目

      ng new myngapp01

    此步需要联网从NPM官网下载第三方模块

    Would you like to add Angular routing? y

    Which stylesheet format would you like to use? (Use arrow keys)
    > CSS
    SCSS [ https://sass-lang.com/documentation/syntax#scss ]
    Sass [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]
    Less [ http://lesscss.org ]
    Stylus [ http://stylus-lang.com ]

    ④进入项目根目录,运行该项目(Node.js 项目)
    npm  start 或者 ng  serve

    Vue,js项目的主配置文件:    vue.config.js
    Angular项目的主配置文件:  angular.json

    ES6中有"模块”的概念: export/export default、import.from..
    Vue.js中无自己的"模块”概念一项目是由自定 义组件构成;
    Angular中有自己的"模块”概念一项目是由自定义组件构成, 每个组件都要放在一个特定的module中,

    4.Angular项目引导启动流程
    ①系统运行main.ts
    ②main.ts启动主模块AppModule
    ③在主模块中引导启动主组件AppComponent

    ④主组件中声明了模板和样式,最终渲染在index.html中<app-root/>

    (2)Angular核心概念之一 一一组件
    可以复用的页面片段,
    Component = Script + Template + Style.
    Angular中的组件是多文件组件: .ts + .html + .css/.scss
    注意:组件必须在某个模块(AppModule)中声明!

     使用快捷命令创建:
    ng g  component  组件名

    (3)Angular核心概念之二———数据绑定
    ①innerHTML绑定: {{ }}
    ②属性绑定: [ attr ] =""                 (区分vue  v-bind  / :)

    ③事件绑定: ( click)= "fn( )"             (区分vue   v-on /@)
    ④循环绑定: *ngFor                            (区分vue   v-for)
    ⑤选择绑定: *nglf  (提示: *nglf 会影响DOM结构)

    ⑥选择绑定: [ngSwitch] *ingSwitchCase  *ngSwitchDefault
    ⑦样式绑定: [ngStyle]   [ngClass]

    ⑧样式绑定指令: [ngClass]
    ⑨双向数据绑定指令:

    Angular中指令分为哪几类:

    (1)组件指令
    <myc01> </myc01>
    Component extends Directive, 组件继承自指令,组件是有模板的指令
    (2)结构型指令
    可以影响当前的DOM结构的指令;所有结构型指令都以*开头
    (3)属性型指令

    不会影响DOM结构,只会影响当前元素的特征,如样式;所有的属性型指令都用[]括起来!

    1.Angular核心概念之三一指令(Directive)
    指令:是一种特殊的模板页面内容,可以对页面执行特殊的处理;
    例如:< any*ngFor="">
    Angular中常见指令:
    ①循环绑定指令: *ngFor
    <any *ngFor="let tmp of 集合对象">


    ②选择绑定指令: *ngIf
    <any *nglf= " expression" >
    提示: *nglf 会影响DOM结构


    ③选择绑定指令: [ngSwitch] *ngSwitchCase *ngSwitchDefault
    <any [ngSwitch]= "变量名">
    <any *ngSwitchCase= "值"> ... </any>

    ...

    < any"ngSwitchDefault> ... </any>

    </any>

    ④样式绑定指令: [ngStyle]
    <any [ngStyle]= "obj">

    ⑤样式绑定指令: [ngClass]
    <any [ngClass]="obj">

    2.(了解)如何自定义指令
    可使用工具ng  g  directive 指令名      快速的创建一个指令

    < div  appNeedStrong> ... </div>

    @Directive({ selector: 'appNeedStrong' })
    export class MyDirective {
    contructor( el: ElementRef){
    el.nativeElemet.xxx.....
      }
    }

    3.Angular中的双向数据绑定
    方向1: Model=>View
    方向2: View=>Model
    Angular中实现双向数据绑定的方法:
    <input   [(ngModel)]="userName">

    提示: ngModel指令处于FormsModule,必须在当前模块中声明导
    入才能使用:

    import { FormsModule } from '@angular/forms';
    @NgModule({
    imports: [ FormsModule ]
    })

    如果想监视模型数据的改变(就像Vue.js 中的watch函数),可以使用
    ngModelChange事件:

    <input  [(ngModel)]= "userName"  (ngModelChange)="fn()">

    示例:创建密码输入框,随着用户的输入,后面的提示信息不停的在改变:

    "密码不能为空"
    "密码长度不能少于6位"
    "密码长度合法"
    "密码长度不能超过12位"

    使用Angular实现TodoList

    4.Angular核心概念之四---管道
    Vue.js中的过滤器(filter): <p>{{1| sex('zh'}}</p>
    Angular中的类似的概念称为管道(pipe): <p>{{1 |sex:zh' }}</p>
    Vue.js没有内置任何过滤器;但Angular内置了很多好用的管道:
    ①lowercase:把数据转换为小写形式

    ②uppercase:把数据转换为大写形式
    ③slice:获取字符串或数组中的一部分
    ④json:把对象转换为JSON字符串
    ⑤date:把日期/数字转换为特定格式的日期字符串
    ⑥number:数字格式化(每E位加逗号,并指定小数位数)
    ⑦currency:把数字以货币形式显示

    TypeScript语法知识:

    (1)class中的成员(属性、方法)、参数的参数都可以声明类型:
      class Book{
      price: number = 12.5
      add(n:number): void{ }
        }

    (2)TS中的新类型:接口(interface)
    接口是一种特殊的class,用于规定一个对象“必须具备”哪些功能
    interface Runnable{

        run( );
        stop( );
      }
    class Car implements Runnable{
      run( ){...}
    stop( ){...}
    }

     

    1.自定义管道:


    工具命令:
    ng  g  pipe
    管道名
    @Pipe({
    name: 'sex'
    })
    class SexPipe {
    transform(val, args){
    return ...;
    }
    }

    示例:创建一个管道: zzmm,可以把数字1/2/3分别转换为"党员/中共党员”、”团员/中国共青团团员”和"群众/中国人民群众”

    2.(重点/难点)父子组件间的数据传递
    ng g  component  parent
    ng g  component   child
     

    (1)父组件给子组件传递数据:父=>子-Props Down

    (1.1)子组件声明自己专有的属性

    @Input()     //Input装饰器把下面的属性变为“输入型属性”
    userName: string;
    (1.2)父组件使用子组件的专有属性赋值一值为父组件的模型数据
    <app-child [userName]="myName">

    -----------------------------------------------------------------------

    parent.component.html:

    <h1>这里是父组件</h1>
    <app-child [uname]=" parentName' > </app-child>


    parent.component.ts:

    parentName: '父亲的名称'

    child.component.ts:
    @Input( )
    private uname: string

    -----------------------------------------------------------------------


    (2)子组件给父组件传递数据:子=>父 一Events Up

    (2.1)子组件声明并触发事件,触发时携带自己的数据

    @Output()
    unameEvent = new EventEmitter();
    ...
    this.unameEvent.emit(data);


    (2.2)父组件监听子组件的事件,并提供处理函数接收事件数据

    < app-child (unameEvent)= "doEvent($event)" >
    ....
    doEvent( data ){...}

    ---------------------------------------------------------------------

    parent.component.html:
    <h1>这里是父组件</h1>
    <app-child (childEvent)= "doChildEvent($event)"> </app-child>
    parent.component.ts:
    doChildEvent( data){ .. }

    child.component.ts:
    private childName: string = '孩子的名称'
    @(Ouput)
    private childEvent = new EventEmitter()
    doClick(){
    this.childEvent.emit( this.childName )
    }

     

    3.服务和依赖注入
    Angular认为:
    Component:组件,仅应该只负责视图,只参与展示;与展示无关的语句都应该剥离出去;例如:做日志、计时、网络数据访问
    Service:服务,就是一个简单的对象,负责执行从组件中剥离的与视图无关的操作,例如:做日志、计时、网络访...
    创建服务:
    ng  generate  service  服务名

    inject:打针,注入
    injectable:能被注入给别人的

    Angular创建对象的两种方式:
    (1)手工创建
    var logger = new LoggerService();
    logger.log("用户增加了一个商品);

    (2)依赖注入(Dependency Injection)
    logger = null;
    constructor(logger:LoggerService){
    this.logger = logger
    }

    在构造方法中声明需要依赖某个对象,且该对象是”可以被注入的
    (@Injectable)" ,那么Angular就会自动创建依赖的对象,并注入给
    当前构造方法

     TypeScript知识点一 强类型语言:

    1.类型声明:
    class Book{
    price: number = 1.5
    author: any = 'Tom'
    }

    work( tool: number[] ): void{
    }

    2.接口:是一种特殊的class,用于规定一个class必须提供特定的方法
    interface Runnable{
    run()
    stop()
    }
    class Car implements Runnable{

    run(){}

    stop(){}

    }

    3.类成员(属性/方法)的访问修饰符

    ①private: 私有成员,只能在当前类内部使用; class中的属性一般都应该声明为私有的或被保护的!
    ②protected:被保护的,只能在当前类内部以及子类中使用
    ③public:默认值!公共成员,可以被任何类使用; class中的方法一般声明为公共的!

    4.类属性的声明/赋值方式
    class Book{
    private price:number =0

    public constructor( price: number ){
    this.price = price
    }
    }

    上面的代码可以简写为:
    class Book{
    //构造方法中的形参前加private/ protected/public此形参
    自动变为一个同名属性,且自动赋值
    public constructor( private price: number ){
        }
      }
    var book1 = new Book( 100 )

     

    1.Angular核心概念之六————服务和DI(依赖注入)

    Component:负责视图的数据绑定/事件处理
    Service:负责从组件中剥离的与视图无关的任务,如日志计时、网络访问...

    注意: Angular 中的依赖注入是基于构造方法的参数类型,而与先后顺序无关

    创建服务:
    @lnjectable( {
    //可以被注入给某个组件
    //Injector/Provider:注入器/服务提供者,负责创建服务对象
    并注入给组件, Angular 会自动为每个服务创建必需的注入器
    })
    export class LoggerService{

    }

    问题: Angular 中的Service可以在哪里被提供/Service的提供者/注入器有哪些?
    方式1:声明服务时提供——根模块中提供的服务对象是整个应用中 “ 单例的"(logger.service.ts中)
    @lnjectable({ 
      providedIn: 'root'
    })
    export class LoagerService{ }

    万式2:在模块中提供----在当期模块中的所有组件共用同一 个服务对象(app module.ts中)

    @Injectable()
    @NgModule({
    providers: [ LoggerService
    })

    方式3:在组件声明中提供----该服务仅能作用于当前组件(组件的ts文件中)
    @Component({
    selector: 'app-myc01',
    template:'',
    providers: [ LoggerService ]
    }) 

     

    问题:前端技术中有哪些异步请求方案?
    (1)原生XHR:
    (2)jQuery封装: $.ajax( )    基于回调函数= >回调地狱
    (3)Axios:底层还是XHR,基于Promise,可以避免回调地狱
    (4)Angular HttpClient服务:底层还是XHR 基于Observable
    (5)ES2016新方案: Fetch: 底层不是XHR!就是fetch对象!   不支持请求打断、请求排队

    由W3C提供的XHR的替代方案,采用Promise

     

    2.Angular中异步请求服务器端数据
    HTTPClient Service:是Angular官方提供的异步请求工具
    使用步骤:
    (1)在主模块中引入HTTPClientModule-会提供 HttpClient服务的注入器
    @NgModule({

    imports: [ HttpClientModule ]
    })
    (2)在需要使用异步请求模块中声明依赖HttpClient服务
    constructor(private http: HttpClient){}

    (3)调用HttpClient提供的异步数据请求服务
    this.http.get( )
    this.http.post( )
    this.http.put( )
    this.http.delete( )

    3. Rx.js和Observable对象
    Angular中HttpClient服务底层基于Rx.js 第三方模块
    官方: RxJS是Reactive Extensions for JavaScript 的缩写,是一
    个基于可观测数据流在异步编程应用库。RxJS是Reactive
    Extensions在JavaScript.上的实现。-般说到RxJS,都会讲他是基
    于流的响应式的结合观察者和迭代器模式的一种库
    Observer模式(也称为“订阅-发布”模式):

    乙方声明“订阅(subscribe)" 甲方;
    在未来的某个不确定时间,甲方"发布(publish)" 新消息,乙方会立即接到通知

    HttpClient服务采用了“观察者/订阅-发布模式" ,其最核心对象为: 
    let obj=new Observable( ); //可被观察的对象
    //可以关注/订阅“可被观察的”对象
    pbj.subscribe( ( )=>{ //收到订阅消息时的回调函数} )

     示例:创建组件: ProductList,点击“加载更多”则异步请求更多数据,呈现在表格中,
     4.Angular中组件的声明周期钩子函数

    Hooks Function:声明好的特定的函数,到了指定的时间点,就会被自动执行
    LifeCycle Hooks Function:在组件的不同生命阶段会自动执行的函数

    面试题: Angular中组件的生命周期钩子函数按顺序有:
    (0)constructor( ):构造方法执行且仅执行一次
    (1)ngOnChanges( ):组件的输入属性值发生赋值或改变
    (2)ngOnInit():组件正在初始化,执行且仅执行一次

    (3)ngDoCheck( ):组件正在执行变化检查

    (4)ngAfterContentlnit( ):组件内容初始化之后
    (5)ngAfterContentChecked():组件内容被重新检查后
    (6)ngAfterViewInit( ):组件视图初始化之后
    (7)ngAfterViewChecked):组件视图被重新检查后

    (8)ngOnDestroy( ):组件即将从DOM树上销毁,用于释放定时器、取消订阅...执行且仅执行一次 

     

    5.Angular核心概念之七一路由和 SPA应用
    Single Page Application,单页应用----整个应用中只有一个完整的HTML页面,其它所有的“页面”

    SPA应用的优点:
    (1)DOM树只需要创建一次,"页面切换”只是在切换部分元素
    (2)便于实现“过场动画”一多页应用不可能做到
    SPA应用的不足:

    (1)不便于实现SEO优化

    SPA应用的核心----路由词典(把一个地址和一个组件一 一对应起来):

    [
    { path: 'index',component: ...
    { path: 'produlct/list',component: ...
    { path: 'user/login', component: ...
    ]
    SPA应用的原理:框架根据客户端请求的路由地址,异步加载对应的组件内容,替换之前的组件内容


    使用Angular中的路由步骤:
    (0)提前准备好路由组件

    ng g component index

    ng g component productList

    ng g component productDetail


    (

    (1)在根模块中创建路由词典
    var  routes = [ {path:", component: ... }]
    (2)在根模块引入路由模块,注册路由词典
    @NgModule({
    import: [ RouterModule.forRoot(routes) ]
    })

    (3)在根模块的模板中声明路由组件的占位符

    <router-outlet></router-outlet>

    (4)让客户端请求路由地址

    http://127.0.0.1:4200/product/list

     示例:

    1)创建如下四个组件: ng g component index

              ng g component productList

              ng g component productDetail

    ng g component userCenter


    2)创建路由词典,为每个组件分配访问路径


    index    =>        index
    productList   =>        product/list

    productDetail =>  product/detail
    userCenter     =>  user/center

    let routes=[{path:'',component:...},...]

    3)在根模块中注册路由词典

    RouterModule.forRoot(routes);
    4)在根组件中声明路由出口

    app.component.html:  <router-outlet></router-outlet>
    5)使用客户端访问每个路由地址,测试路由功能实现

    http://127.0.0.1:4200/user/center

     

     

    1.路由词典的配置

    let routes=[
      {path:'',component:IndexComponent},
      {path:'index',component:IndexComponent},
      {path:'product/list',component:ProductListComponent},
      {path:'product/detail',component:ProductDetailComponent},
      {path:'user/center',component:UserCenterComponent},
      {path:'**',component:NotFoundComponent}

    注意:路由词典中的路由path不能以'/' 开头,但是,路由跳转时指定的路径最好都以‘/’开头

    2.路由跳转
    从一个路由地址跳转到另一个有两种方法:
    方式1:编程方式

    constructor(private router:Router){}

    ...

    this.router.navgeteByUrl('router')
    方式2:模板方式

    <any routerLink="...">
    注意:routerLink指令可以用在任何元素上,如DIV、A、BUTTON
     
     
     

    3.路由参数
    在路由的path属性中,有些部分固定不变,有些部分需要动态变化:
    { path: product/detail/20', component: .. }
    { path: product/detail/23', component: .. }
    { path: product/detail/35', component: .. }

    --------------------------------------------------------------------

    { path: product/detail/:pid', component: ... }
    路由参数:路由地址中的变量
    使用步骤:
    ①路由词典中设置路由参数: 
    path: 'product/detail/:pid',
    ②路由跳转时提供路由参数值:
    <any routerLink= " /product/detail/35">

    ③在目标组件中读取当前路由的参数
    constructor( private route: ActivatedRoute ){
    }
    ngOnInit(){
    this.route.params.subscribe( (data)=>{
      data.pid
      })
    }

     

    4.路由嵌套
    在一个路由组件内部,有部分内容固定,另一区域中的内容可以切换不同的子组件一嵌套路由
    路由词典:

    let
    routes = [
    {
    path: 'user/center',
    component: UserCenterComponent,
    children: [

    { path: 'myinfo', component: ....
    { path: 'headpic', component: ..
    { path: 'security', component: ...

       ]
      }
    ]

    路由出口:
    app.component.html: < router-outlet> </router-outlet>
    user-center.component.html:....< router-outlet> </router-outlet>...

    示例:为“用户中心”创建嵌套路由
    (0)创建必需的子组件
    ng g component myInfo
    ng g component headPic
    ng g component securityManagement

    5.路由守卫
    Guard:护卫,守护者
    有些路由地址只有在特定条件满足的情况下才允许访问,不满足的情况下禁止访问
    如是否登录、是否充值、是否满足时间段限制...
    对访问条件是否满足而进行设置,满足的话,就让访问路由组件;否则就不
    让访问一这种对象成为 “路由守卫对象”

    使用方法:
    ①创建一个路由守卫:
    @lnjectable({
    providedIn: 'root'
    })
    class Xxx {
    canActivate(){ //组件是否允许被激活

    .......
    return true / false ;
      }
    }

    }

    ②使用路由守卫

    [
    {
    path: 'user/center',
    component: UserCenterComponent,
    canActivate: [ XxxGuard ]
    children: [ ...]
    }
    ]

    创建一个路由守卫: 
    TimeCheckGuard,
    作用:如果当前时间是18:00~ 24:00,允许用户访问user/center,否则禁止访问

    移动端应用的种类:
    (1)Native App:
    原生App,指使用Java/Kotlin为Android. OC/Swift 为ios开发应用程序,直接运行与手机操作系统上
    优势:运行速度快   劣势:两套代码不跨平台,且必须下载

    (2)Web App:
    使用HTML/CSS/JS技术编写类似原生App的应用,代码运行于手机中的浏览器(如WebView)中,
    优势:无需提前下载、一套代码到处运行     劣势: 运行效率低、不能访问手机底层系统服务

    (3)Hybrid App:
    使用HTML/CSS/JS技术编写类似原生App的应用,并混入部分Java/OC等驱动代码以调用系统底层服务,最终运行于操作系统中
    优势:结合了前两种的优势

    (4)Dart/ Flutter一 代表着未来

     6.基于Angular的UI组件库

    Angular相关的组件库:
    (1)lonic
    (2)Material
    (3)Zorro
    (4)Zorro Mobile

    lonic概述: https://ionicframework.com/

    lonic是一个基于HTML/CSS/JS技术的,创建混合App的UI组件库技术。底层可以不依赖于任何框架(弓|入.css和.js就可以运行),也可以
    与Vue.js、React、 Angular 框架整合在一起,作为它们的第三方组件库使用。

    lonic CLI = Angular CLI + UIModule +移动端打包工具...

    移动端打包工具

    md: Meterial Design      Android Studio
    ios                                 XCode
    HBuilder:可以打包Android/iOs安装程序(国内)

    使用方法:

    (1)下载全局脚手架工具
    npm i  -g ionic                   

    (npm config set registry https://registry.npm.taobao.org/)


    (2)运行脚手架工具在当前目录下创建一个项目


    ionic start 项目名 blank
    ionic start 项目名 tabs
    ionic start 项目名 sidemenu

    创建好项目后会自动调用npm i 下载所依赖的第三方模块
    (3)进入项目目录,运行它
      cd  项目名
      npm start

    (4)启动客户端浏览器,访问开发服务器  用(手机)浏览器访问项目

    http://127.0.0.1:4200

    lonic的九种主题色----color:
    primary(蓝白)、secondary(青白)、tertiary(偏紫白)、danger(红白)、warn(黄白)、
    success(绿白)、dark(黑白)、 medium(灰白). light(亮色)

    2.lonic App的页面布局
    <ion-app>

    ion-header > ion-toolbar > ion-title >标题
    ion-content[padding] >内容
    ion-footer > ion-toolbar > ion-title >内容

    </ion-app>

    ------------------------------------------------------------

    lonic主体中的“栅格布局系统”一仿 Bootstrap3:
    <ion-grid>
    < ion-row>
    <ion-col  no-padding size="宽" offset="偏移" push="右推" pull="左拉"> </ion-col>
    </ion-row>
    </ion-grid>

    Module:模块
    Model:模型,MVVM中第一个M
    Modal:模态对话框

    3.lonic提供预定义组件
    Icon:图标<ion-icon name="">

    Button:按钮<ion-button>
    Badge:徽章<ion-badge>
    Card:卡片ion-card> ion-card-header + ion-card-content
    Alert:警告框,必须使用AlertController创建并呈现  

    this.alertController.create({
    }).then((d)= >{d.present()})


    Modal:模态框,必须使用ModalController创建并呈现

    this.modalController.create({
    }).then((d)= >{d.present()})

    Item:列表项

    <ion-item detail href= "#">
    <ion-avatar slot= "start"> img </ion-avatar>
    < ion-thumbnail> img </ion-thumbnail>
    <ion-label> </ion-label>
    < ion-button slot= "end">
    < /ion-item>

    卡片:< ion-card> ion-card-header + ion-card-content< /ion-card>


    List:列表

    InfiniteScroll:无穷滚动组件,滚动到底部时加载更多内容

    <ion-infinite-scroll threshold = "20px" (ionInfinite)= "loadData" >
    <ion-infinite-scroll-content
    loadingSpinner=""
    loadingText=">
    </ ion-infinite-scroll>


    Refresher:刷新器,从顶部显示加载更多内容

    搜索条: <ion-searchbar>
    滑动轮播: <ion-slides> <ion-slide> </ion-slide> </ion-slides>
    标签页: <ion-tabs> </ion-tabs>

    2.Angular & lonic阶段项目
    实现步骤:
    (1)创建空白的lonic项目模板
    (2)创建项目必需的组件

    ng g component main   盛放ion-tabs组件的页面
    ng g component index    首页(1F/2F/3F)
    ng g component  product-list  商品列表页
    ng g component  cart  购物车页
    ng g component  login  登录页

    ng g component not-found    404页
    ng g component product-detail 商品详情页

    确保每个组件都在AppModule中进行了声明: declarations:[ ]
    (3)修改根组件模板AppComponent.html,使用

    <ion-app>

    <ion-router-outlet></ion-router-outlet>

      <app-main> </app-main>

     </ion-app>

    (4)编辑main.component.html,声明页签组件
    <ion-tabs>

    <ion-tab-bar>

    <ion-tab-button>图标+文字</ion-tab-button>

    </ion-tab-bar>

    </ion-tabs>

    (5)编辑路由配置模块文件app-routing.module.ts,声明并注册路由词典
    const routes = [
    {path: ", component: IndexComponent},
    {path: 'product-list', component: ProductListComponent},

    {path: 'product-detail/:pid', component: ProductDetailComponent},

    {path: 'cart', component: CartComponent},
    {path: 'login', component: LoginComponent},
    {path: **',component: NotFoundComponent},
    ];
    此时可以使用客户端进行测试,访问页签中的每个按钮,可以在路由出口显示对应路由组件页面

    --------------------------------------------------------------------------------------------

     (6)开始修改主页组件模板: index.component.html, 添加页面内容

    <ion-header>
    img + ion-searchbar
    </ion-header>
    < ion-content>
    slides + ion-item +ion-grid>ion-card + ...
    < /ion-content>

    -------------------------------------------------------------------------------------------

    (7)修改商品列表页模板: product-list.component.html, 添加页面内容
    <ion-header>
    ion-button + ion-searchbar
    </ion-header>
    <ion-content>
    ion-card> ion-item+ ion-infinite-scroll + ion-text
    </ion-content>
    模型数据: productList、 pno、 hasMore、 http

     ------------------------------------------------------------------------------------------

    解释跨域请求:

    跨域请求是浏览器的一种安全策略,浏览器禁止xml访问另外一个不同域下的资源,可以是不同协议、不同端口、不同域名,只要有一点不一样就算跨域,出于安全考虑不允许使用数据

    跨域请求解决方案:
    jsonp方案 :缺点是只能发get请求、效率偏低在dom树上动态创建script

    cors方案:只适合前后端是一家的情况

    服务器端代理

    HTML元素属性(Attribute)和JS DOM对象的属性(Property)
    ①元素属性和对象属性同名:
    <img src= " Xxx">
    document.createElement('img').src= "xx"
    ②元素属性和对象属性不同名:
    <input   class="box" tabindex="3" >
    document.createElement('box' ).className= "box"
    document.createElement( box').tabIndex= "3"
    ③元素属性在对象属性不存在:

    <td colspan="3">
    document.createElement('td").colSpan= "box"
    ④对象属性在元素属性中不存在
    document.createElement('div').innerHTML = 'abcd'
    <div innerHTML="">

    自定义一个管道内俩种模式

     

     

     
  • 相关阅读:
    wampserver的安装及使用配置方法
    关于数据未渲染完,要获取document高度问题——ajax全局事件
    浏览器内核及对应兼容性的处理问题
    [PHP]php缓冲 output_buffering的使用详解
    [PHP]PDO各方法在发生MYSQL断开时的反应
    [算法]浮点数在内存中的存储方式
    [PHP]session回收机制及php.ini session生命期
    [Linux][HTTP] Cookie和Set-Cookie
    [MySQL]多表关联查询技巧
    [MySql]索引的一些技巧
  • 原文地址:https://www.cnblogs.com/liuqingqing-bloom/p/13363877.html
Copyright © 2020-2023  润新知