初識小程序-視圖層

視圖層

框架的視圖層由WXML(WeiXin Markup language)與WXSS(WeiXin Style Sheet)編寫,由組件來進(jìn)行展示。對于微信小程序而言,視圖層就是所有.wxml文件與.wxss文件的集合。
微信小程序在邏輯層將數(shù)據(jù)進(jìn)行處理后發(fā)送給視圖層展現(xiàn)出來,同時接受視圖層的事件反饋。

■.wxml文件用于描述頁面的結(jié)構(gòu)。
■.wxss文件用于描述頁面的樣式。
視圖層以給定的樣式展現(xiàn)數(shù)據(jù)并將事件反饋給邏輯層,而數(shù)據(jù)展現(xiàn)是以組件來進(jìn)行的。組件(Component)是視圖的基本組成單元,是構(gòu)建.wxml文件必不可少的。
對于小程序的WXML編碼開發(fā),基本上可認(rèn)為就是使用組件、結(jié)合事件系統(tǒng),構(gòu)建頁面結(jié)構(gòu)的過程。.wxml文件中所綁定的數(shù)據(jù),均來自于對應(yīng)頁面的.js文件中Page方法的data對象。

WXML

WXML是框架設(shè)計(jì)的一套類似HTML的標(biāo)簽語言,結(jié)合基礎(chǔ)組件、事件系統(tǒng),可以構(gòu)建出頁面的結(jié)構(gòu),即.wxml文件。

.wxml文件第一行建議寫。比如logs頁面的wxml文件(logs. wxml)如下:

<!--logs.wxml-->
<view class="container log-list">
    <block wx:for="{{logs}}" wx:for-item="log">
        <text class="log-item">{{index+1}}.{{log}}</text>
    </block>
</view>

上述代碼,我們通過組件控制頁面內(nèi)容展現(xiàn),通過組件與組件實(shí)現(xiàn)頁面數(shù)據(jù)的綁定;

WXML具有數(shù)據(jù)綁定、列表渲染、條件渲染、模板及事件綁定的能力:

1)數(shù)據(jù)綁定:
//wxml
<view>{{message}}</view>
//page.js
Page({
    data:{
        message:'hello MINA'
  }
})
上例中,在.wxml文件中綁定message變量,在.js文件的data對象中給message賦值“hello MINA ”

2)列表渲染:
//wxml
<view wx:for="{{array}}">{{item}}</view>
//page.js
Page({
    data:{
        array:[1,2,3,4,5]
  }
})

3)條件渲染:
//wxml
<view wx:if="{{view=='WEBVIEW'}}">WEBVIEW</view>
<view wx:elif="{{view=='APP'}}">APP</view>
<view wx:else="{{view=='MINA'}}">MINA</view>
//page.js
Page({
    data:{
        view:'MINA'
  }
})

4)模板:
//wxml
<template name="staffName">
  <view>FirstName:{{firstName}},LastName:{{lastName}}</view>
</template>

<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>

//Pages.js
Page({
    data:{
        staffA:{firstName:'hh',lastName:'hhh'},
        staffB:{firstName:'bb',lastName:'bbb'},
        staffC:{firstName:'cc',lastName:'ccc'}
  }
})
注:字例代碼中,“...”為擴(kuò)展運(yùn)算符,用它來展開一個對象,如staffA對象。

5)事件綁定:
//wxml
<view bindtap="add">{{count}}</view>
//page.js
Page({
    data:{
        count:1
  },
    add:function(e){
      this.setData({
          count:this.data.count+1
      })  
  }
})

1.?dāng)?shù)據(jù)綁定

.wxml文件中的動態(tài)數(shù)據(jù)均來自對應(yīng)頁面的.js文件中Page的data對象。

(1)簡單綁定

數(shù)據(jù)綁定使用Mustache語法(即“雙大括號”語法)將變量包起來,可以作用于:

1).內(nèi)容:
<!--wxml-->
<view>{{content}}</view>
//page.js
Page({
    data:{
        content:'hello world'
    }
})

2).組件屬性(需要在雙引號之內(nèi)):
<!--wxml-->
<view id="item-{{id}}">{{content}}</view>
//page.js
Page({
    data:{
        content:'hello world',
        id:0
    }
})

3).控制屬性(需要在雙引號之內(nèi)):
<!--wxml-->
<view wx:if="{{condition}}">{{content}}</view>
//page.js
Page({
    data:{
        content:'hello world',
        condition:true
    }
})
(2)運(yùn)算

可以在{{}}內(nèi)進(jìn)行簡單的運(yùn)算,支持如下幾種方式;

1).三元運(yùn)算:
<!--wxml-->
<view hidden="{{flag?true:false}}">Hidden</view>

2).算數(shù)運(yùn)算:
<!--wxml-->
<view>{{a+b}}+{{c}}+d</view>
//page.js
Page({
    data:{
        a:1,
        b:2,
        c:3
    }
})
view中的內(nèi)容為3+3+d

3).邏輯判斷:
<view wx:if="{{length>5}}"></view>

4).字符串運(yùn)算:
<!--wxml-->
<view>{{"hello"+name}}</view>
//page.js
Page({
    data:{
        name:'MINA'
    }
})

5).數(shù)據(jù)路徑運(yùn)算:
<view>{{object.key}}{{array[0]}}</view>
Page({
    data:{
      object:{
          key:'hello'
      },
      array:['world']
    }
})
(3)組合

也可以在Mustache內(nèi)直接進(jìn)行組合,構(gòu)成新的對象或者數(shù)組。

1).數(shù)組
<!--wxml-->
<view wx:for="{{[zero,1,2,3,4]}}">{{item}}</view>
//page.js
Page({
    data:{
        zero:0
    }
})
最終組合成數(shù)組[0, 1, 2, 3, 4]。

2).對象
<!--wxml-->
<template is="objectCombine" data="{{for:a, bar:b}}"></template>
//page.js
Page({
    data:{
        a:1,
        b:2
    }
})
最終組合成的對象是{for: 1, bar: 2}

3).也可以用擴(kuò)展運(yùn)算符. ..來將一個對象展開:
<!--wxml-->
<template is="objectCombine" data="{{...obj1,...obj2,e:5}}"></template>
//page.js
Page({
    data:{
        obj1:{
            a:1,
            b:2
        },
       obj2:{
            c:3,
            d:4
        }
    }
})
最終組合成的對象是{a: 1, b: 2, c: 3, d: 4, e: 5}。

4).如果對象的key和value相同,也可以間接地表達(dá):
<!--wxml-->
<template is="objectCombine" data="{{foo,bar}}"></template>
//page.js
Page({
    data:{
      foo:'my-foo',
      bar:'my-bar'
    }
})
最終組合成的對象是{foo: 'my-foo', bar:'my-bar'}。

5).注意:
上述方式可以隨意組合,但是如果變量名相同,后邊的對象會覆蓋前面的對象。
<!--wxml-->
<template is="objectCombine" data="{{...obj1,...obj2,a,c:6}}"></template>
//page.js
Page({
    data:{
      obj1:{
        a:1,
        b:2
      },
      obj2:{
        b:3,
        c:4
      },
      a:5
    }
})
最終組合成的對象是{a: 5, b: 3, c: 6}。

2.條件語句

條件語句可用于.wxml中進(jìn)行條件渲染,不同的條件進(jìn)行不同的渲染。

(1)wx:if
我們用wx:if="{{condition}}"來判斷是否需要渲染該代碼塊。比如:
<view wx:if="{{condition}}">True</view>

也可以用wx:elif和wx:else來添加一個else塊:
<view wx:if="{{length>5}}">1</view>
<view wx:elif="{{length>2}}">2</view>
<view wx:else>3</view>
(2)block wx:if

因?yàn)閣x:if是一個控制屬性,需要將它添加到一個組件標(biāo)簽上。如果想一次性判斷多個組件標(biāo)簽,其實(shí)可以使用一個標(biāo)簽將多個組件包裝起來,并在其上使用wx:if控制屬性:

<block wx:if="{{true}}">
    <view>view1<view>
    <view>view2</view>
<block>

注意
并不是一個組件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。

(3)wx:if vs hidden

因?yàn)閣x:if之中的模板也可能包含數(shù)據(jù)綁定,所以當(dāng)wx:if的條件值切換時,框架有一個局部渲染的過程,從而確保條件塊在切換時銷毀或重新渲染。
同時wx:if也是惰性的,如果在初始渲染條件為false,框架什么也不做,在條件第一次變成真的時候才開始局部渲染。
相比之下,hidden就簡單得多,組件始終會被渲染,只需簡單地控制顯示與隱藏。
一般來說,wx:if有更高的切換消耗,而hidden有更高的初始渲染消耗。因此,如果需要頻繁切換的情景下,用hidden更好;如果運(yùn)行時條件不大可能改變,則wx:if較好。

3.列表語句

列表語句可用于.wxml中進(jìn)行列表渲染,將列表中的各項(xiàng)數(shù)據(jù)進(jìn)行重復(fù)渲染。

(1)wx:for

在組件上使用wx:for控制屬性綁定一個數(shù)組,即可使用數(shù)組中各項(xiàng)的數(shù)據(jù)重復(fù)渲染該組件。
默認(rèn)數(shù)組當(dāng)前項(xiàng)的下標(biāo)變量名默認(rèn)為index,數(shù)組當(dāng)前項(xiàng)的變量名默認(rèn)為item。
示例如下:

<view wx:for="{{items}}">{{index}}:{{item.message}}</view>
//page.js
Page({
    data:{
      items:[{message:'foo'},{message:'go'}]
    }
})

使用wx:for-item可以指定數(shù)組當(dāng)前元素的變量名。
而使用wx:for-index則可以指定數(shù)組當(dāng)前下標(biāo)的變量名:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">{{idx}}:{{itemName.message}}</view>

wx:for也可以嵌套,例如下邊是一個九九乘法表:
<view wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="I">
<view wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="j">
<view wx:if="{{i<j}}">{{I}}*{{j}}={{i*j}}</view>
</view>
</view>
(2)block wx:for

類似于block wx:if,也可以將wx:for用在標(biāo)簽上,渲染一個包含多節(jié)點(diǎn)的結(jié)構(gòu)塊。
例如:

<block wx:for="{{[1,2,3]}}">
    <view>{{index}}:</view>
    <view>{{item}}</view>
</block>
(3)wx:key

如果列表中項(xiàng)目的位置會動態(tài)改變,或者有新的項(xiàng)目添加到列表中,并且希望列表中的項(xiàng)目保持自己的特征和狀態(tài)(如input標(biāo)簽中的輸入內(nèi)容,switch中的選中狀態(tài)),需要使用wx:key來指定列表中項(xiàng)目的唯一標(biāo)識符。
wx:key的值以兩種形式提供:
■字符串,代表在for循環(huán)的array中item的某個property,該property的值需要是列表中唯一的字符串或數(shù)字,且不能動態(tài)改變。
■保留關(guān)鍵字*this代表在for循環(huán)中的item本身,這種表示需要item本身是一個唯一的字符串或者數(shù)字,例如:當(dāng)數(shù)據(jù)改變觸發(fā)渲染層重新渲染的時候,會校正帶有key的組件,框架會確保它們被重新排序,而不是重新創(chuàng)建,以確保使組件保持自身的狀態(tài),并且提高列表渲染時的效率。
注意:
如不提供wx:key,會報錯,如果明確知道該列表是靜態(tài),或者不必關(guān)注其順序,可以選擇忽略。
示例代碼如下:

//wx-key-demo.wxml
<switch wx:for ="{{objectArray}}" wx:key="unique" style="display:block;">{{item:id}}</switch>
<button bindtap="switch">Switch</button>
<button bindtap="addToFront">Add to the front</button>
<switch wx:for="{{numberArray}}" wx:key="*this" style="display:block;">{{item}}</switch>
<button bindtap="addNumberToFront">Add to the front</button>

//wx-key-demo.js
Page({
    data:{
      objectArray:[{id:5,unique:'unique_5'},{id:4,unique:'unique_4'},
      {id:3,unique:'unique_3'},{id:2,unique:'unique_2'},],
      numberArray:[1,2,3,4]
  },
  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 
        })
   },
  addNumberToFront: function(e){ 
        this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this. data.numberArray)
        this.setData({
           numberArray: this.data.numberArray 
        }) 
    }
})

4.模板

WXML支持模板(template),可以在模板中定義代碼片段,然后在不同的地方調(diào)用。

(1)定義模板

使用name屬性,作為模板的名字。然后在<template/>內(nèi)定義代碼片段:

<template name="msgItem">
  <view>
    <text>{{index}}:{{msg}}</text>
    <text>time:{{time}}</text>
  </view>
</template>
(2)使用模板

使用is屬性,聲明需要使用的模板,然后將模板所需要的data傳入,例如:

<!--wxml-->
<template is="msgItem" data="{{...item}}"/>
//page.js
Page({
    data:{
    item:{
      index:0,
      msg:'this is a template',
      time:'2018-12-12'
    }
  }
})

is屬性可以使用Mustache語法,來動態(tài)決定具體需要渲染哪個模板:
<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>
(3)模板的作用域

模板擁有自己的作用域,只能使用data傳入的數(shù)據(jù)。

5.引用

WXML提供兩種文件引用方式:import和include。

(1)import

import可以在該文件中使用目標(biāo)文件定義的template,例如:在item.wxml中定義了一個叫item的template:

 <! -- item.wxml -->   
 <template name="item">      
    <text>{{text}}</text>   
 </template>

在index.wxml中引用了item.wxml,就可以使用item模板:

<import src="item.wxml"/>    
<template is="item" data="{{text: 'forbar'}}"/>
(2)import的作用域

import有作用域的概念,即只會引用目標(biāo)文件中定義的template,而不會引用目標(biāo)文件嵌套import的template。
例如:C import B, B import A,在C中可以使用B定義的template,在B中可以使用A定義的template,但是C不能使用A定義的template。如下所示:

 <! -- A.wxml -->    
<template name="A">      
<text> A template </text>    
</template>    
<! -- B.wxml -->    
<import src="a.wxml"/>    
<template name="B">      
<text> B template </text>   
</template>    
<! -- C.wxml -->    
<import src="b.wxml"/>    
<template is="A"/>   
<! -- Error! Can not use tempalte when not import A. -->    <template is="B"/>
(3)include

include可將目標(biāo)文件除模板代碼(<template/>)塊的所有代碼引入,相當(dāng)于拷貝到include位置,例如:

 <! -- index.wxml -->    
<include src="header.wxml"/>    
<view> body </view>    
<include src="footer.wxml"/>    
<! -- header.wxml -->    
<view> header </view>    
<! -- footer.wxml -->    
<view> footer </view>

6.事件綁定

事件的定義如下:
■事件是視圖層到邏輯層的通信方式。
■事件可以將用戶的行為反饋到邏輯層進(jìn)行處理。
■事件可以綁定在組件上,當(dāng)達(dá)到觸發(fā)事件,就會執(zhí)行邏輯層中對應(yīng)的事件處理函數(shù)。
■事件對象可以攜帶額外信息,如id、dataset、touches。

(1)事件的使用

小程序與用戶的交互多數(shù)情況下是通過事件來進(jìn)行的。
首先,在組件中綁定一個事件處理函數(shù)。如下面代碼中,我們使用bindtap,當(dāng)用戶點(diǎn)擊該組件view的時候會在該頁面對應(yīng)的Page中找到相應(yīng)的事件處理函數(shù)tapName:

// 指定view組件的唯一標(biāo)識tapTest;自定義屬性hi,其值為MINA;綁定事件tapName    
<view id="tapTest" data-hi="MINA" bindtap="tapName"> Click me! </view>

注意
應(yīng)將bindtap理解為:bind+tap,即綁定冒泡事件tap(手指觸摸后離開)。
其次,要在相應(yīng)的Page定義中寫上相應(yīng)的事件處理函數(shù),參數(shù)是event。如下列示例代碼中,定義了tapName函數(shù),將事件信息輸出到控制臺上:

Page({      
  tapName: function(event) {      
      console.log(event)     
   }   
 })
(2)事件詳解

微信小程序里的事件分為冒泡事件和非冒泡事件:
■冒泡事件:當(dāng)一個組件上的事件被觸發(fā)后,該事件會向父節(jié)點(diǎn)傳遞。
■非冒泡事件:當(dāng)一個組件上的事件被觸發(fā)后,該事件不會向父節(jié)點(diǎn)傳遞。WXML中的冒泡事件僅有6個,列表如下:

冒泡事件 含義或觸發(fā)條件
touchstart 手指觸摸
touchmove 手指觸摸后移動
touchcancel 手指觸摸動作被打斷,如來電提醒、彈窗
touchend 手指觸摸動作結(jié)束
tap 手指觸摸后離開
longtap 手指觸摸后超過350ms再離開

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

事件綁定的寫法同組件的屬性,以key、value的形式,如下所示:
■key以bind或catch開頭,然后跟上事件的類型,如bindtap、catchtouchstart。
■value是一個字符串,需要在對應(yīng)的Page中定義同名的函數(shù)。不然當(dāng)觸發(fā)事件的時候會報錯。
注意
bind事件綁定不會阻止冒泡事件向上冒泡,catch事件綁定可以阻止冒泡事件向上冒泡。

例子,點(diǎn)擊id為inner的組件view會先后觸發(fā)handleTap3和handle-Tap2(因?yàn)閠ap事件會冒泡到id為middle的組件view,而middle view阻止了tap事件冒泡,不再向父節(jié)點(diǎn)傳遞),點(diǎn)擊middle view會觸發(fā)handleTap2,點(diǎn)擊id為outter的組件view會觸發(fā)handleTap1:

<view id="outter" bindtap="handleTap1"> outer view      
  <view id="middle" catchtap="handleTap2"> middle view  
          <view id="inner" bindtap="handleTap3"> inner view        </view>      </view>    </view>

如無特殊說明,當(dāng)組件觸發(fā)事件時,邏輯層綁定該事件的處理函數(shù)會收到一個事件對象。事件對象具有的屬性參見表

事件對象的屬性 類型 說明
type String 事件類型
timeStamp Integer 事件生成的時間戳
target Object 觸發(fā)事件組件的一些屬性值集合
currentTarget Object 當(dāng)前組件的一些屬性值集合
touches Array 觸摸事件,當(dāng)前停留在屏幕中觸摸點(diǎn)信息的數(shù)組
changedTouches Array 觸摸事件,當(dāng)前變化的觸摸點(diǎn)信息的數(shù)組
detail Object 額外的信息

其中:
■type指通用事件類型。
■timeStamp是該頁面打開到觸發(fā)事件所經(jīng)過的毫秒數(shù)。
■target觸發(fā)事件的源組件,是一個對象,具有以下3個屬性

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

■currentTarget事件綁定的當(dāng)前組件。與target類似,是一個對象,同樣具有上表三個屬性。(組件<canvas />中的觸摸事件為特殊事件,不可冒泡,所以無currentTarget。)
說明:
1)target和currentTarget可以參考上例中,點(diǎn)擊inner view時,handleTap3收到的事件對象target和currentTarget都是inner,而handleTap2收到的事件對象target就是inner, currentTarget就是middle。
2)dataset在組件中可以定義數(shù)據(jù),這些數(shù)據(jù)將會通過事件傳遞給App Service。dataset書寫方式以data-開頭,多個單詞由連字符“-”連接,不能有大寫(大寫會自動轉(zhuǎn)成小寫),如data-element-type,最終在event.target.dataset中會將連字符轉(zhuǎn)成駝峰形式:elementType。
示例代碼如下:

// bindviewtap.wxml    
<view  data-alpha-beta="1"  data-alphaBeta="2"  bindtap="bindViewTap">    DataSet Test </view>    
// bindviewtap.js    
Page({      
    bindViewTap:function(event){   
       event.target.dataset.alphaBeta == 1      //- 會轉(zhuǎn)為駝峰寫法 
         event.target.dataset.alphabeta == 2      //大寫會轉(zhuǎn)為小寫 
   }    
})

■touches是一個觸摸點(diǎn)的數(shù)組。每個元素為一個Touch(觸摸點(diǎn))對象,具有以下屬性:
■changedTouches數(shù)據(jù)格式同touches。表示有變化的觸摸點(diǎn),如從無變有(touch-start)、位置變化(touchmove)、從有變無(touchend、touchcancel)。

WXSS

WXSS是一套樣式語言,用于描述WXML的組件樣式。它將決定WXML的組件應(yīng)該怎么顯示。
官方文檔表明,WXSS的選擇器目前支持(“.class”、“#id”、“element”、“element, element”、“::after”、“::before”),而且本地資源無法通過WXSS獲取,所以WXSS中的樣式都是用的網(wǎng)絡(luò)圖片,或者base64。這樣,對于某些前端開發(fā)者而言,會有所局限。

與CSS相比,WXSS擴(kuò)展的特性有:
■尺寸單位。
■樣式導(dǎo)入。

1.尺寸單位

WXSS新增了針對移動端屏幕的兩種尺寸單位:rpx與rem。
rpx(responsive pixel):可以根據(jù)屏幕寬度進(jìn)行自適應(yīng)。規(guī)定屏幕寬為750rpx。如在iPhone6上,屏幕寬度為375px,共有750個物理像素,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

設(shè)備 rpx換算px(屏幕寬度/750) px換算rpx(750/屏幕寬度)
iPhone5 1rpx=0.42px 1px=2.34rpx
iPhone6s 1rpx=0.5px 1px=2rpx
iPhone6sPlus 1rpx=0.552px 1px=1.81rpx

rem(root em):規(guī)定屏幕寬度為20rem;1rem =(750/20)rpx。
因此建議,開發(fā)微信小程序時設(shè)計(jì)師可以用iPhone6作為視覺稿的標(biāo)準(zhǔn)。

2.導(dǎo)入樣式

可以使用@import語句來導(dǎo)入外聯(lián)樣式表。@import后跟需要導(dǎo)入的外聯(lián)樣式表的相對路徑,并用;表示語句結(jié)束。
示例代碼如下:

/** common.wxss **/   
 .small-p {      padding:5px;    }   
 /** app.wxss **/   
@import "common.wxss";   
 .middle-p {      padding:15px;    }

3.內(nèi)聯(lián)樣式

內(nèi)聯(lián)樣式指的是框架組件上支持使用style、class屬性來控制組件的樣式:
■style:靜態(tài)的樣式統(tǒng)一寫到class中。style接收動態(tài)的樣式,在運(yùn)行時會進(jìn)行解析,請盡量避免將靜態(tài)的樣式寫進(jìn)style中,以免影響渲染速度:
<view style="color:{{color}}; " />
■class:用于指定樣式規(guī)則,其屬性值是樣式規(guī)則中類選擇器名(樣式類名)的集合,樣式類名不需要帶上“. ”,比如,“.normal-view”樣式類的使用:
<view class="normal_view" />

4.選擇器

WXSS目前支持的選擇器有:

選擇器 樣例 樣例描述
.class .intro 選擇所有擁有class="intro"組件
#id #firstname 選擇所有擁有id="firstname"組件
element view 選擇所有view組件
element,element view,checkbox 選擇所有文檔的view組件和所有的checkbox組件
::after view::after 在view組件后面插入內(nèi)容
::before view::before 在view組件前邊插入內(nèi)容

5.全局樣式和局部樣式

定義在app.wxss中的樣式為全局樣式,作用于每一個頁面。在page的.wxss文件中定義的樣式為局部樣式,只作用在對應(yīng)的頁面,并會覆蓋app.wxss中相同的選擇器。

6.WXSS與CSS開發(fā)的差異

(1)選擇器的差異

WXSS提供的選擇器目前官網(wǎng)提供得很少,下面也是通過圖表來對比下WXSS與CSS選擇器的差異


wxss.png
(2)適配

WXSS剛開始時并不能適配各種設(shè)備,雖然支持rem,但是并不能改變HTML的屬性,這使得HTML 5中的rem適配方案失效。最終微信團(tuán)隊(duì)推出了rpx(responsive pixel)這個新的計(jì)量單位,它規(guī)定屏幕寬度為750rpx,從而可以依據(jù)屏幕寬度進(jìn)行自適應(yīng)。rpx的實(shí)現(xiàn)原理跟rem很相似,而且最終也是換算成rem。
rpx計(jì)量最大的優(yōu)勢在于750設(shè)計(jì)稿不需要進(jìn)行任何轉(zhuǎn)換即可適配。750設(shè)計(jì)稿量是多少就是多少,如在iPhone6上,屏幕寬度為375px,共有750個物理像素,則750rpx =375px = 750物理像素,1rpx = 0.5px = 1物理像素。但是目前的方案還存在一定的問題,那就是非750的設(shè)計(jì)稿則需要進(jìn)行一次換算,如640的設(shè)計(jì)稿就需要進(jìn)行一次換算在640設(shè)計(jì)稿中的1rpx = 640/750rpx,而在WXSS中并不支持算術(shù)運(yùn)算符,所以小程序的視覺設(shè)計(jì)稿盡量使用750來給出。

(3)樣式級聯(lián)

如"element element",微信團(tuán)隊(duì)回復(fù)說“級聯(lián)會破壞掉組件的結(jié)構(gòu),級聯(lián)最終會取消”,因此推薦使用BEM,即Block(塊)、Element(元素)、Modifier(修飾符),是由Yandex團(tuán)隊(duì)提出的一種CSSClass命名方法。后續(xù)會提供另外的一種層級關(guān)系來解決依賴層級的情況。雖然現(xiàn)在還能使用級聯(lián)的寫法,但是最終可能會廢棄,所以建議大家盡量不要使用級聯(lián)。

框架組件

組件是視圖層的基本組成單元,除自帶某些功能外,也具有微信風(fēng)格的樣式。一個組件通常包括“開始標(biāo)簽”和“結(jié)束標(biāo)簽”,組件由屬性來定義與修飾,放在“開始標(biāo)簽”中。組件的內(nèi)容則包含在兩個標(biāo)簽之內(nèi);

注意:
所有的組件與屬性都需使用小寫字符。
所有組件都有的共同屬性:

屬性名 類型 描述 注解
id String 組件的唯一標(biāo)示 保持整個頁面唯一
class String 組件的樣式類 在對應(yīng)的wxss中定義的樣式類
style String 組件的內(nèi)聯(lián)樣式 可以動態(tài)設(shè)置的內(nèi)聯(lián)樣式
hidden Boolean 組件是否顯示 所有組件默認(rèn)顯示
data-* Any 自定義屬性 組件上觸發(fā)事件時,會發(fā)送給事件處理函數(shù)
bind/catch EventHandler 組件的事件 事件綁定

同時每一個組件也可以有自定義的屬性(稱為“特殊獨(dú)有屬性”),用于對該組件的功能或樣式進(jìn)行修飾。但屬性只支持下面這七種數(shù)據(jù)類型:

類型 描述 注解
Boolean 布爾值 組件寫上該屬性,不管該屬性等于什么,其值為true,該組件上沒寫該屬性,屬性值才為false
Number 數(shù)字 1,2,5
String 字符串 "string"
Array 數(shù)組 [1,"string"]
Object 對象 [key:value]
EventHandler 事件處理函數(shù)名 "handlerName"是page中定義的事件處理函數(shù)
Any 任意屬性 ...

微信小程序?yàn)殚_發(fā)者提供了九大類組件:

組件類型 組件用途 包含組件
視圖容器組件 控制視圖樣式 view\scroll-view\swiper
基礎(chǔ)內(nèi)容組件 圖標(biāo),文本與進(jìn)度條 icon\text\progress
表單組件 構(gòu)建表單 button\form\input\checkbox\radio\picker\picker-view\slider\switch\label\textarea
互動操作組件 操作反饋 action-sheet\modal\toast\loading
頁面導(dǎo)航組件 頁面鏈接 navigator
媒體組件 多媒體控制 audio\image\video
地圖組件 地圖 map
畫布組件 畫圖 canvas
客服會話組件 客服會話服務(wù) contact-button
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內(nèi)容