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 包含
<!DOCTYPE html> <html lang="en"> <head> <title>My title</title> </head> <body> <a href="">My Link</a> <h1>My header</h1> </body> </html>
節點遍歷
在元素節點中提取自己所需的節點,并予以操作。
節點類型
常用節點類型
不同節點對應的NodeType類型
此值可以通過 Node.nodeType 來獲取。
1元素,2屬性,3文本,8注釋,9文檔等比較常用。還有平常說的元素 其實指的是節點中得元素節點,所以說節點包含元素,節點還包括文本節點、實體節點等。
T之家 2 月 10 日消息,華為技術有限公司的江英杰為大家揭曉了關于開源鴻蒙 OpenHarmony 3.1 Beta 版中的一個關鍵特性,也就是 ArkUI 開發框架中的 canvas 畫布。
據介紹,canvas 是 ArkUI 開發框架里的畫布組件,常用于自定義繪制圖形。因為其輕量、靈活、高效等優點,被廣泛應用于 UI 界面開發中。本期,我們將為大家介紹 ArkUI 開發框架中 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 組件在 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 %}
*請認真填寫需求信息,我們會在24小時內與您取得聯系。