初識(shí)小程序-視圖層

視圖層

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

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

WXML

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

.wxml文件第一行建議寫歹垫。比如logs頁(yè)面的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>

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

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

1)數(shù)據(jù)綁定:
//wxml
<view>{{message}}</view>
//page.js
Page({
    data:{
        message:'hello MINA'
  }
})
上例中暮芭,在.wxml文件中綁定message變量鹿驼,在.js文件的data對(duì)象中給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)算符辕宏,用它來展開一個(gè)對(duì)象畜晰,如staffA對(duì)象。

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文件中的動(dòng)態(tài)數(shù)據(jù)均來自對(duì)應(yīng)頁(yè)面的.js文件中Page的data對(duì)象瑞筐。

(1)簡(jiǎn)單綁定

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

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

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

3).控制屬性(需要在雙引號(hào)之內(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)行簡(jiǎ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)成新的對(duì)象或者數(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).對(duì)象
<!--wxml-->
<template is="objectCombine" data="{{for:a, bar:b}}"></template>
//page.js
Page({
    data:{
        a:1,
        b:2
    }
})
最終組合成的對(duì)象是{for: 1, bar: 2}

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

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

5).注意:
上述方式可以隨意組合,但是如果變量名相同纱控,后邊的對(duì)象會(huì)覆蓋前面的對(duì)象游岳。
<!--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
    }
})
最終組合成的對(duì)象是{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來添加一個(gè)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是一個(gè)控制屬性唾那,需要將它添加到一個(gè)組件標(biāo)簽上。如果想一次性判斷多個(gè)組件標(biāo)簽褪尝,其實(shí)可以使用一個(gè)標(biāo)簽將多個(gè)組件包裝起來闹获,并在其上使用wx:if控制屬性:

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

注意
并不是一個(gè)組件,它僅僅是一個(gè)包裝元素河哑,不會(huì)在頁(yè)面中做任何渲染避诽,只接受控制屬性。

(3)wx:if vs hidden

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

3.列表語句

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

(1)wx:for

在組件上使用wx:for控制屬性綁定一個(gè)數(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也可以嵌套,例如下邊是一個(gè)九九乘法表:
<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)簽上逸吵,渲染一個(gè)包含多節(jié)點(diǎn)的結(jié)構(gòu)塊。
例如:

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

如果列表中項(xiàng)目的位置會(huì)動(dòng)態(tài)改變缝裁,或者有新的項(xiàng)目添加到列表中扫皱,并且希望列表中的項(xiàng)目保持自己的特征和狀態(tài)(如input標(biāo)簽中的輸入內(nèi)容,switch中的選中狀態(tài))捷绑,需要使用wx:key來指定列表中項(xiàng)目的唯一標(biāo)識(shí)符韩脑。
wx:key的值以兩種形式提供:
■字符串,代表在for循環(huán)的array中item的某個(gè)property粹污,該property的值需要是列表中唯一的字符串或數(shù)字段多,且不能動(dòng)態(tài)改變。
■保留關(guān)鍵字*this代表在for循環(huán)中的item本身壮吩,這種表示需要item本身是一個(gè)唯一的字符串或者數(shù)字进苍,例如:當(dāng)數(shù)據(jù)改變觸發(fā)渲染層重新渲染的時(shí)候,會(huì)校正帶有key的組件鸭叙,框架會(huì)確保它們被重新排序琅捏,而不是重新創(chuàng)建,以確保使組件保持自身的狀態(tài)递雀,并且提高列表渲染時(shí)的效率柄延。
注意:
如不提供wx:key,會(huì)報(bào)錯(cuò)缀程,如果明確知道該列表是靜態(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語法,來動(dòng)態(tài)決定具體需要渲染哪個(gè)模板:
<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中定義了一個(gè)叫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有作用域的概念,即只會(huì)引用目標(biāo)文件中定義的template葱峡,而不會(huì)引用目標(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ā)事件铣缠,就會(huì)執(zhí)行邏輯層中對(duì)應(yīng)的事件處理函數(shù)烘嘱。
■事件對(duì)象可以攜帶額外信息,如id蝗蛙、dataset蝇庭、touches。

(1)事件的使用

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

// 指定view組件的唯一標(biāo)識(shí)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ù)颜启,將事件信息輸出到控制臺(tái)上:

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

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

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

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

事件綁定的寫法同組件的屬性冻辩,以key、value的形式拆祈,如下所示:
■key以bind或catch開頭恨闪,然后跟上事件的類型,如bindtap放坏、catchtouchstart咙咽。
■value是一個(gè)字符串,需要在對(duì)應(yīng)的Page中定義同名的函數(shù)淤年。不然當(dāng)觸發(fā)事件的時(shí)候會(huì)報(bào)錯(cuò)钧敞。
注意
bind事件綁定不會(huì)阻止冒泡事件向上冒泡,catch事件綁定可以阻止冒泡事件向上冒泡麸粮。

例子溉苛,點(diǎn)擊id為inner的組件view會(huì)先后觸發(fā)handleTap3和handle-Tap2(因?yàn)閠ap事件會(huì)冒泡到id為middle的組件view,而middle view阻止了tap事件冒泡弄诲,不再向父節(jié)點(diǎn)傳遞)愚战,點(diǎn)擊middle view會(huì)觸發(fā)handleTap2,點(diǎn)擊id為outter的組件view會(huì)觸發(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í)凤巨,邏輯層綁定該事件的處理函數(shù)會(huì)收到一個(gè)事件對(duì)象。事件對(duì)象具有的屬性參見表

事件對(duì)象的屬性 類型 說明
type String 事件類型
timeStamp Integer 事件生成的時(shí)間戳
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是該頁(yè)面打開到觸發(fā)事件所經(jīng)過的毫秒數(shù)留美。
■target觸發(fā)事件的源組件彰檬,是一個(gè)對(duì)象伸刃,具有以下3個(gè)屬性

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

■currentTarget事件綁定的當(dāng)前組件。與target類似逢倍,是一個(gè)對(duì)象捧颅,同樣具有上表三個(gè)屬性。(組件<canvas />中的觸摸事件為特殊事件较雕,不可冒泡碉哑,所以無currentTarget。)
說明:
1)target和currentTarget可以參考上例中亮蒋,點(diǎn)擊inner view時(shí)扣典,handleTap3收到的事件對(duì)象target和currentTarget都是inner,而handleTap2收到的事件對(duì)象target就是inner, currentTarget就是middle慎玖。
2)dataset在組件中可以定義數(shù)據(jù)贮尖,這些數(shù)據(jù)將會(huì)通過事件傳遞給App Service。dataset書寫方式以data-開頭趁怔,多個(gè)單詞由連字符“-”連接湿硝,不能有大寫(大寫會(huì)自動(dòng)轉(zhuǎn)成小寫),如data-element-type润努,最終在event.target.dataset中會(huì)將連字符轉(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      //- 會(huì)轉(zhuǎn)為駝峰寫法 
         event.target.dataset.alphabeta == 2      //大寫會(huì)轉(zhuǎn)為小寫 
   }    
})

■touches是一個(gè)觸摸點(diǎn)的數(shù)組。每個(gè)元素為一個(gè)Touch(觸摸點(diǎn))對(duì)象铺浇,具有以下屬性:
■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。這樣测砂,對(duì)于某些前端開發(fā)者而言茵烈,會(huì)有所局限。

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

1.尺寸單位

WXSS新增了針對(duì)移動(dòng)端屏幕的兩種尺寸單位:rpx與rem存璃。
rpx(responsive pixel):可以根據(jù)屏幕寬度進(jìn)行自適應(yīng)仑荐。規(guī)定屏幕寬為750rpx。如在iPhone6上有巧,屏幕寬度為375px释漆,共有750個(gè)物理像素,則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í)設(shè)計(jì)師可以用iPhone6作為視覺稿的標(biāo)準(zhǔn)逊笆。

2.導(dǎo)入樣式

可以使用@import語句來導(dǎo)入外聯(lián)樣式表。@import后跟需要導(dǎo)入的外聯(lián)樣式表的相對(duì)路徑岂傲,并用难裆;表示語句結(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接收動(dòng)態(tài)的樣式,在運(yùn)行時(shí)會(huì)進(jìn)行解析亩进,請(qǐng)盡量避免將靜態(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中的樣式為全局樣式习贫,作用于每一個(gè)頁(yè)面。在page的.wxss文件中定義的樣式為局部樣式千元,只作用在對(duì)應(yīng)的頁(yè)面苫昌,并會(huì)覆蓋app.wxss中相同的選擇器。

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

(1)選擇器的差異

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


wxss.png
(2)適配

WXSS剛開始時(shí)并不能適配各種設(shè)備祟身,雖然支持rem屋厘,但是并不能改變HTML的屬性,這使得HTML 5中的rem適配方案失效月而。最終微信團(tuán)隊(duì)推出了rpx(responsive pixel)這個(gè)新的計(jì)量單位汗洒,它規(guī)定屏幕寬度為750rpx,從而可以依據(jù)屏幕寬度進(jìn)行自適應(yīng)父款。rpx的實(shí)現(xiàn)原理跟rem很相似溢谤,而且最終也是換算成rem。
rpx計(jì)量最大的優(yōu)勢(shì)在于750設(shè)計(jì)稿不需要進(jìn)行任何轉(zhuǎn)換即可適配憨攒。750設(shè)計(jì)稿量是多少就是多少世杀,如在iPhone6上,屏幕寬度為375px肝集,共有750個(gè)物理像素瞻坝,則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)樣式級(jí)聯(lián)

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

框架組件

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

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

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

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

類型 描述 注解
Boolean 布爾值 組件寫上該屬性,不管該屬性等于什么临燃,其值為true睛驳,該組件上沒寫該屬性,屬性值才為false
Number 數(shù)字 1,2,5
String 字符串 "string"
Array 數(shù)組 [1,"string"]
Object 對(duì)象 [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
互動(dòng)操作組件 操作反饋 action-sheet\modal\toast\loading
頁(yè)面導(dǎo)航組件 頁(yè)面鏈接 navigator
媒體組件 多媒體控制 audio\image\video
地圖組件 地圖 map
畫布組件 畫圖 canvas
客服會(huì)話組件 客服會(huì)話服務(wù) contact-button
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膜廊,一起剝皮案震驚了整個(gè)濱河市乏沸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌爪瓜,老刑警劉巖蹬跃,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異铆铆,居然都是意外死亡蝶缀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門薄货,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扼劈,“玉大人,你說我怎么就攤上這事菲驴〖龀常” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵赊瞬,是天一觀的道長(zhǎng)先煎。 經(jīng)常有香客問我,道長(zhǎng)巧涧,這世上最難降的妖魔是什么薯蝎? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮谤绳,結(jié)果婚禮上占锯,老公的妹妹穿的比我還像新娘。我一直安慰自己缩筛,他們只是感情好消略,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞎抛,像睡著了一般艺演。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天胎撤,我揣著相機(jī)與錄音晓殊,去河邊找鬼。 笑死伤提,一個(gè)胖子當(dāng)著我的面吹牛巫俺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肿男,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼识藤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了次伶?” 一聲冷哼從身側(cè)響起痴昧,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冠王,沒想到半個(gè)月后赶撰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柱彻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年豪娜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哟楷。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘤载,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卖擅,到底是詐尸還是另有隱情鸣奔,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布惩阶,位于F島的核電站挎狸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏断楷。R本人自食惡果不足惜锨匆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冬筒。 院中可真熱鬧恐锣,春花似錦、人聲如沸舞痰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匀奏。三九已至鞭衩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娃善,已是汗流浹背论衍。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聚磺,地道東北人坯台。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瘫寝,于是被迫代替她去往敵國(guó)和親蜒蕾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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