Angular入门教程 | 05Angular操作DOM

195 阅读2分钟

接下来这篇文章来演示一下angular如何操作dom

通过原生js来操作dom

home.component.html

<div id="box">
  this is a box
</div>

home.component.ts中,我们可以发现这个时候是可以获取并且操作dom的。

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

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
  title = 'Tour of Heroes';
  public keywords = ''

  public flag:boolean=true
  constructor() {
  }

  // 这个生命周期只是组件和指令初始化完成,并不是dom加载完成
  ngOnInit(): void {
    // angular里面所有的变量我们都要指明类型
    let oBox:any = document.getElementById('box')

    console.log(oBox.innerHTML,'oBox.innerHTML');
    oBox.style.color="red"  //有效

  }

}

当我们在dom元素中加入angular的指令时 在home.component.html


<div id="box">
  this is a box
</div>

<div id="box2" *ngIf="flag">
  this is a box2
</div>

home.component.ts中,我们可以发现这个时候是不可以获取并且操作dom的。

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

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
  title = 'Tour of Heroes';
  public keywords = ''

  public flag:boolean=true
  constructor() {
  }

  // 这个生命周期只是组件和指令初始化完成,并不是dom加载完成
  ngOnInit(): void {
    // angular里面所有的变量我们都要指明类型
    let oBox:any = document.getElementById('box')
    let oBox2:any = document.getElementById('box2')

    console.log(oBox.innerHTML,'oBox.innerHTML');
    oBox.style.color="red" 
    oBox2.style.color="blue" //这个时候是无效的

  }
}

这个时候我们可以声明一个新的生命周期

  // 视图加载完成之后触发的方法 dom这个时候肯定已经加载完成了 (建议把dom操作放在这个里面)

ngAfterViewInit(): void {
    //Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
    //Add 'implements AfterViewInit' to the class.
    let oBox2:any = document.getElementById('box2')
    oBox2.style.color="blue" //有效
    
  }

用angular提供的 ViewChild来操作dom

  1. 模版中给dom起个名字
  2. 在业务逻辑里面引入ViewChild
  3. 写在类里面,通过装饰器获取节点 @ViewChild('myBox') myBox:any ;
  4. 在ngAfterViewInit(){}生命周期里获取dom,通过this.myBox.nativeElement获取 我们通过实际代码来看一下: news.component.html
<!-- 通过ViewChild操作dom需要通过#起一个名字 -->
<h1 #myBox>
    这是一个新闻组件---操作dom
</h1>

news.component.ts

// 1.引入ViewChild
import { Component, OnInit,ViewChild } from '@angular/core';

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.scss']
})
export class NewsComponent implements OnInit {
  // 2.获取dom节点,并且赋值给myBox这个变量
  @ViewChild('myBox') myBox:any;
  constructor() { }

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    //Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
    //Add 'implements AfterViewInit' to the class.
    console.log('获取dom节点',this.myBox.nativeElement);
    
    this.myBox.nativeElement.style.width = '600px'
    this.myBox.nativeElement.style.height = '100px'
    this.myBox.nativeElement.style.background = 'green'

  }

}

总结:

  1. 我们通过ViewChild不仅能实现操作dom,还可以实现父组件调用子组件的方法。
  2. 我们在父组件里面引入一个子组件,通过#给子组件起名字
  3. 通过import引入ViewChild,在父组件中通过装饰器引入子组件,@ViewChild('xx') xx:any
  4. 在生命周期,或者父组件的方法中通过this.yy来调用子组件中的方法