整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

重学前端基础:如何查看文档对象的所有属性?如何文档查

重学前端基础:如何查看文档对象的所有属性?如何文档查找节点?

档树

Document Object Model (DOM) 为文档对象模型, 它使用对象的表示方式来表示对应的文档结构及其中的内容

下面为一个样例 p 元素在文档中的对象所包含的所有属性

控制台:

p#dom
accessKey: ""
align: ""
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {0: id, id: id, length: 1}
autocapitalize: ""
baseURI: "file:///E:/yuanli.html"
childElementCount: 0
childNodes: NodeList [text]
children: HTMLCollection []
classList: DOMTokenList [value: ""]
className: ""
clientHeight: 26
clientLeft: 0
clientTop: 0
clientWidth: 713
contentEditable: "inherit"
dataset: DOMStringMap {}
dir: ""
draggable: false
firstChild: text
firstElementChild: null
hidden: false
id: "dom"
innerHTML: "查看我自己都有哪些属性"
innerText: "查看我自己都有哪些属性"
inputMode: ""
isConnected: true
isContentEditable: false
lang: ""
lastChild: text
lastElementChild: null
localName: "p"
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: script
nextSibling: text
nodeName: "P"
nodeType: 1
nodeValue: null
nonce: ""
offsetHeight: 26
offsetLeft: 8
offsetParent: body
offsetTop: 20
offsetWidth: 713
onabort: null
onauxclick: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onblur: null
oncancel: null
oncanplay: null
oncanplaythrough: null
onchange: null
onclick: null
onclose: null
oncontextmenu: null
oncopy: null
oncuechange: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
ondurationchange: null
onemptied: null
onended: null
onerror: null
onfocus: null
onfullscreenchange: null
onfullscreenerror: null
ongotpointercapture: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onloadeddata: null
onloadedmetadata: null
onloadstart: null
onlostpointercapture: null
onmousedown: null
onmouseenter: null
onmouseleave: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onpause: null
onplay: null
onplaying: null
onpointercancel: null
onpointerdown: null
onpointerenter: null
onpointerleave: null
onpointermove: null
onpointerout: null
onpointerover: null
onpointerup: null
onprogress: null
onratechange: null
onreset: null
onresize: null
onscroll: null
onsearch: null
onseeked: null
onseeking: null
onselect: null
onselectionchange: null
onselectstart: null
onstalled: null
onsubmit: null
onsuspend: null
ontimeupdate: null
ontoggle: null
onvolumechange: null
onwaiting: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwheel: null
outerHTML: "<p id="dom">查看我自己都有哪些属性</p>"
outerText: "查看我自己都有哪些属性"
ownerDocument: document
parentElement: body
parentNode: body
prefix: null
previousElementSibling: null
previousSibling: text
scrollHeight: 26
scrollLeft: 0
scrollTop: 0
scrollWidth: 713
shadowRoot: null
slot: ""
spellcheck: true
style: CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}
tabIndex: -1
tagName: "P"
textContent: "查看我自己都有哪些属性"
title: ""
translate: true
__proto__: HTMLParagraphElement

通过使用 DOM 提供的 API (Application Program Interface) 可以动态的修改节点(node),也就是对 DOM 树的直接操作。 浏览器中通过使用 JavaScript 来实现对于 DOM 树的改动。

DOM 包含

  • DOM Core
  • DOM HTML
  • DOM Style
  • DOM Event

HTML 转换 DOM 树

<!DOCTYPE html>
<html lang="en">
 <head>
 <title>My title</title>
 </head>
 <body>
 <a href="">My Link</a>
 <h1>My header</h1>
 </body>
</html>

节点遍历

在元素节点中提取自己所需的节点,并予以操作。

节点类型

常用节点类型

  • ELEMENT_NODE 可使用 Document.createElement('elementName'); 创建
  • TEXT_NODE 可使用 Document.createTextNode('Text Value'); 创建

不同节点对应的NodeType类型

此值可以通过 Node.nodeType 来获取。

1元素,2属性,3文本,8注释,9文档等比较常用。还有平常说的元素 其实指的是节点中得元素节点,所以说节点包含元素,节点还包括文本节点、实体节点等。

T之家 2 月 10 日消息,华为技术有限公司的江英杰为大家揭晓了关于开源鸿蒙 OpenHarmony 3.1 Beta 版中的一个关键特性,也就是 ArkUI 开发框架中的 canvas 画布。

据介绍,canvas 是 ArkUI 开发框架里的画布组件,常用于自定义绘制图形。因为其轻量、灵活、高效等优点,被广泛应用于 UI 界面开发中。本期,我们将为大家介绍 ArkUI 开发框架中 canvas 组件的使用。

canvas 介绍

1.1 什么是 canvas?

IT之家了解到,在 Web 浏览器中,canvas 是一个可自定义 width、height 的矩形画布,画布左上角为坐标原点,以像素为单位,水平向右为 x 轴,垂直向下为 y 轴,画布内所有元素都基于原点进行定位。

如下图所示,我们可以通过 <canvas> 标签,创建了一个 width=1500px,height=900px 的空白画布,我们还需要“画笔”才能绘制图形。canvas 采用轻量的逐像素渲染机制,以 JS 为“画笔”直接控制画布像素,从而实现图形绘制。

1.2 Canvas 的“画笔”

canvas 本身虽不具备绘制能力,但是提供了获取“画笔”的方法。开发者可通过 getContext ('2d') 方法获取 CanvasRenderingContext2D 对象完成 2D 图像绘制,或通过 getContext ('webgl') 方法获取 WebGLRenderingContext 对象完成 3D 图像绘制。

目前,ArkUI 开发框架中的 WebGL1.0 及 WebGL2.0 标准 3D 图形绘制能力正在完善中,所以本文将着重介绍 2D 图像的绘制。如下图所示,是 CanvasRenderingContext2D 对象提供的部分 2D 图像绘制方法,丰富的绘制方法让开发者能高效地绘制出矩形、文本、图片等。

除此之外,开发者还可以通过获取 OffscreenCanvasRenderingContext2D 对象进行离屏绘制,绘制方法同上。当绘制的图形比较复杂时,频繁地删除与重绘会消耗很多性能。

这时,开发者可以根据自身的需求灵活选取离屏渲染的方式,首先通过创建 OffscreenCanvas 对象作为一个缓冲区,然后将内容绘制在 OffscreenCanvas 上,最后再将 OffscreenCanvas 绘制到主画布上,以提高画布性能,确保绘图的质量。

canvas 基础绘制方法

通过上节对 canvas 组件的基本介绍,相信大家对 canvas 组件已经有了一定的认识,下面我们将为大家实际演示 canvas 组件在 ArkUI 开发框架中的使用方法。ArkUI 开发框架参考了 Web 浏览器中 canvas 的设计,并在“类 Web 开发范式”及“声明式开发范式”两种开发范式中进行提供,接下来我们将分别介绍这两种开发范式中 canvas 的绘制方法。

2.1 类 Web 开发范式中 canvas 的绘制方法

类 Web 开发范式,使用 HML 标签文件进行布局搭建、CSS 文件进行样式描述,并通过 JS 语言进行逻辑处理。目前,JS 语言的 canvas 绘图功能已经基本上完善,下面我们将通过两个示例,展示基于 JS 语言的 canvas 组件基础使用方法。

2.1.1 矩形填充

CanvasRenderingContext2D 对象提供了 fillRect (x, y, width, height) 方法,用于绘制一个填充的矩形。如下图所示,在画布内绘制了一个黑色的填充矩形,x 与 y 指定了在 canvas 画布上所绘制的矩形的左上角(相对于原点)的坐标,width 和 height 则设置了矩形的尺寸。

示例代码如下:

//创建一个width=1500px,height=900px的画布<!-- xxx.hml --><div>  <canvas ref="canvas" style="width: 1500px; height: 900px; "></canvas></div>
//xxx.jsexport default {  onShow() {    const el =this.$refs.canvas;//获取2D绘制对象    const ctx = el.getContext('2d');//设置填充为黑色    ctx.fillStyle = '#000000';//设置填充矩形的坐标及尺寸    ctx.fillRect(200, 200, 300, 300);  }}

2.1.2 缩放与阴影

CanvasRenderingContext2D 对象提供了 scale (x,y) 方法,参数 x 表示横轴方向上缩放倍数,y 表示纵轴方向上缩放的倍数,值得注意的是缩放过程中定位也会被缩放。如下图所示,是将上个示例中的填充矩形通过 scale (2,1.5) 缩放,并通过 shadowBlur 方法加上阴影后的效果。

示例代码如下:

//xxx.jsexport default {  onShow() {    const el =this.$refs.canvas;    const ctx = el.getContext('2d');//设置绘制阴影的模糊级别    ctx.shadowBlur = 80;    ctx.shadowColor = 'rgb(0,0,0)';    ctx.fillStyle = 'rgb(0,0,0)';    // x Scale to 200%,y Scale to 150%    ctx.scale(2, 1.5);    ctx.fillRect(200, 200, 300, 300);  }}

2.2 声明式开发范式中 canvas 的绘制方法

声明式开发范式,采用 TS 语言并进行声明式 UI 语法扩展,从组件、动效和状态管理三个维度提供了 UI 绘制能力,目前已经提供了 canvas 组件绘制能力,但功能仍在完善中。下面我们将通过两个示例展示声明式开发范式中 canvas 组件的基础使用方法。

2.2.1 图片叠加

如下图所示,是三张图片叠加的效果,顶层的图片覆盖了底层的图片。通过依次使用 drawImage (x,y, width, height) 方法设置图片坐标及尺寸,后面绘制的图片自动覆盖原来的图像,从而达到预期效果。

扩展的 TS 语言采用更接近自然语义的编程方式,让开发者可以直观地描述 UI 界面,示例代码如下:

@Entry@Componentstruct IndexCanvas1 {  private settings:RenderingContextSettings = new RenderingContextSettings(true);//获取绘图对象  private ctx: RenderingContext = new RenderingContext(this.settings);//列出所要用到的图片  private img:ImageBitmap = new ImageBitmap("common/bg.jpg");  build() {    Column() {      //创建canvas      Canvas(this.ctx)        .width(1500)        .height(900)        .border({color:"blue",width:1,})        .backgroundColor('#ffff00')         //开始绘制        .onReady(() => {          this.ctx.drawImage( this.img,400,200,540,300);          this.ctx.drawImage( this.img,500,300,540,300);          this.ctx.drawImage( this.img,600,400,540,300);        })    }    .width('100%')    .height('100%')  }}

2.2.2 点击创建线性渐变

如下图所示,是一个线性渐变效果。基于 canvas 扩展了一个 Button 组件,通过点击“Click”按钮,触发 onClick () 方法,并通过调用 createLinearGradient () 方法,绘制出了一个线性渐变色。

示例代码如下:

@Entry@Componentstruct GradientExample {  private settings: RenderingContextSettings = new RenderingContextSettings(true);  private context: RenderingContext = new RenderingContext(this.settings);  private gra: CanvasGradient = new CanvasGradient();  build() {    Column({ space: 5 })  {//创建一个画布      Canvas(this.context)        .width(1500)        .height(900)        .backgroundColor('#ffff00 ')      Column() {//设置按钮的样式        Button('Click').width(250).height(100).backgroundColor('#000000')          .onClick(() => {//创建一个线性渐变色            var grad = this.context.createLinearGradient(600, 200, 400, 750)            grad.addColorStop(0.0, 'red');            grad.addColorStop(0.5, 'white');            grad.addColorStop(1.0, 'green');            this.context.fillStyle = grad;            this.context.fillRect(400, 200, 550, 550);          })       }.alignItems(HorizontalAlign.center)     }   } }

飞机大战小游戏绘制实践

如下图所示,是一款”飞机大战”小游戏,通过控制战机的移动摧毁敌机。如何使用 ArkUI 开发框架提供的 canvas 组件轻松实现这个经典怀旧的小游戏?实现思路及关键代码如下:

1. 首先列出游戏所用到的图片

private imgList:Array<string> = ["xx.png","xx.png"…];

2. 将图片渲染到 canvas 画布上

let img:ImageBitmap = new ImageBitmap("图片路径(如common/images)/"+this.imgList[数组下标]);this.ctx.drawImage( img,150/* x坐标*/,  150/* y坐标*/, 600/*宽*/, 600/*高*/)

3. 绘制背景图片和战机向下移动的效果

this.ctx.drawImage(this.bg, 0, this.bgY);this.ctx.drawImage(this.bg, 0, this.bgY - 480);this.bgY++ == 480 && (this.bgY = 0);

4. 使用 Math.round 函数随机获取敌机图片并渲染到画布上,并且改变敌机 y 轴坐标,使它向下运动。

Efight = Math.round(Math.random()*7);//前七张为敌机图片。let img:ImageBitmap = new ImageBitmap("common/img"+this.imgList[Efight]);this.ctx.drawImage(img, 0, this.Eheight + 50);//渲染敌机

5. 在页面每隔 120s 出现一排子弹,之后减小或增大(x,y)轴的坐标达到子弹射出效果。

let i= 0;setInterval(()=>{  this.ctx.drawImage(this.bulImg1,image.x – 10 – (i *10) , image.x + (i *10))  this.ctx.drawImage(this.bulimg2, this. bulImg1,image.x – (i *10) , i image.x + (i *10))  this.ctx.drawImage(this.bulimg3, image.x + 10 + (i *10), image.x + (i *10))i ++;},120)

6. 使用 onTouch 方法获取战机移动位置,获取拖动的坐标后重新设置战机的图片坐标,使战机实现拖动效果。

.onTouch((event)=>{  var offsetX = event.localX ||event.touches[0].localX;  var offsetY = event.localY ||event.touches[0].localY;  var w = this.heroImg[0].width,      h = this.heroImg[0].height;  var nx = offsetX - w / 2,      ny = offsetY - h / 2;      nx < 20 - w / 2 ? nx = 20 - w / 2 : nx > (this.windowWidth - w / 2 - 20) ? nx =  (this.windowWidth - w / 2 - 20) : 0;  ny < 0 ? ny = 0 : ny > (this.windowHeight - h / 2) ? ny = (this.windowHeight –  h/2) : 0;     this.hero.x = nx;     this.hero.y = ny;     this.hero.count = 2;

注:本示例引用了部分开源资源,感兴趣的开发者可参考此开源资源,结合文中的实现思路补全代码。(https://github.com/ xs528 / game)

以上就是本期全部内容,期待广大开发者能通过 canvas 组件绘制出精美的图形,更多 canvas 组件的详细使用方法,请参考文档进行学习:

https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-canvas-canvas-0000000000621808

Angular及Ionic

Angular

概述

what?

一套框架,多种平台 移动端 & 桌面端 在学完了Angular框架的使用之后, 可以使用NativeScript做跨平台开发, 使用ionic做移动端的开发, 使用material或者ngZorro来实现PC端的开发

why?

angular内置的丰富的class ts(typeScript)是es6的超集,强类型约束的语言 支持组件化 更好的可读性和可维护性 更好的社区支持和文档支持 体积更小 强大的cli(command line interface)支持

when?

用在中大型SPA

how?

搭建环境

npm install -g @angular/cli ng new my-app cd my-app ng serve --open

编程方式

angular: ①采用模块来作为容器,封装组件、指令、管道等,基本单位 ②采用组件来封装可复用的视图 ③采用服务来封装可复用的数据和方法 ④采用装饰器和元数据来完成类的具体描述和配置 ⑤采用指令来增强模板的功能

装饰器与元数据的整理

@Component

@Component({ selector:'', templateUrl:'', styleUrls:[] })

@Directive

@Directive({ selector:[''] })

@Pipe

@Pipe({ name:"" })

@Injectable

@Injectable({ providedIn:'root' })

@NgModule

@NgModule({ declarations:[组件类、指令类、管道类], imports:[依赖的模块类] })

@Input @Output

@ViewChild

使用

组件的创建和使用

创建

ng g component demo01

import {Component} from '@angular/core' @Component({ selector:'app-demo01', templateUrl:"", styleUrls:[''] }) export class Demo01Component{}

调用

<app-demo01></app-demo01>

基本语法

{{}}

<any>{{expression}}</any>

内置的指令

*ngFor

*ngIf

()

[]

[(ngModel)]

前提:让当前所属的模块 依赖于FormsModule

自定义的指令

创建

ng g directive test

使用

<any appTest></any>

进阶知识

①获取调用指令的元素

ElementRef

②获取指令调用时所传递的参数

Input

内置的管道

uppercase/lowercase

json

percent

number

slice

currency

。。。

自定义的管道

创建

ng g pipe test

配置

实现管道类中的transform方法

@Pipe({ name:'' }) export class TestPipe implements PipeTransform{ transform(value:any,...args:Array<any>){ //根据管道的需要,实现数据的处理 return 处理后的结果 } }

调用

在组件的模板中 调用自定义管道, 自定义管道和内置的管道用法是一致的


服务

服务:将不同的组件要复用的数据和方法 封装在一个类中 以方便给组件进行复用

实现

创建

ng g service user

注意:@Injectable({ providedIn:'root' }) 等价于在app.module.ts中 直接指定providers

配置

在服务的类中 定义业务所需要用到的 数据和方法

调用

import {UserService} from '****'

constructor(private myService:UserService){}

this.myService.***

组件间通讯

props down

发送

<son myName='123'></son>

子组件接收

import {Input} from '@angular/core'

@Input() myName=""

this.myName

events up

绑定

handleEvent(msg){}

<son (myEvent)="handleEvent($event)"></son>

触发

import {Output,EventEmitter} from '@angular/core'

@Output myEvent=new EventEmitter()

this.myEvent.emit(123)

补充

local variable

适合:父组件在模板中 主动的读取子组件中 的数据或者方法

<son #zhangsan></son> {{zhangsan.**}}

viewChild

适合:父组件在组件类中 操作子组件

用法

import {ViewChild} from '@angular/core'

如果找子,指定了本地变量 @ViewChild('zhangsan') mySon

如果找子,没有指定本地变量 import {Son} from '***' @ViewChild(Son) mySon

service

网络通讯

HttpClient

用法

步骤1:让根模块依赖于HttpClientModule

app.module.ts

import {HttpClientModule} from '@angular/common/http'

@NgModule({ imports:[HttpClientModule] })

步骤2:在组件中调用HttpClient

import {HttpClient} from '@angular/common/http'

constructor(private myHttp:HttpClient){}

this.myHttp.get('').subscribe((result)=>{ //result就是服务器端在本次请求中返回的结果 })

路由模块

基本用法

步骤1:创建一个用来配置路由的自定义的模块 ng g module my-router --routing 步骤2:指定一个盛放组件的容器 <router-outlet></router-outlet> 步骤3: 创建组件 ng g component demo14-login ng g component demo14-register 步骤4:路由词典 路由词典:是一个多个路由对象构成的数组 在新建的模块中my-route.routing.module.ts const routes:Routes=[ {path:"",component:**} ] 步骤5:调用路由词典 在新建的模块中my-route.routing.module.ts @NgModule({ imports:[RouterModule.forRoot(routes)] }) 步骤6:让根模块调用刚配置过的自定义模块 import {MyRouterRoutingModule} from '**' app.module.ts @NgModule({ imports:[MyRouterRoutingModule] }) 步骤7:测试 localhost:4200 localhost:4200/login localhost:4200/register

跳转和传参

跳转

Router

import {Router} from '@angular/router'

constructor(private myRouter:Router){}

this.myRouter.navigateByUrl('')

RouterLink

<any routerLink="/detail"></any>

传参

配置接收方的路由地址 /detail --> /detail/:id

发送参数

this.myRouter.navigateByUrl('detail/10')

<any routerLink="/detail/10"></any>

this.myRouter.navigateByUrl('detail/'+this.id)

<any [routerLink]="'/detail/'+id"></any>

接收参数

import {ActivatedRoute} from '@angular/router'

constructor(private myRoute:ActivatedRoute){}

this.myRoute.params.subscribe((result)=>{ //result.id })

嵌套

比如A,需要根据不同的url嵌套B或者C

实现

给A组件的模板指定一个容器 router-outlet

在A组价的路由对象中,配置子路由

{ path:'a', component:A, children:[ {.....} ] }

守卫

在访问一个路由地址的时候,通过一个守卫来保护 该地址所对应的组件是否可被访问

实现

创建一个服务

ng g service my-guard

在该服务中实现一个CanActivate接口

import {CanActivate} from '@angular/router'

export class MyGuardService implements CanActivate{ canActivate() { return true/false } }

调用路由守卫

import {MyGuardService} from '****' { path:'admin', component:AdminComponent, canActivate:[MyGuardService] }

。。。

Ionic

概述

ionic=angular + 封装的ui组件库+icon+phonegap

使用

页面类的创建和使用

ionic g page demo01

button

ion-button

color primary/secondary/danger/light/dark

large/small

block

clear/outline

icon-left/right

<ion-icon name="home/cog"></ion-icon>

list

基础用法

普通列表

<ion-list> <ion-item>123</ion-item> </ion-list>

icon列表

<ion-list> <ion-item> <ion-icon item-start/end name=''></ion-icon> </ion-item> </ion-list>

头像avatar列表

<ion-list> <ion-item> <ion-avatar> <img src=""/> </ion-avatar> 123 </ion-item> </ion-list>

缩略图thumbnail列表

<ion-list> <ion-item> <ion-thumbnail> <img src=""/> </ion-thumbnail> 123 </ion-item> </ion-list>

侧滑动列表

<ion-list> <ion-item-sliding> <ion-item></ion-item> <ion-item-options> .... </ion-item-options> </ion-item-sliding> </ion-list>

进阶用法

下拉刷新

调用标签

将ionRefresher放在ionContent的第一个子元素的位置

绑定事件

<ion-refresher (ionRefresh)="handleRefresh($event)"></ion-refresher>

指定事件处理函数

handleRefresh(myRefresher){ //异步操作数据完成之后 //结束刷新动作 myRefresher.complete() }

上拉加载

调用标签

将ionInfiniteScroll放在ionContent的最后一个子元素的位置

绑定事件

绑定一个事件ionInfinite

指定事件处理函数

handleInfinite(myInfinite){ //异步操作 //结束 myInfinite.complete() }

自定义布局

基本用法

<ion-grid> <ion-row> <ion-col></ion-col> <ion-col></ion-col> </ion-row> </ion-grid>

常见配置

col-* 设置列的宽度

align-items-start/center/end 一行中所有列的纵向对齐方式

align-self-start/center/end 当前列内容的纵向对齐方式

justify-content-start/center/end 行中列的横向对齐方式

offset-* 设置当前列距离左边列的位移

push/pull-* 将当前列向右推或者左拉的距离

轮播图

<ion-slides autoplay=2000 loop=true effect="cube/flip/slide" speed=3000 pager=true paginationType="bullets/fraction/progress" direction='vertical' > <ion-slide></ion-slide> <ion-slide></ion-slide> <ion-slide></ion-slide> </ion-slides>

card

<ion-card> <ion-card-header></ion-card-header> <ion-card-content></ion-card-content> </ion-card>

窗口

交互窗口有着相似的 使用方法

引入

实例化

创建

显示

loading(一个活动正在进行)

import {LoadingController} from 'ionic-angular'

constructor(private loadingCtrl:LoadingController){}

var myLoading=this.loadingCtrl.create({ spinner:'', content:"", duration:3000 })

myLoading.present() myLoading.dismiss()

actionSheet (从多个选项中让用户选择)

create({ title:'', message:'', buttons:[ { text:'', handler:()=>{}, role:'destructive/cancel' } ] })

toast(显示操作的结果)

create({ message:"", position:'top/middle/bottom', duration:1500, showCloseButton:true, closeButtonText:'', ... })

alert (警告、确认、输入提示)

create({ title:'', message:'', inputs:[ {type:'password'} ], buttons:[ {text:'',handler:(data)=>{ //data是一个数组 data[0] 获取第0个输入框的值 }} ] })

modal (自定义窗口)

create(Demo22Page)

进阶知识

在模态窗内部如何关闭

import {ViewController} from 'ionic-angular'

constructor(private viewCtrl:ViewController){}

this.viewCtrl.dismiss()

关闭时完成参数的传递和接收

this.viewCtrl.dismiss(1000)

var myModal=this.modelCtrl.create(**) myModal.onDidDismiss((data)=>{ //data就是传来的数据 })

tabs

标签页栏,实现底部的导航工具条

用法

在页面类中 引入每一个tab被选中时要 用到的页面类

import {SettingsPage} from 'ionic-angular'

在当前的页面类中 定义变量保存上一步引入的页面类(目的是到模板中可以使用)

tabSettings=SettingsPage

<ion-tabs> <ion-tab tabTitle="" tabIcon="" [root]=tabSettings></ion-tab> <ion-tab></ion-tab> <ion-tab></ion-tab> </ion-tabs>

导航

跳转

方案1

import {NavController} from 'ionic-angular'

import {DetailPage} from '**'

constructor(private navCtrl:NavController){}

this.navCtrl.push(DetailPage)

方案2

import {DetailPage} from '**'

detail=DetailPage

<any [navPush]="detail"></any>

传参

发送

this.navCtrl.push(DetailPage,{id:10})

<any [navPush]="detail" [navParams]="{id:20}"></any>

接收

import {NavParams} from 'ionic-angular'

constructor(private navParams:NavParams){}

this.navParams.get('id')

支持滚动的容器

<ion-scroll scrollX=true scrollY=true></ion-scroll>

表单

通过ionList和ionItem来管理表单

实现

<ion-list> <ion-item> <ion-label></ion-label> <ion-input></ion-input> <ion-toggle></ion-toggle> <ion-checkbox></ion-checkbox> <ion-radio></ion-radio> .... </ion-item> </ion-list>

生命周期

会被执行很多次

守卫

ionViewCanEnter

ionViewCanLeave

普通

ionViewWillEnter

ionViewDidEnter

ionViewWillLeave

执行一次

ionViewDidLoad

ionViewWillUnload

React及ReactNative

ReactJS

概述

what?是一个以组件化的方式来构建ui层的js库

when? 数据操作比较频繁的场景

why?

历史背景

浏览器性能瓶颈

VDOM

开发和维护

单向数据流

how?

引入3个js文件

cli

npx create-react-app my-app cd my-app npm start

demo01

<script src="js/react.js"></script> <script src="js/react-dom.js"></script> <script src="js/browser.min.js"></script>

<div id="example"></div>

<script type='text/babel'></script>

ReactDOM.render( <h1>123</h1>, document.getElementById('example') )

核心思想

everything is component

核心概念

jsx

jsx需要通过babel转换为浏览器能识别的语法, 是reactjs开发推荐使用,不强制使用

两个基本语法

<

首字母是小写--》html

首字母是大写--》组件

{

执行表达式

优缺点

优点

方便的封装组件

提高代码的可读性

缺点

现有的html标签有些属性不能用 class-->className for-->htmlFor

将数据和视图合在一起,增加代码的耦合度

component

组件:可被反复使用的,带有特定功能的视图

创建和使用

创建

var MyComponent=React.createClass({ render(){ return ** } })

调用

<MyComponent></MyComponent>

注意事项

有开始有结束

全驼峰

放在一个顶层标签

render方法return时,第一个标签不要直接换行

props

知识点1

props down(父--》子)

实现

<Son myName='zhangsan'></Son>

this.props.myName

知识点2

子--》父

实现

save(msg){}

<Son myFunc={this.save}></Son>

this.props.myFunc(123)

知识点3

this.props.children 获取 当前组件作为标签去使用时,内部的子标签

React.Children.map(this.props.children,(child)=>{})

state

管理数据

初始化

getInitialState:function(){ return {count:1,age:10} }

this.state.count

this.setState({count:2})

this.setState({count:2},()=>{ //状态修改成功之后的回调函数 })

绑定

将状态中的值 给视图去使用, 状态发生了变化,视图就会更新 比如: <p>{this.state.count}</p> <h2 style={{opacity:this.state.opacityValue}}></h2>

ref

reference 引用 参考 参照

ref是可以让在父组件中直接找到子组件的实例, 或者找到一个标签

实现

<any ref="mySon"></any>

this.refs.mySon.***

生命周期

react中组件的生命周期分为3个阶段

阶段

mount

componentWillMount

componentDidMount

update

componentWillUpdate

componentDidUpdate

componentWillReceiveProps

unmount

componentWillUnmount

注意事项

①通过ref寻找元素或者组件,必须等到 componentDidMount或者之后

②componentWill/DidUpdate(是在props或者state中值变化时), 中不允许执行状态的修改操作 会陷入死循环

③componentWillRecevieProps是允许修改状态的

④不允许修改props对象中的值(read only)

受控表单元素

前提:在react中不是所有的表单元素都是受控表单元素

只有指定了value/checked/selected等属性的表单元素才需要特殊处理

处理

方案1:defaultValue

方案2:

基于状态具有绑定的特性

步骤1:初始化状态

getInitialState:function(){ return {myAddr:'bj'} }

步骤2:读

<input value={this.state.myAddr}/>

步骤3:绑定事件,在事件 处理函数中写状态

handleChange(e){ this.setState({myAddr:e.target.value}) }

<input onChange={this.handleChange} value={this.state.myAddr}/>

进阶知识

1、事件处理函数自定义传值?

<button onClick={()=>this.handleClick(123)}></button>

2、循环

{ this.state.list.map((value,index)=>{ return <li key={index}></li> }) }

3、条件判断

判断条件比较简单: 逻辑与

{ expression && <标签></标签> }

判断条件相对复杂: 方法的封装和调用

isShow(){ //执行运算,得到判断条件需要的数据 //判断,如果符合条件,返回要显示的元素否则不显示 if(){ return <标签></标签> } }

{ this.isShow() }

ReactNative

概述

what?

构建原生app的,由fb所推出的,可以使用react和js 进行编程的框架

how?

搭建环境

npm install -g expo-cli expo init AwesomeProject cd AwesomeProject npm start

如何编程

使用react中的组件化的核心思想,以及核心概念; 来完成rn中封装的组件的调用,构建属于自己的组件(页面) 借助第三方的工具react-navigation来完成路由和导航, 实现一个完成的app

基础

组件化

创建

import React,{Component} from 'react' import {Text} from 'react-native' export default class Demo01Component extends Component{ render(){ return <Text></Text> } }

使用

import Demo01Component from '***'

<Demo01Component></Demo01Component>

AppRegistry.registerComponent("myapp",()=>Demo01Component)

通过路由访问

注意

①不允许调用html标签 ②组件先引入 再使用 ③类的名称要遵循全驼峰 ④类的导出方式的区别 export default --> 引入时,不需要加花括号;类的名称可以和导出不一致 export class --> 引入时,必须加上花括号,类的名字必须和导出时保持一致

样式

目的:在rn中是支持常见的html的style属性

import {StyleSheet} from 'react-native'

const myStyles=StyleSheet.create({ myText:{ fontSize:20, color:'red' } })

<Text style={myStyles.myText}></Text>

数据

初始化

constructor(){ super() this.state={count:0} }

this.state.count

this.setState({count:10})

自定义布局

flexDirection

justifyContent

alignItems

网络通讯

fetch("") .then((response)=>response.json()) .then((result)=>{ //result就是服务器端数据反序列化之后的结果 })

常见组件

容器

View

实现一个容器

步骤

import {View} from 'react-native'

<View> 嵌套一些其他的标签 </View>

ScrollView

实现一个支持滚动的容器

使用

import {ScrollView} from 'react-native'

<ScrollView> ... </ScrollView>

实现页脚的技巧

<View style={{flex:1}}> <ScrollView></ScrollView> <View> 页脚中的东西 </View> </View>

FlatList

高性能的列表

步骤

import {FlatList} from 'react-native'

//有参数有返回值的 showItem(info){ //info是一个对象,item属性对应的数组的临时变量, index属性对应的当前遍历时下标 return <渲染的列表项></渲染的列表项> }

<FlatList renderItem={this.showItem} data={[100,200,300]}></FlatList>

TouchableOpacity

实现一个容器,放在此容器中的组件 支持点按时 透明度变化效果

使用

import {TouchableOpacity} from 'react-native'

<TouchableOpacity onPress={}> <Text>123</Text> </TouchableOpacity>

Text

显示一段内容

步骤

import {Text} from 'react-native'

<Text>渲染的内容</Text>

Switch

滑动开关(默认的受控组件)

使用

import {Switch} from 'react-native'

constructor(){ super(); this.state={myValue:true} }

handleValueChange(value){ this.setState({myValue:value}) }

<Switch value={this.state.myValue} onValueChange={this.handleValueChange}></Switch>

TextInput

文本输入框

使用

import {TextInput} from 'react-native'

handleChangeText(msg){ //msg就是输入框的数据 }

<TextInput placeholder="" secureTextEntry={true} onChangeText={this.handleChangeText}></TextInput>

Button

按钮

步骤

import {Button} from 'react-native'

handlePress(){ }

<Button title="clickMe" onPress={this.handlePress}></Button>

Image

显示图片

使用

import {Image} from 'react-native'

//本地 <Image source={require("加载的图片路径")}></Image> //网络资源 <Image source={{uri:""}}></Image>

注意事项

本地资源图片路径不允许做运算

网络资源图片 要指定宽高

ActivityIndicator

实现一个加载中的指示器

使用

import {ActivityIndicator} from 'react-native'

<ActivityIndicator size="" color=""></ActivityIndicator>

Python及Django

Python

学习目标

目标: ①熟练掌握python基本语法、常见的标准库的使用、面向对象、异常处理 ②第三方的库django:ORM、模板语法、基本用法。。 ③采用python和django框架编写出后台的api

概述

Python是一门编程语言, 用在很多领域中,比如web、GUI、科学分析和数据处理、系统集成 (爬虫、系统运维、人工智能、数据分析。。)

常识

注释

行注释: #注释内容

块注释: """ 块注释内容 """

输入输出

输入:input('提示信息')

输出:print("信息1","信息2")

缩进

python是通过缩进和冒号来组织一个代码块

进入到python的命令解析模式

py/python

exit() quit()

查看帮助信息

help('keywords')

help('modules')

help('print')

....

基本使用

变量的定义、调用、释放

定义

a=3

调用

print(a)

释放

del a

常见数据类型以及api

number

int

a=10

float

a=10.2

bool

a=True/False

complex

a=2+3j

string

定义

myName='zhangsan'

myName="zhangsan"

myName='''zhangsan'''

myName="""zhangsan"""

拼接

myName+myName

重复输出

myName*3

list

定义一个数组

myList=[10,20,30]

数组基本操作

myList.append(11)

myList.insert(0,1)

myList.pop() 删除最后一个元素

myList.pop(2) 删除指定下标为2的元素

myList[0]=100

myList[0]

myList[2]

myList[-2]

补充

len(myList)

max(myList)

min(myList)

myList.sort() myList.sort(reverse=True)

myList.reverse()

tuple(带了枷锁的数组)

元组是带了枷锁的数组,不支持修改元组中的数据

定义

myTuple=(100,200,300)

myTuple=tuple([100,200,300])

myTuple=(1,)

读取元组的中

myTule[0]

set(不会重复的元素)

存储是不会重复的数据集合

定义

mySet=set([100,200,300,300])

mySet.add()

mySet.remove()

dict

存储是一些键值对,查找和插入的速度比较快

字典的常用操作

myDict={"uname":"zhangsan",'upwd':123456}

myDict.get('uname')

myDict['uname']='johnReese'

myDict.keys()

myDict.values()

myDict.items()

数据类型的转换

显示类型转换

list

list(myTuple)

set

set(myList)

tuple

tuple(myList)

int

int('10')

float

float('10.3')

str

str(10)

异常处理

基本用法

try: print(myName) except NameError: print('异常处理流程') finally: 执行最终一定要执行的代码

进阶用法

捕获多个错误

try: print(myName) except NameError: print('异常处理流程1') except ValueError: print('异常处理流程2') finally: 执行最终一定要执行的代码

try: print(myName) except (NameError,ValueError): print('异常处理流程1') finally: 执行最终一定要执行的代码

try: print(myName) except Exception:#捕获所有的错误 print('异常处理流程1') finally: 执行最终一定要执行的代码

手工触发错误并自定义错误消息内容

try: raise(ValueError('错误消息1')) except ValueError as msg: print(msg) finally: 执行最终一定要执行的代码

支持的运算符

算术运算

+-*/ ** % //

关系运算

> >=< <===!=

逻辑运算

and

两者为真,结果是真

or

一个为真,结果为真

not

取反

位运算

& | ~ ^ << >>

赋值运算

+=-+ [num1,num2,num3]=[1,2,3] ... 不支持自增 自减

身份运算

in /not in

id

is

控制语句

条件判断

if expression: pass else: pass

if expression1: pass elif expression2: pass elif expression3: pass else: pass

循环控制

for

for tmp in myList: tmp#遍历数组时的临时变量

range(start,stop,step)

range(5)

0 1 2 3 4

range(5,8)

5 6 7

range(1,8,3)

1 4 7

for index in range(0,len(myList)): index#下标 myList[index]#得到指定下标的元素

while

while expression: pass

continue

直接进入到下一次循环

break

跳出循环

方法

基础知识

创建一个方法 def myFunc(): 方法体

调用方法 myFunc()

参数

参数的值传递和引用传递

# 值传递:修改参数,原始数据不受影响 number/string/tuple # 引用传递:修改参数,原始数据也会变化 list/set/dict

关键字参数

关键字参数,在方法的调用过程中, 是可以通过keyValue指定关键字参数,调整参数顺序

示例

def myFunc(arg1,arg2): print("arg1 is ",arg1) print("arg2 is ",arg2)

myFunc(10,20) myFunc(arg2=30,arg1=15) myFunc(16,arg2=20)

可变长参数

写法1

# 可变长参数:是以元组中的数据进行存储的 def test(*myArgs): print(myArgs) test() test(1) test(1,2,3)

写法2

# 可变长参数的第二种写法: def testFunc(**myArgs): print(myArgs,type(myArgs)) # testFunc(1,2,3) 会报错的 testFunc(a=1,b=2,c=3)

默认值参数

# 默认值参数:调用方法,如果传参,以实际参数为准, 如果没有传参,以默认值为调用的数据 def myFunc(arg1,arg2=20): print(arg1,arg2) myFunc(10) myFunc(10,30)

作用域

分类

Local

函数内部的变量

Embedded

被嵌套的函数内部的变量

Global

定义在模块中的变量

使用注意事项

函数内部 修改全局变量,必须 通过Global引入全局变量才可以

num=10 def myFunc(): global num num+=1

嵌套函数内部,修改外层函数变量,必须 通过nonlocal引入才可以

def outer(): count=0 def inner(): nonlocal count count+=1

闭包

允许在一个函数内部 ,嵌套一个函数

①外层函数在调用,创建外层函数作用域对象 ②内层函数在创建时,通过自己__closure__属性 引用外层作用域对象 在外层函数执行之后,无法释放,形成一个闭包的结果(变量依然保留在内存中,可重用)

模块与包

包:一个文件夹,里头可以包含多个py文件

创建

utility/data.py

调用

import utility.data import utility.data as m1

from utility.data import * from utility.data import test

模块:一个py文件

创建

创建一个py文件

调用

import module1 import module1 as m1

from module1 import test from module1 import *

面向对象编程

封装

创建一个类

class Animal: #定义构造函数 def __init__(self,name,age): self.uname=name self.__myAge=age #定义其它方法 def eat(self): pass

调用

a1=Animal() a1.eat()

继承

class Cat(Animal): pass

多态

在python方法 是可以通过重写来实现在不同的情况下,不同的效果

标准库

time

time.localtime

time.strftime

random

random.choice(range(0,100))

math

math.ceil()

math.floor()

math.fabs()

os

os.environ

os.path.exists

os.path.isFile

...

...

第三方库

mysql-connector

功能:mysql在python下的驱动程序

使用步骤:

①安装、引入

pip install mysql-connector

import mysql.connector as conn

②连接指定的数据库服务器

myConnection=conn.connect(host="localhost",user="root",passwd="",database="xz")

③创建一个游标对象

myCursor=myConnection.cursor(dictionary=True)

④执行sql

myCursor.execute("select * from xz_user")

⑤获取执行的结果

myCursor.fetchall() myCursor.lastrowid myCursor.rowcount

数据库连接池

①引入

import mysql.connector.pooling as pooling

②创建一个连接池

config={ "host":"localhost", "user":"root", "passwd":"", "database":"xz" }

myPool=pooling.MySQLConnectionPool(pool_size=5,**config)

③获取一个连接

myConnection=myPool.get_connection()

....

Django

flask

pyqt

tornado

....

Django

概述:

django是一个基于python的全栈类框架, 05年发布,早期可以用做新闻门户; 提供了强大的后台管理系统,实现网站的前后端的所有东西

django

路由系统的搭建

router

接收请求并返回执行的消息

api

ORM

处理后端数据

模板语法

处理前端页面

基础知识

project和app的区分

一个django的project是一个大的站点, 此网站可以包含很多模块,将模块称之为一个django的app

project的准备

django-admin startproject netease

cd netease py manage.py runserver (默认启动开发服务器端口8000)

app的准备

django-admin startapp military

django-admin startapp history

py manage.py startapp fashion

后台管理系统

默认localhost:8000/admin可以访问,但是 登录不了

py mange.py makemigrations

py manage.py migrate

py manage.py createsuperuser

密码的输入是不可见的

路由系统

路由系统就是为了搭建视图和url的映射关系

①创建视图

举例当前有个app:military

找到military/views.py

from django.http import HttpResponse

def handleIndex(request): return HttpResponse("这是首页")

②配置路由

需求:localhost:8000/military/index

实现步骤

配置app内部路由

新建一个文件 military/urls.py

from django.urls import path from . import views

urlpatterns=[ path("index",views.handleIndex) ]

配置project的路由

netease/urls.py

from django.urls import path,include

urlpatterns=[ path("military",include('military.urls')) ]

参数处理

get

#localhost:8000/demo01/detail?id=2 def handleDetail(request): request.GET['id']

post

关闭CSRF(403)

settings/middleware 注释'django.middleware.csrf.CsrfViewMiddleware'

接收

def handleRegister(request): myData=request.body.decode('utf-8') myDic=json.loads(myData) myDic.get()

跨域

安装

pip install django-cors-headers

注册

settings.py中的INSTALLED_APPS:corsheaders

settings.py中的MIDDLWARE的数组添加: corsheaders.middleware.CorsMiddleware

配置

CORS_ORIGIN_WHITELIST=( "http://localhost:8080" )

ORM

Object Relational Mapping 对象关系映射 直接操作对象中的方法,来实现编写sql进行数据操作的同等效果

orm在django的实现方式

举例:当前一个app:military

步骤1:app要注册

netease/settings.py INSTALLED_APPS

步骤2:创建模型类

military/models.py

class Weapon(models.Model): title=models.CharField(max_length=200) #AutoField IntegerField BooleanField DateField

步骤3:将模型类注册 到后台管理系统

military/admin.py

from .models import Weapon

admin.site.register(Weapon)

步骤4:激活数据模型

py manage.py makemigrations

py manage.py migrate

ORM在处理CRUD:

https://docs.djangoproject.com/zh-hans/2.1/ref/models/querysets/

from .models import Weapon

方式1

w1=Weapon(title="AK47")

w1.save()

方式2

w1=Weapon()

w.title="AK47"

w1.save()

Weapon.objects.all().delete()

Weapon.objects.get(title="AK47").delete()

w1=Weapon.objects.get(title="AK47")

w1.title="M16"

w1.save()

Weapon.objects.all() Weapon.objects.values("title") Weapon.objects.filter() Weapon.objects.get()

模板

模板层提供了一个对设计者友好的语法 用于渲染向用户呈现的信息

模板的api

创建

在app中 创建一个文件夹templates, 在此文件夹中创建一个和当前app名字一样的文件夹, 在此文件夹中就可以创建模板了 templates/news/newsList.html

加载

from django.template import loader

tpl=loader.get_template("news/newsList.html")

渲染

tpl.render({myId:10})

模板所支持的语法

双花括号

{{myId}}

循环

{% for tmp in myList %} <li>{{tmp}}</li> {% endfor %}

条件

{% if myId > 10 %} <p>id是大于10的</p> {% else %} <p>id是小于等于10的</p> {% endif %}