<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # WXML WXML(WeiXin Markup Language)是微信的一套標簽語言,結合基礎組件、事件系統,可以構建出頁面的結構。 *(小安娜:好像很厲害的樣子,那基礎組件、事件系統是什么?感覺更厲害,因為必須結合它們。)*,基礎組件類似HTML中的標簽,事件系統是JavaScript中的事件,可處理邏輯反應到界面上;wxml只是一個文件格式,如果沒有組件和事件它沒任何用處,又如果把組件、事件寫在txt文檔里面也沒任何用處,所以沒有誰更厲害,相輔相成的關系。*(小安娜:嗦嘎,就好像ap、ad、adc的關系,一起才最強)* 用以下一些簡單的例子來看看 WXML 具有什么能力: ## 數據綁定 WXML 中的動態數據均來自對應** Page 的 data 對象**。 ### 簡單綁定 數據綁定使用 Mustache 語法(雙大括號)將變量包起來,可以作用于以下: *(小安娜:等等,有沒有點誠意,Mustache是什么都不知道!)*,Mustache是基于JavaScript實現的模板解析引擎,等等...總之它非常方便和好用。*(小安娜:我去,你自己也不知道是什么吧)* #### 內容 ```html <view> {{ message }} </view> ``` ```javascript Page({ data: { message: 'Hello MINA!' } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-0@2x.jpg) *(小安娜:`<view>`代表什么意思,記得HTML中沒這樣的標簽啊?)*,這就是基礎組件,view組件代表視圖容器,可以理解成HTML中的DIV標簽。 #### 組件屬性(需要在雙引號之內) ```html <view id="item-{{id}}">id="item-{{id}}"</view> ``` ```javascript Page({ data: { id: 0 } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-1@2x.jpg) #### 控制屬性(需要在雙引號之內) ```html <view wx:if="{{condition}}">你看得見我嗎?</view> ``` ```javascript Page({ data: { condition: true } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-3@2x.png) *(小安娜:我剛剛試了,condition改成false就看不見我了!)*,是的,改成`false`就表示條件為假,view組件里面的內容就不會顯示了。*(小安娜:哦明白了,雖然我不想看見你,為了學好小程序還是改成true吧)* #### 關鍵字(需要在雙引號之內) `true`:boolean 類型的 true,代表真值。 `false`: boolean 類型的 false,代表假值。 ```html <checkbox checked="{{false}}" />默認沒選中 ``` **特別注意:**不要直接寫 `checked="false"`,這時候`"false"`是一個字符串,(JavaScript中非0為真、非空位真)轉成`boolean`類型后代表真值。 *(小安娜:那這個`checkbox`是不是和HTML的復選框一樣?)*,沒錯啦,但`checkbox`組件更團結,更多是以組的概念存在,例如我們都會用`checkbox-group`包括起所有同類型的`checkbox`組件,后面用到自然會明白了。*(小安娜:啊啊抓狂了,又多了個`checkbox-group`,感覺沒耐心學了)*,可別這樣想,基礎都是乏味的,可是帶你飛之前要先帶你走,下篇文章我們做案例就會感覺很有意思了。*(小安娜:知道啦,那我可以直接看下一篇不^_^)*,繼續... 所以顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-4@2x.png) ### 運算 可以在 `{{}}` 內進行簡單的運算,支持的有如下幾種方式: #### 三元運算 三元運算是:條件 ? 結果1 : 結果2;條件為ture時結果1否則結果2。 ```html <view hidden="{{flag ? true : false}}"> 看得見嗎? </view> ``` *(小安娜:`flag`我找了好久沒見你定義啊,你確定不會報錯?)*,不會的,這種變量即為空變量,(還記得前面提到過非空為真)`flag`轉成 `boolean`類型后代表`false`,也就是表達式最終是這樣的:`hidden="{{false}}"`,明白了嗎?*(小安娜:阿拉搜,繼續啦)* 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-5@2x.png) #### 算數運算 ```html <view> {{a + b}} + {{c}} + d </view> ``` ```javascript Page({ data: { a: 1, b: 2, c: 3 } }) ``` 這次就先不說結果了,小安娜,你來猜猜看結果是什么?*(小安娜:恩~,a=1,b=2,a+b就等于3,c=3,咦~,d沒定義啊?)*,結果其實是:3 + 3 + d,d不是沒定義,而它本來就是一個文字d,不參與任何計算。*(小安娜:我這么認真回答,你居然這樣坑我!!!)* 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-6@2x.png) #### 字符串運算 ```html <view>{{"hello " + name}}</view> ``` ```javascript Page({ data:{ name: 'MINA2' } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-7@2x.png) #### 數據路徑運算 如果data對象中包含了子對象,例如: ```javascript Page({ data: { object: { key: 'Hello ' }, array: ['MINA3'] } }) ``` 可以這樣訪問: ```html <view>{{object.key}} {{array[0]}}</view> ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-8@2x.png) 這個應該沒問題吧?*(小安娜:沒問題,就是點操作嘛,一個是JSON對象操作,一個是數組操作)*,OK繼續。 ### 組合 也可以在 Mustache 內直接進行組合,構成新的對象或者數組。 #### 數組 ```html <view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view> ``` ```javascript Page({ data: { zero: 0 } }) ``` *(小安娜:等等,這里我看了很久還是理解不了,再細講解下)*,好,首先我們在data對象中定義zero變量并賦值為0,然后使用view組件的`wx:for`屬性表示重復顯示這個組件,`wx:for`屬性的值是一個重新構造的數組,數組中第一個元素(也就是下標為0)的值來自于data中的zero對象,所以最終是用數組為`[0, 1, 2, 3, 4]`重復渲染組件。*(小安娜:哦哦,完~全明白了)* 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-9@2x.png) ## 條件渲染 ### wx:if `wx:if`我們之前已經用過了,用來判斷是否渲染該組件: ```html <view wx:if="{{condition}}">你看得見我嗎?</view> ``` 也可以用 `wx:elif` 和 `wx:else` 來添加其他判斷: ```html <view wx:if="{{length > 5}}"> 1 </view> <view wx:elif="{{length > 2}}"> 2 </view> <view wx:else> 3 </view> ``` ```javascript Page({ data: { length: 10 } }) ``` 界面顯示結果:1 ### block wx:if 因為 `wx:if` 是一個控制屬性,需要將它添加到一個標簽上。但是如果我們想一次性判斷多個組件,我們可以使用 `<block/>` 標簽將多個組件包裝起來,并在`block`標簽上用`wx:if`控制屬性。 ```html <block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view> </block> ``` 這里的`{{true}}`是一個`boolean`類型的值,所以最后view1、view2都會顯示。 *(小安娜:我記得你說view可以看成div,那block呢,HTML中沒這種控制標簽?)*,沒錯啦,`<block/>` 并不是一個組件,它僅是一個包裝元素,不會在頁面中做任何渲染顯示,只接受控制屬性。*(小安娜:明白了,block就好像文件夾,不占用空間,可設置文件夾顯示和隱藏)* ## 列表渲染 ### wx:for 在組件上使用 `wx:for` 控制屬性綁定一個數組數據重復渲染該組件。 默認的當前項下標變量名為: `index`,數組當前項的變量名為:`item`:*(小安娜:不默認是什么樣啊?)* ```html <view wx:for="{{array}}"> {{index}}:{{item.message}} </view> ``` ```javascript Page({ data: { array: [{ message: 'foo', }, { message: 'bar' }] } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-11@2x.png) 不使用默認可以使用 `wx:for-item` 可以指定當前元素的變量名,使用 `wx:for-index` 可以指定當前下標的變量名: ```html <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"> {{idx}}: {{itemName.message}} </view> ``` 輸出結果一樣。 ### block wx:for 類似`block wx:if`,也可以將`wx:for`用在 `<block/>`標簽上,重復渲染多組件塊。例如: ```html <block wx:for="{{['a', 'b', 'c']}}"> <view> {{index}}:{{item}}</view> </block> ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161110-12@2x.png) ### wx:key(可以選擇跳過,但,是很重要的重點) *(小安娜:突然有種想打你的沖動,又是重點又可以跳過,下課操場見!!!)*,冷靜、冷靜,官方文檔我看到這時,也是沒理解這是什么意思,后來就跳過這段了,但是也完成了B站的首頁,*(小安娜:哈~,原來是自己傻看不懂,別把我們的智商和你比好吧!)*,當寫到這時再去多看了一遍*(小安娜:絕對不止一遍)*,把官方例子運行調試之后,才發現微信官方設計`wx:key`的用意,而且是很重要的重點。 如果列表中的項目位置會改變或者有新的項目添加到列表中,為了項目保持自己的屬性和狀態(如 `<input/>` 的輸入內容,`<switch/>` 的選中狀態),需要使用`wx:key`來指定列表中項目的唯一的標識符。 **`wx:key`的值以兩種形式提供:** 1. 字符串;代表在`for`循環的`array`中`item`的某個屬性,該屬性的值是列表中唯一的字符串或數字,并且不能動態改變。 2. 保留關鍵字;`*this` 代表在`for`循環中的`item`本身,這種需要`item`本身是唯一的字符串或者數字。 是不是完全理解不了什么意思?*(小安娜:我覺得這不是重點,重點是案例你還沒講)* **案例1:`wx:key`的值是字符串** ```html <switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch> <button bindtap="switch"> 改變順序 </button> <button bindtap="addToFront"> 添加到前面 </button> ``` *(小安娜:`bindtap`是什么意思呢?)*,這個是用來綁定事件的,`bindtap`是當用戶點擊的時候會執行相對于的函數,這個馬上會在事件中詳細講解。 ```javascript Page({ data: { objectArray: [ {id: 5, unique: 'unique_5'}, {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'}, ] }, // 隨機改變列表項目順序 switch: function(e) { const length = this.data.objectArray.length for (let i = 0; i < length; ++i) { const x = Math.floor(Math.random() * length) const y = Math.floor(Math.random() * length) const temp = this.data.objectArray[x] this.data.objectArray[x] = this.data.objectArray[y] this.data.objectArray[y] = temp } this.setData({ objectArray: this.data.objectArray }) }, // 添加項目到最前面 addToFront: function(e) { const length = this.data.objectArray.length this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray) this.setData({ objectArray: this.data.objectArray }) } }) ``` *(小安娜:天了嚕,一大波代碼來襲,看不懂了啦)*,所有函數真可以不用看懂內部實現,只需知道干什么用就行*(內心的杰爾夫君:其實我知道只有她看不懂,大家照顧照顧她,假裝看不懂)(小安娜:阿丘~誰在說我壞話!)*。 顯示結果(①:初始化狀態;②:打開項目2的開關;③:改變順序后項目2依然是打開狀態;④:在最前面添加項目6,項目2依然是打開狀態),這就是`wx:key`的作用,它會利用一個唯一值保留該項狀態: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161111-33@2x.jpg) **案例2:`wx:key`的值是`*this` ** ```html <switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch> <button bindtap="addNumberToFront">添加到前面</button> ``` ```javascript Page({ data: { numberArray: [1, 2, 3, 4] }, // 添加項目到前面 addNumberToFront: function(e){ this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray) this.setData({ numberArray: this.data.numberArray }) } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161111-34@2x.jpg) ## 模板 WXML提供模板(template),可以在模板中定義代碼片段,然后在不同的地方調用。 ### 使用模板 1. 使用name屬性作為模板的名字。然后在`<template/>`內定義代碼片段。 2. 使用 is 屬性,聲明需要的使用的模板,然后將模板所需要的 data 傳入。 ```html <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template> <!-- 這里代表把item對象傳入模板 --> <template is="msgItem" data="{{...item}}"/> ``` ```javascript Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161111-0@2x.png) is 屬性可以使用 Mustache 語法來做邏輯判斷,例如以下根據條件來選擇使用模板: ```html <template name="odd"> <view> odd </view> </template> <template name="even"> <view> even </view> </template> <block wx:for="{{[1, 2, 3, 4, 5]}}"> <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/> </block> ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161111-1@2x.png) 恩~\~,這里有什么問題嗎?*(小安娜:恩~\~就是呢,不知道模板可以用在什么地方?)*,當你網站很多地方都用到同一種結構的時候就可以用了,例如我們要做的B站首頁: *(小安娜:↓↓↓藍色區域第二張圖,不謝)* ![B站首頁](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161111-12@2x.jpg) 可以看出綠、紅、藍色區域的結構都一樣,改變的只是內容,這樣的結構就很適合用模板實現。*(小安娜:那其他頁面也有這種結構呢?例如B站的直播頁也有這種結構,順便問一下為什么綠色在最前面XD)*,像這種需求我們就需要創建單獨的模板文件,在需要的地方導入模板文件就行,接下來就細講這個。 ### 導入模板 WXML 提供兩種文件引用方式`import`和`include`。 #### 帶作用域的import `import`可以導入指定文件的`template`,例如在item.wxml中定義了一個叫item的`template`: ```html <!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template> ``` 在 index.wxml 中引用了 item.wxml,就可以使用item模板: ```html <import src="item.wxml"/> <template is="item" data="{{text: 'forbar'}}"/> ``` `data="{{text: 'forbar'}}"`表示構造一個對象傳入item.wxml中item模板。 *(小安娜:顯示結果是:forbar,對吧?)*,沒錯啦,厲害了我的小姐姐;還有就是`import`有**一級作用域的概念**,例如:C import B,B import A,在C中可以使用B定義的template,在B中可以使用A定義的template,但是C不能使用A定義的template。 ```html <!-- a.wxml --> <template name="A"> <text> A template </text> </template> ``` ```html <!-- b.wxml --> <import src="a.wxml"/> <template name="B"> <text> B template </text> </template> ``` ```html <!-- index.wxml --> <import src="b.wxml"/> <template is="A"/> <!-- Error! Can not use template when not import A. --> <template is="B"/> ``` 顯示結果:B template;程序這樣寫編譯會通過,但會在控制臺(Console)報運行時警告(Runtime warn),還請注意。*(小安娜:這么大個坑,那不是debug時很難找出問題?)*,是啊,的確很難避免,很容易出錯而且找不到問題所在,但顯示結果又不對,所以我們開發的時候要多注意調試控制臺(Console)輸出的錯誤和異常信息。*(小安娜:開發果然是個細心活,同志們一起加油啦)*。 #### 頭部和底部的include `include`可以將目標文件除了`<template/>`的整個代碼引入,相當于是拷貝到`<include />`的位置,比較常用于程序的頭部(header)和底部(footer),例如: ```html <!-- header.wxml --> <view>{{header}}</view> ``` ```html <!-- footer.wxml --> <view>{{footer}}</view> ``` ```html <!-- index.wxml --> <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/> ``` 等同于 === : ```html <!-- index.wxml --> <view>{{header}}</view> <view> body </view> <view>{{footer}}</view> ``` ```javascript // index.js Page({ data: { header: "header", footer: "footer" } }) ``` 顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161113-0@2x.png) *(小安娜:發現了,它可以直接使用index.js的數據)*,沒錯,所以這種更適合**頭部和底部**數據不會隨著頁面不同而改變,而`import`更適合定義內容中模板,因為每個頁面的數據結構體是會不一樣的,例如首頁的數據結構可能是:`{channels:[music:[],dance:[],live:[]]}`,而在直播頁面中的數據結構可能是:`{lives:[]}`,2個頁面數據結構不同,這時候可以用`import`把數據重新構造傳入給模板。*(小安娜:懵懵懂懂好像明白了)*,沒關系,后面我們實戰時就會徹底明白了。*(小安娜:期待期待~)* ## 事件 事件是視圖層(wxml)到邏輯層(js)的通訊方式,可以綁定在組件上,當觸發事件,就會執行邏輯層中對應的事件處理函數。 ### 事件分類 | 類型 | 觸發條件 | | ----- | ----- | | touchstart | 手指觸摸動作開始 | | touchmove | 手指觸摸后移動 | | touchcancel | 手指觸摸動作被打斷,如來電提醒,彈窗 | | touchend | 手指觸摸動作結束 | | tap | 手指觸摸后馬上離開 | | longtap | 手指觸摸后,超過350ms再離開 | 綁定事件格式為:**`bind` + 事件類型**(例如:bindtap),我們先來看事件類型的執行順序: ```html <!-- index.wxml --> <button bindtouchstart="ontouchstart" bindtouchmove="ontouchmove" bindtouchend="ontouchend" bindtap="ontap" bindlongtap="onlongtap">點擊我<button/> ``` ```javascript Page({ ontouchstart: function() { console.log( "touchstart" ); }, ontouchmove: function() { console.log( "touchmove" ); }, ontouchend: function() { console.log( "touchend" ); }, ontap: function() { console.log( "tap" ); }, onlongtap: function() { console.log( "longtap" ); } }) ``` 當點擊(\<=350ms)的時候,執行順序: 1. touchstart 2. touchend 3. tap 當長按(\>350ms)的時候,執行順序: 1. touchstart 2. longtap 3. touchend 4. tap 我們發現點擊是我們想象中的那樣,但是長按執行一次`longtap`還會在執行一次`tap`事件,*(小安娜:那這就比較坑了,我很喜歡長按一些頭像按鈕,因為會有快捷操作菜單)*,是啊,我知道長按這個操作在Android是很常用的設計,所以我們在小程序里面盡量避免設計某個組件有長按又有點擊事件。*(小安娜:因為這個操作太好用了,沒有解決辦法嗎?)*,可以在`data`里面設置一個判斷長按的變量,當`touchstart`的時候設置此變量為`false`,當執行`longtap`事件的時候設置變量為`true`,然后在`tap`事件里面做判斷就行了。 ```html Page({ data: { islongtap: false }, ontouchstart: function() { this.islongtap = false; console.log( "touchstart" ); }, ontap: function() { if( this.islongtap ) return ; console.log( "tap" ); }, onlongtap: function() { this.islongtap = true; console.log( "longtap" ); } }) ``` *(小安娜:perfect,運行了下完美解決)* 像js的事件一樣,小程序事件也分為**冒泡事件**和**非冒泡事件**: ```html <view id="outter" bindtap="handleTap1"> <view id="middle" bindtap="handleTap2"> <button id="inner" bindtap="handleTap3"> 操作按鈕 </button> </view> </view> ``` ```javascript Page({ handleTap1: function() { console.log( "handleTap1" ); }, handleTap2: function() { console.log( "handleTap2" ); }, handleTap3: function() { console.log( "handleTap3" ); } }) ``` 這是一個常用的結構,一個大的層包含內部很多小層,小層內部有個操作按鈕,當我們點擊操作按鈕: 1. handleTap3 2. handleTap2 3. handleTap1 發現所有父組件的點擊事件都執行了,這就是冒泡事件:當一個組件上的事件被觸發后,該事件會向父節點傳遞。非冒泡事件就是不會向父節點傳遞。當然這很多時候不是件好事情,怎么避免呢? 小程序除了提供`bind`還提供`catch`綁定事件,格式為:**`catch` + 事件類型**,`catch`事件綁定可以阻止向上冒泡。現在在`button`上改用`catch`試一下: ```html <view id="outter" bindtap="handleTap1"> <view id="middle" bindtap="handleTap2"> <button id="inner" catchtap="handleTap3"> 操作按鈕 </button> </view> </view> ``` 輸出結果:handleTap3,達到我們的效果了。*(小安娜:我覺得把父組件的綁定事件去掉更好)* ### 事件參數event 當組件觸發事件時,處理函數會收到一個事件對象參數。 ```javascript Page({ handleTap3: function(event) { console.log( event ); } }) ``` 控制臺輸出的結果: ```javascript { // 代表事件的類型 "type": "tap", // 頁面打開到觸發事件所經過的毫秒數 "timeStamp": 2239, // 觸發事件的源組件 "target": { // 事件源組件的id "id": "inner", // 距離左方或上層控件的位置(官方文檔未說明) "offsetLeft": 0, // 距離上方或上層控件的位置(官方文檔未說明) "offsetTop": 0, // 事件源組件上由data-開頭的自定義屬性組成的集合 "dataset": {} }, // 事件綁定的當前組件,數據格式同 target "currentTarget": { "id": "inner", "offsetLeft": 0, "offsetTop": 0, "dataset": {} }, // 額外的數據信息 "detail": { "x": 280, "y": 18 }, // touches 是一個數組,每個元素為一個 Touch 對象(canvas 觸摸事件中攜帶的 touches 是 CanvasTouch 數組)。 表示當前停留在屏幕上的觸摸點。 "touches": [ { // 觸摸點的標識符 "identifier": 0, // 距離文檔左上角的距離,文檔的左上角為原點 ,橫向為X軸 "pageX": 280, // 距離文檔左上角的距離,文檔的左上角為原點 ,縱向為Y軸 "pageY": 18, // 距離頁面可顯示區域(屏幕除去導航條)左上角距離,橫向為X軸 "clientX": 280, // 距離頁面可顯示區域(屏幕除去導航條)左上角距離,縱向為Y軸 "clientY": 18 } ], // changedTouches 數據格式同 touches。 表示有變化的觸摸點,如從無變有(touchstart),位置變化(touchmove),從有變無(touchend、touchcancel)。 "changedTouches": [ { "identifier": 0, "pageX": 280, "pageY": 18, "clientX": 280, "clientY": 18 } ] } ``` 每個參數具體什么意思,我們放在以后B站項目中去講解,*(小安娜:噗~,我好多問題準備問了,現在又憋回去了,聽你講東西真心累)*,畢竟太多了,每個都講到估計可以寫幾篇文章了,用到什么再回頭來看看,然后再配合案例這樣最容易理解了。*(小安娜:好像也是,總感覺哪里不對,等等...要是你不用到呢)*,這個保證不會,因為有我們常用的`dataset`,經常會為組件自定義一些參數。*(小安娜:姑且相信你)* # WXSS - WXSS(WeiXin Style Sheets)是一套樣式語言,用于描述 WXML 的組件樣式。 - 用來決定 WXML 的組件應該怎么顯示。 - 具有 CSS 大部分特性。 - 定義在 app.wxss 中的樣式為全局樣式,可用于任何Page。在 Page 里的 wxss 文件中定義的樣式為局部樣式,只作用在當前頁面,并會覆蓋 app.wxss 中相同的選擇器。 與 CSS 相比增加的特性有: - 尺寸單位 - 樣式導入 ## 尺寸單位rpx rpx(responsive pixel): 可以根據屏幕寬度進行自適應。規定屏幕寬為750rpx。如在 iPhone6 上,屏幕寬度為375px,共有750個物理像素,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。*(小安娜:真啰嗦,也就是1px = 2rpx嘛)* | 設備 | rpx換算px (屏幕寬度/750) | px換算rpx (750/屏幕寬度) | | ------ | ------ | ------ | | iPhone5 | 1rpx = 0.42px| 1px = 2.34rpx | | iPhone6/6s | 1rpx = 0.5px| 1px = 2rpx | | iPhone6/6s Plus | 1rpx = 0.552px| 1px = 1.81rpx | **所以:**我們設計/開發微信小程序時都應該用 iPhone6s 作為視覺稿的標準。*(小安娜:所以,看你教程是不是有福利,會給我們發iPhone 6s嗎?)* ## 樣式導入 使用`@import`語句導入外聯樣式表,`@import`后跟樣式表的相對路徑。 ```css /* common.wxss */ .header, .footer { padding: 20rpx 0; text-align: center; font-size: 50rpx; } ``` ```css /* index.wxss */ @import "common.wxss"; .content { line-height: 50rpx; } ``` ```html <view class="header">header</view> <view class="content" style="color:#e64340;">和小安娜一塊去超市買東西,小安娜:“好想吃泡面,可是怕上火啊”;我:“那就不要買了”;小安娜:“不行,再去買一罐加多寶吧”;我:...</view> <view class="footer">footer</view> ``` 這樣就在`index.wxss`中導入了`common.wxss`樣式文件,顯示結果: ![顯示結果](http://ctt.jieerf.com/wp-content/uploads/2016/11/QQ20161114-2@2x.png) *(小安娜:你怎么?不過用加多寶泡泡面還真挺好吃。喂,快說正事啦,我發現你使用了行內樣式`style="color:#e64340;"`)*,wxss也支持行內樣式,不過盡量避免將靜態的樣式寫入style中,以免影響渲染速度,靜態樣式都應該寫在wxss文件中。 ## 目前支持的選擇器 | 選擇器 | 樣例 | 樣例描述 | | ----- | ----- | ----- | | .class | .intro | 選擇所有擁有 class="intro" 的組件 | | #id | #firstname | 選擇擁有 id="firstname" 的組件 | | element | view | 選擇所有 view 組件 | | element, element | view,.header | checkbox 選擇所有文檔的 view 組件和所有的 checkbox 組件 | | ::after | view::after | 在 view 組件后邊插入內容 | | ::before | view::before | 在 view 組件前邊插入內容 | **注意:**結果筆者開發試驗,暫時還不支持\*選擇器(所有元素),例如我們經常會設置所有組件的`box-sizing`屬性來改變測量寬度的起點邊界,從而使規定寬度包括邊框和填充: ```css * { box-sizing: border-box; } ``` 使用之后會發現所有`wxss`文件中的樣式都無效了。*(小安娜:那可以怎么解決呢,難道給每個組件都設置一次?)*,小哥哥不才,目前還真是每個組件都設置一次,或者這問題官方會很快解決。*(小安娜:也是,還是官方靠譜點。)* # 記得官方文檔 了解到這,基礎知識終于告一段落了,下一篇開始實戰,開發時更多組件知識請參考官方文檔。 - 開發工具介紹和下載:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/devtools.html - 注冊流程:https://mp.weixin.qq.com/debug/wxadoc/introduction/index.html - 開發組件:https://mp.weixin.qq.com/debug/wxadoc/dev/component/ - 開發API:https://mp.weixin.qq.com/debug/wxadoc/dev/api/ - 問題交流:QQ群:301926812(非官方) 寫了這么多口好干,我需要倒杯水喝,等等我。*(小安娜:去吧去吧)*,「滴答、滴答,過去5分鐘...10分鐘...」*(小安娜:喂喂,10分鐘了,你是喝一桶水嗎?)*,(遠處的聲音:quatary kill!WO CAO,要超神了),*(小安娜:我去,喝個水時間去開黑了,快滾回來,馬上到我的提問環節了!)*,都怪你了,一開始就說什么ap、ad、adc,搞的我熱血沸騰的,馬上來了。 # 小安娜有問題 ## WXML是什么? **杰爾夫君**:WXML(WeiXin Markup Language)是一套標簽語言,結合基礎組件、事件系統,可以構建出頁面的結構。和HTML相似。 ## WXML組件怎么綁定數據? **杰爾夫君:**WXML中的動態數據均來自對應 Page 的 data。數據綁定使用 Mustache 語法(雙大括號)將變量包起來。例如: ```javascript Page({ data: { message: 'Hello MINA!' } }) ``` ```html <!-- 綁定Page中的data.message --> <view> {{ message }} </view> ``` ## 什么是Mustache? **杰爾夫君:**Mustache 是一個 logic-less (輕邏輯)模板解析引擎。在小程序里主要關注小程序的語法。詳細了解前往:http://www.open-open.com/lib/view/open1416792564461.html ## WXML中怎么使用條件判斷? **杰爾夫君:**在框架中,我們用 `wx:if="{{condition}}"` 來判斷是否需要渲染該代碼塊: ```html <view wx:if="{{condition}}"> True </view> ``` 也可以用 `wx:elif` 和 `wx:else` : ```html <view wx:if="{{length > 5}}"> 1 </view> <view wx:elif="{{length > 2}}"> 2 </view> <view wx:else> 3 </view> ``` 如果想一次性判斷多個組件標簽,我們可以使用一個 `<block/>` 標簽將多個組件包裝起來: ```html <block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view> </block> ``` ## WXML怎么循環列表? **杰爾夫君:**在組件上使用`wx:for`屬性綁定一個數組,即可使用數組中的數據重復渲染該組件,默認當前的下標變量名為`index`,當前項的變量名為`item`。用`wx:for-index`指定當前下標的變量名,用`wx:for-item`指定當前元素的變量名; ```html <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"> {{idx}}: {{itemName.message}} </view> ``` 等等,怎么感覺你從頭到尾都有問題啊,感覺沒學過一樣?*(小安娜:沒辦法啦,這次講太多了,本小姐記憶不太好,都不記得學了什么)*,好吧好吧,也正好總結一下,繼續你的問題。*(小安娜:你別打斷啊!)* ## WXML怎么使用模板? **杰爾夫君:**用`<template/>`定義模板,指定`name`屬性為模板的名字,用`is`屬性指定使用模板的名稱,然后將模板所需要的`data`傳入,如: ```html <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template> ``` ```html <!-- 參數傳入Page中的data.item --> <template is="msgItem" data="{{...item}}"/> ``` ```javascript Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } } }) ``` 也可以把模板定義在單獨文件中,通過`import`或`include`引入。 ```html <!-- import --> <!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template> <!-- index.wxml --> <import src="item.wxml"/> <template is="item" data="{{text: 'forbar'}}"/> ``` ```html <!-- include --> <!-- header.wxml --> <view> header </view> <!-- footer.wxml --> <view> footer </view> <!-- index.wxml --> <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/> ``` `import`和`include`區別是:`import`有一層作用域概念,即C import B,B import A,在C中可以使用B的template,在B中可以使用A的template,但是C不能使用A定義的template。而`include`相當于是拷貝,使用原頁面數據。 ## WXML中怎么使用事件? **杰爾夫君:**使用`bind`或`catch`開頭,然后跟上事件的類型(如:bindtap, catchtouchstart),`bind`事件綁定會發生事件冒泡,catch事件綁定可以阻止冒泡事件向上冒泡。 ## 什么是WXSS? **杰爾夫君:**WXSS(WeiXin Style Sheets)是一套樣式語言,用于描述 WXML 的組件樣式。WXSS 具有 CSS 大部分特性。 同時為了更適合開發微信小程序,對 CSS 進行了擴充以及修改了:尺寸單位、樣式導入。 ### 尺寸單位 rpx(responsive pixel): 可以根據屏幕寬度進行自適應。規定屏幕寬為750rpx。以iPhone6為例:1rpx = 0.5px,1px = 2rpx。 ### 樣式導入 使用`@import`語句導入外部樣式,`@import`后跟外部樣式文件的相對路徑。 ```css @import "common.wxss"; .middle-p { padding:15px; } ``` *(小安娜:嗯~\~,我問完了)*,好的今天就到這了,今天學的比較多,希望多多復習交流,記住我們的交流QQ群:301926812(非官方的也很營養),*(小安娜:好的,已經加了,撒喲啦啦!)*
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看