小程序學習筆記三:頁面文件詳解之視圖層WXML、WXS、WXSS文件


    視圖層:Pages主要有 wxml頁面文件和模板文件、wxs腳本文件、wxss樣式文件;component是抽取出來的業務單元,同樣擁有wxml頁面文件和模板文件、wxs腳本文件、wxss樣式文件。

    WXML(WeiXin Markup language) 用於描述頁面的結構。

    WXS(WeiXin Script) 是小程序的一套腳本語言,結合 WXML,可以構建出頁面的結構。

    WXSS(WeiXin Style Sheet) 用於描述頁面的樣式。

    組件(Component)是視圖的基本組成單元。

 

    一:WXML:WXML(WeiXin Markup Language)是一套標簽語言,結合基礎組件、事件系統,可以構建出頁面的結構。

    MVVM模式:

    在網頁的一般開發流程中,我們通常會通過 JS 操作 DOM (對應 HTML 的描述產生的樹),以引起界面的一些變化響應用戶的行為。例如,用戶點擊某個按鈕的時候,JS 會記錄一些狀態變化到 JS 變量里邊,同時通過 DOM API 操控 DOM 的屬性或者行為,進而引起界面一些變化

    當項目越來越大的時候,你的代碼會充斥着非常多的界面交互邏輯和程序的各種狀態變量,顯然這不是一個很好的開發模式。

     MVVM 的開發模式把渲染和邏輯分離:不讓 JS 直接操控 DOM,JS只需要管理狀態(數據)變化即可;然后再通過一種模板語法來描述狀態和界面結構的關系,將狀態(數據)變化實時更新到界面

     MVVM在微信小程序開發中的實現:通過數據綁定,將狀態(數據)在界面上顯示;通過 WXS腳本語言,根據狀態(數據)動態決定頁面結構

     通過 {{ }} 的語法把一個變量綁定到界面上,我們稱為數據綁定。僅僅通過數據綁定還不夠完整的描述狀態和界面的關系,還需要 if/else, for等控制能力,在小程序里邊,這些控制能力都用 wx: 開頭的wxs語法來表達

   

    1)數據綁定

    簡單數據綁定:使用 Mustache 語法(雙大括號)將要綁定的變量包起來。數據在js文件中定義,在wxml文件中綁定。

Page({
  data: { //定義數據
    message: 'Hello world!'
  } 
})
<view> {{ message }} </view> //數據綁定到頁面

    組件屬性綁定:wxml中組件的屬性值也可以通過數據綁定來賦值。

<view id="{{數據名}}"> </view>

    條件語句值綁定:條件語句的值也可以通過數據綁定來賦值。

<view wx:if="{{condition}}"> </view>
Page({
  data: {
    condition: true //條件語句的值
  }
})

    關鍵字綁定:對於一些關鍵字、保留字,需要在  {{關鍵字}}  內才能起作用,如果只有雙引號、沒有雙括號,則只是作為一個字符串而已。

<checkbox checked="{{false}}"> </checkbox>
//不要直接寫 checked="false",其計算結果是一個字符串,轉成 boolean 類型后代表真值。

    運算結果綁定:可以在  {{表達式}}  內進行運算,將結果綁定到頁面。

運算支持:
三目運算:conditions ? val1 : val2
算術運算:+-*/
比較運算:> < == 等
點運算符:對象.屬性
索引運算:數組對象[index]
組合成數組:{{[var...]}}
組合成對象:{{屬性1:值,屬性2:值,屬性3:值...}}
展開一個對象:{{...object}} //用 ... 運算符將對象展開成 鍵值對 的形式

    【特別注意:花括號和引號之間如果有空格,將最終被解析成為字符串。】

 

   2)wxs渲染控制語句

   2.1)條件控制語句:

//條件語句是在view屬性中定義的,當條件成立時,該view就被繪制 <view wx:if="{{條件1}}"> 內容</view>
<view wx:elif="{{條件2}}"> 內容</view>
<view wx:else> 內容 </view>

   如果要一次性判斷多個組件標簽,可以使用一個 <block/> 標簽將多個組件包裝起來,並在block標簽使用 wx:if 控制屬性:

<block wx:if="{{條件}}">
  <view> view1 </view>
  <view> view2 </view>
</block>
wx:if vs hidden

因為 wx:if 之中的模板也可能包含數據綁定,所有當 wx:if 的條件值切換時,框架有一個局部渲染的過程,因為它會確保條件塊在切換時銷毀或重新渲染。

同時 wx:if 也是惰性的,如果在初始渲染條件為 false,框架什么也不做,在條件第一次變成真的時候才開始局部渲染。

相比之下,hidden 就簡單的多,組件始終會被渲染,只是簡單的控制顯示與隱藏。

一般來說,wx:if 有更高的切換消耗而 hidden 有更高的初始渲染消耗。因此,如果需要頻繁切換的情景下,用 hidden 更好,如果在運行時條件不大可能改變則 wx:if 較好。

  

    2.2)循環語句

    組件上使用 wx:for 控制屬性綁定一個數組,即可使用數組中各項的數據重復渲染該組件

//默認數組的當前項的下標變量名默認為 index,數組當前項的變量名默認為 item
<view wx:for="{{array}}">
  {{index}}: {{item}}
</view>

    也可以使用 wx:for-item 可以指定數組當前元素的變量名,使用 wx:for-index 可以指定數組當前下標的變量名:

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName}}
</view>

    重復渲染多個組件,可以用一個block標簽把他們組成塊:

<block wx:for="{{array}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>

   

    優化:使用wx:key避免被重新繪制、丟失狀態。

    如果view數組的view組件數量會動態增減或者view組件位置會動態變化,這些變化會引起view數組重新繪制,那么某個被重繪的view組件當前的狀態可能會丟失(如:input接收的輸入、switch開關的狀態)。

    若想要保持住這些狀態數據,可以使用 wx:key 來避免組件被重繪。當數據改變觸發渲染層重新渲染的時候,會校正帶有 key 的組件,框架會確保他們被重新排序,而不是重新創建,以確保使組件保持自身的狀態,並且提高列表渲染時的效率。

wx:key 的值以兩種形式提供:
    字符串:使用array中item 的某個屬性值,該屬性值需要是數組中唯一的字符串或數字且不能動態改變。
    保留關鍵字*this:使用item本身,這種表示需要 item 本身是一個唯一的字符串或者數字
//使用 item 的屬性值作key
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>

objectArray: [
      {id: 5, unique: 'unique_5'}, //每個item的unique屬性值均唯一
      {id: 4, unique: 'unique_4'},
      {id: 3, unique: 'unique_3'},
      {id: 2, unique: 'unique_2'},
      {id: 1, unique: 'unique_1'},
      {id: 0, unique: 'unique_0'},
    ],


//使用 *this 作為key
<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>

numberArray: [1, 2, 3, 4]

 

 3)WXML模版

    對於可以在不同頁面出現的頁面結構,我們可以提取成為一個WXML模版,然后在不同的wxml文件引入這個模版並為模版傳具體值,就可以復用這個頁面結構了。

    【注意區分:wxml模版是界面結構的重用;自定義組件則是功能結構的重用】

    3.1)模版定義:

    可以新建一個template目錄,專門用於存放wxml模版文件。模版文件也是wxml文件,以wxml為后綴名。模版部分界面結構用 template 括住:

//header.wxml 頁面頭部模版文件示例
<template name="header">
  <view class="left">
    左邊內容
 </view>
 <view class="center">
    中間內容
 </view>
 <view class="right">
    右邊內容
 </view>
</template>

    在模版文件中,也可以使用wxs語法進行組件的條件渲染、列表渲染。

    3.2)使用模版

   使用 is 屬性聲明需要的使用的模板,然后將模板所需要的 data 傳入。data的格式需要符合模板中數據綁定的格式(類型、變量名都要對應上)

<import src="模板文件相對路徑"/> //導入模板
<template is="模板名" data="{{模板需要的數據}}" />  //傳遞數據,適用模板

    is 屬性可以使用 Mustache 語法,動態決定具體需要渲染哪個模板:

<template is="{{條件 ? '模版名1' : '模板名2'}}"/>

 

    4)引用

    WXML 提供兩種文件引用方式importinclude

    4.1)import可以在該文件中使用目標文件定義的template,上面模板使用已經示范過了。

    4.2)include 可以將目標文件除了 <template/> <wxs/> 外的整個代碼引入,相當於是拷貝到 include 位置。

 

    5)視圖層事件

    5.1)事件分為冒泡事件和非冒泡事件:

  1. 冒泡事件:當一個組件上的事件被觸發后,該事件會向父節點傳遞。
  2. 非冒泡事件:當一個組件上的事件被觸發后,該事件不會向父節點傳遞。

   

    WXML的冒泡事件列表:

類型 觸發條件 最低版本
touchstart 手指觸摸動作開始  
touchmove 手指觸摸后移動  
touchcancel 手指觸摸動作被打斷,如來電提醒,彈窗  
touchend 手指觸摸動作結束  
tap 手指觸摸后馬上離開  
longpress 手指觸摸后,超過350ms再離開,如果指定了事件回調函數並觸發了這個事件,tap事件將不被觸發 1.5.0
longtap 手指觸摸后,超過350ms再離開(推薦使用longpress事件代替)  
transitionend 會在 WXSS transition 或 wx.createAnimation 動畫結束后觸發  
animationstart 會在一個 WXSS animation 動畫開始時觸發  
animationiteration 會在一個 WXSS animation 一次迭代結束時觸發  
animationend 會在一個 WXSS animation 動畫完成時觸發

    注:除上表之外的其他組件自定義事件如無特殊聲明都是非冒泡事件,如<form/>submit事件,<input/>input事件,<scroll-view/>scroll事件。

 

    5.2)事件的綁定

   事件綁定的寫法同組件的屬性,以 key、value 的形式。

  • key 以bindcatch開頭,然后跟上事件的類型,如bindtapcatchtouchstartbindcatch后可以緊跟一個冒號再跟事件類型,其含義不變,如bind:tap、、catch:touchstart
  • value 是一個字符串,需要在對應的 Page 中定義同名的事件處理函數。

  bind事件綁定不會阻止冒泡事件向上冒泡,catch事件綁定可以阻止冒泡事件向上冒泡。

    

    5.3)事件處理的流程

    事件處理可以包括兩個階段:事件捕獲階段(從界面父節點向組件子節點傳遞,被捕獲)、事件處理階段(冒泡的事件會從組件子節點開始處理,逐層向父節點傳播,被處理【除非被catch阻止了】)

    捕獲事件可以采用capture-bindcapture-catch關鍵字,后者將中斷捕獲階段和取消冒泡階段。

 

    5.4)事件處理函數

    當組件觸發事件時,邏輯層綁定該事件的處理函數會收到一個事件對象,根據事件類型的不同,事件對象攜帶的信息也不同。

    BaseEvent 基礎事件對象屬性列表:

屬性 類型 說明
type String 事件類型
timeStamp Integer 事件生成時的時間戳
target Object 觸發事件的組件的一些屬性值集合
currentTarget Object 當前組件的一些屬性值集合

   

    CustomEvent 自定義事件對象屬性列表(繼承 BaseEvent):

屬性 類型 說明
detail Object 額外的信息

   

    TouchEvent 觸摸事件對象屬性列表(繼承 BaseEvent):

屬性 類型 說明
touches Array 觸摸事件,當前停留在屏幕中的觸摸點信息的數組
changedTouches Array 觸摸事件,當前變化的觸摸點信息的數組

    其中的幾個Object類型參數主要包含信息如下:

    target:觸發事件的源組件。

屬性 類型 說明
id String 事件源組件的id
tagName String 當前組件的類型
dataset Object 事件源組件上由data-開頭的自定義屬性組成的集合

    currentTarget:事件綁定的當前組件。

屬性 類型 說明
id String 當前組件的id
tagName String 當前組件的類型
dataset Object 當前組件上由data-開頭的自定義屬性組成的集合

 

     Touch 對象

屬性 類型 說明
identifier Number 觸摸點的標識符
pageX, pageY Number 距離文檔左上角的距離,文檔的左上角為原點 ,橫向為X軸,縱向為Y軸
clientX, clientY Number 距離頁面可顯示區域(屏幕除去導航條)左上角距離,橫向為X軸,縱向為Y軸

 

    二:WXS:WXS(WeiXin Script)是小程序的一套腳本語言,結合 WXML,可以構建出頁面的結構。

    【wxs 的運行環境和其他 javascript 代碼是隔離的,wxs 中不能調用其他 javascript 文件中定義的函數,也不能調用小程序提供的API。】

     WXS 代碼可以編寫在 wxml 文件中的 <wxs> 標簽內,或以 .wxs 為后綴名的文件內。

     2.1)模塊

    每一個 .wxs 文件和 <wxs> 標簽都是一個單獨的模塊,一個模塊要想對外暴露其內部的私有變量與函數,只能通過 module.exports 實現

     2.2)WXS文件中定義module

    每個 wxs 模塊均有一個內置的 module 對象,用於導出模塊內數據與函數。

var ref = require("./ref.wxs");   //引用其他wxs模塊

var foo = 定義變量;
var bar = function (param) {
  ref.var; //調用引用模塊的變量
  ref.func();//調用引用模塊的函數
  方法體;
} 
module.exports = { //導出變量、函數,並且指明導出名(用於調用)
  FOO: foo,
  bar: bar,
};

    在wxml中使用wxs模塊文件:

<wxs src="./../ref.wxs" module="ref" /> //定義module標簽,創建一個module;並且通過src屬性指明module的定義源文件路徑

<view> {{ref.var}} </view> //通過module名調用數據、函數
<view> {{ref.func(param)}} </view>

 

    2.3)wxs標簽中定義module

    module 屬性是當前 <wxs> 標簽的模塊名。

<wxs module="模塊名"> //1:通過 wxs 標簽創建模塊
var 變量 =值; //2:在模塊內定義變量、函數
module.exports = {
    導出名 : 變量, //3:導出模塊內容
}
</wxs>
<view> {{模塊名.變量/函數}} </view> //4:調用模塊內容
  • <wxs> 模塊只能在定義模塊的 WXML 文件中被訪問到。使用 <include><import> 時,<wxs> 模塊不會被引入到對應的 WXML 文件中。
  • <template> 標簽中,只能使用定義該 <template> 的 WXML 文件中定義的 <wxs> 模塊。

    2.4)語句

    if語句:

// if ...

if (表達式) 語句;

if (表達式) 
  語句;

if (表達式) {
  代碼塊;
}


// if ... else 

if (表達式) 語句;
else 語句;

if (表達式) 
  語句;
else 
  語句;

if (表達式) {
  代碼塊;
} else {
  代碼塊;
}

// if ... else if ... else ...

if (表達式) {
  代碼塊;
} else if (表達式) {
  代碼塊;
} else if (表達式) {
  代碼塊;
} else {
  代碼塊;
}

    switch語句:

switch (表達式) {
  case 變量:
    語句;
  case 數字:
    語句;
    break;
  case 字符串:
    語句;
  default:
    語句;
}

     for語句:

for (語句; 語句; 語句)
  語句;

for (語句; 語句; 語句) {
  代碼塊;
}

    while語句:

while (表達式)
  語句;

while (表達式){
  代碼塊;
}

do {
  代碼塊;
} while (表達式)

    2.5)數據類型

    number : 數值
    string :字符串
    boolean:布爾值
    object:對象(無序鍵值對,用 {} 來定義)
    function:函數 
    array : 數組
    date:日期
    regexp:正則
//函數的兩種定義方式
function a (x) {
  return x;
}

//方法 2
var b = function (x) { 
  return x;
}

     2.6)基礎類庫

console類庫:控制台類庫,可以調用log方法打印信息。
Math類庫:數學常量、函數。
Json類庫:Json與字符串互相轉換。
Number類庫:最大最小數字常量。
Date類庫:日期相關。
Global類庫:類型轉換函數、判斷有效值等。

 

    :WXSS樣式文件

    3.1)選擇器

.class     .intro     選擇所有擁有 class="intro" 的組件
#id     #firstname     選擇擁有 id="firstname" 的組件
element     view     選擇所有 view 組件
element, element     view, checkbox     選擇所有文檔的 view 組件和所有的 checkbox 組件
::after     view::after     在 view 組件后邊插入內容
::before     view::before     在 view 組件前邊插入內容

    3.2)定義wxss文件

選擇器 {
  樣式定義(鍵值對);
  ...
}

      3.3)wxml文件中使用樣式【小程序根據 同名  規則,將同名的 wxml、wxss、js文件自動引用,無需導入,只需使用相關名稱來調用即可】

<view style="樣式屬性定義;" />
<view class="某種已經定義好樣式的類選擇器" />

    3.4)wxss文件之間的引用

    我們在定義某個wxss文件時,如果某些樣式已經在別處定義過,那么可以將別處的樣式導入進來,無需重復定義。

    使用@import語句可以導入外聯樣式表,@import后跟需要導入的外聯樣式表的相對路徑,用;表示語句結束。

@import "./../路徑/名字.wxss";


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM