小程序 wxs

標(biāo)簽(空格分隔): 小程序


小程序的一套腳本語言雹熬,結(jié)合 WXML宁赤,可以構(gòu)建出頁面的結(jié)構(gòu)

WXS 的運(yùn)行環(huán)境和其他 JavaScript 代碼是隔離的,WXS 中不能調(diào)用其他 JavaScript 文件中定義的函數(shù),也不能調(diào)用小程序提供的API

頁面渲染

<!--wxml-->
<wxs module="m1">
var msg = "hello world";

module.exports.message = msg;
</wxs>

<view> {{m1.message}} </view>

數(shù)據(jù)處理

// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
  }
})
<!--wxml-->
<!-- 下面的 getMax 函數(shù)萎羔,接受一個數(shù)組,且返回數(shù)組中最大的元素的值 -->
<wxs module="m1">
var getMax = function(array) {
  var max = undefined;
  for (var i = 0; i < array.length; ++i) {
    max = max === undefined ?
      array[i] :
      (max >= array[i] ? max : array[i]);
  }
  return max;
}

module.exports.getMax = getMax;
</wxs>

<!-- 調(diào)用 wxs 里面的 getMax 函數(shù)寺董,參數(shù)為 page.js 里面的 array -->
<view> {{m1.getMax(array)}} </view>

WXS響應(yīng)事件

背景:一次 touchmove 的響應(yīng)需要經(jīng)過 2 次的邏輯層和渲染層的通信以及一次渲染覆糟,通信的耗時比較大。為了減少通信的次數(shù)遮咖,讓事件在視圖層(Webview)響應(yīng)滩字。

使用 WXS 函數(shù)用來響應(yīng)小程序事件,目前只能響應(yīng)內(nèi)置組件的事件御吞,不支持自定義組件事件

WXS 函數(shù)的除了純邏輯的運(yùn)算麦箍,還可以通過封裝好的ComponentDescriptor 實(shí)例來訪問以及設(shè)置組件的 class 和樣式,對于交互動畫陶珠,設(shè)置 style 和 class 足夠了

var wxsFunction = function(event, ownerInstance) {
    var instance = ownerInstance.selectComponent('.classSelector') // 返回組件的實(shí)例
    instance.setStyle({
        "font-size": "14px" // 支持rpx
    })
    instance.getDataset()
    instance.setClass(className)
    // ...
    return false // 不往上冒泡挟裂,相當(dāng)于調(diào)用了同時調(diào)用了stopPropagation和preventDefault
}

其中入?yún)?event 是小程序事件對象基礎(chǔ)上多了 event.instance 來表示觸發(fā)事件的組件的 ComponentDescriptor 實(shí)例。ownerInstance 表示的是觸發(fā)事件的組件所在的組件的 ComponentDescriptor 實(shí)例揍诽,如果觸發(fā)事件的組件是在頁面內(nèi)的诀蓉,ownerInstance 表示的是頁面實(shí)例。

方法 參數(shù) 描述
selectComponent selector對象 返回組件的 ComponentDescriptor 實(shí)例暑脆。
selectAllComponents selector對象數(shù)組 返回組件的 ComponentDescriptor 實(shí)例數(shù)組渠啤。
setStyle Object/string 設(shè)置組件樣式,支持rpx添吗。設(shè)置的樣式優(yōu)先級比組件 wxml 里面定義的樣式高沥曹。不能設(shè)置最頂層頁面的樣式。
addClass/removeClass/ hasClass string 設(shè)置組件的 class碟联。設(shè)置的 class 優(yōu)先級比組件 wxml 里面定義的 class 高妓美。不能設(shè)置最頂層頁面的 class。
getDataset 返回當(dāng)前組件/頁面的 dataset 對象
callMethod (funcName:string, args:object) 調(diào)用當(dāng)前組件/頁面在邏輯層(App Service)定義的函數(shù)鲤孵。funcName表示函數(shù)名稱壶栋,args表示函數(shù)的參數(shù)。
requestAnimationFrame Function 和原生 requestAnimationFrame 一樣普监。用于設(shè)置動畫委刘。
getState 返回一個object對象,當(dāng)有局部變量需要存儲起來后續(xù)使用的時候用這個方法鹰椒。
triggerEvent (eventName, detail) 和組件的triggerEvent一致锡移。

WXS 運(yùn)行在視圖層(Webview),里面的邏輯畢竟能做的事件比較少漆际,需要有一個機(jī)制和邏輯層(App Service)開發(fā)者的代碼通信淆珊,上面的 callMethod 是 WXS 里面調(diào)用邏輯層(App Service)開發(fā)者的代碼的方法

使用方法
WXML定義事件:

<wxs module="test" src="./test.wxs"></wxs>
<view change:prop="{{test.propObserver}}" prop="{{propValue}}" bindtouchmove="{{test.touchmove}}" class="movable"></view>

上面的change:prop(屬性前面帶change:前綴)是在 prop 屬性被設(shè)置的時候觸發(fā) WXS 函數(shù),值必須用{{}}括起來奸汇。類似 Component 定義的 properties 里面的 observer 屬性施符,在setData({propValue: newValue})調(diào)用之后會觸發(fā)往声。

注意:WXS函數(shù)必須用{{}}括起來。當(dāng) prop 的值被設(shè)置 WXS 函數(shù)就會觸發(fā)戳吝,而不只是值發(fā)生改變浩销,所以在頁面初始化的時候會調(diào)用一次WxsPropObserver的函數(shù)。

WXS文件test.wxs里面定義并導(dǎo)出事件處理函數(shù)和屬性改變觸發(fā)的函數(shù):

module.exports = {
    touchmove: function(event, instance) {
        console.log('log event', JSON.stringify(event))
    },
    propObserver: function(newValue, oldValue, ownerInstance, instance) {
        console.log('prop observer', newValue, oldValue)
    }
}

示例:

/* wxs文件 */
swipeDirection = 0; //是否觸發(fā)水平滑動 0:未觸發(fā) 1:觸發(fā)水平滑動 2:觸發(fā)垂直滑動
var touchstart = function(event, ownerInstance) {

  var ins = event.instance
  var st = ins.getState()
  st.isMoving = true

  st.startX = event.touches[0].clientX;
  st.startY = event.touches[0].clientY;

  var _data = event.currentTarget.dataset,
    _loc = _data.loc,
    _twoIndex = _data.index;

  st.index = _loc;
  st.twoIndex = _twoIndex;
}


var touchmove = function(event, ownerInstance) {
  var ins = event.instance
  var st = ins.getState()
  if (!st.isMoving) return

  if (event.touches.length == 1) {


    if (swipeDirection === 2) {
      return;
    }



    var pagex = event.touches[0].pageX - st.startX
    var movex = pagex > 0 ? Math.min(st.delBtnWidth, pagex) : Math.max(-st.delBtnWidth, pagex)


    // //已觸發(fā)垂直滑動听哭,由scroll-view處理滑動操作;
    // //手指起始點(diǎn)位置與移動期間的差值 
    var pagey = event.touches[0].pageY - st.startY;
    // //未觸發(fā)滑動方向
    if (swipeDirection === 0) {

      //觸發(fā)垂直操作
      if (Math.abs(pagey) > 20) {
        swipeDirection = 2;

        return;
      }
      //觸發(fā)水平操作
      if (Math.abs(movex) > 4) {

        swipeDirection = 1;
        ownerInstance.callMethod('scrollYFn', {
          scrollY: false
        })
      } else {
        // return;
      }

    }
    // 往回滑動的情況
    var goods = ownerInstance.selectAllComponents('.good-con')
    goods.map(function(item) {
      var itemOut = item.getState().out
      if (itemOut) {
        item.setStyle({
          'transform': 'translateX(0px)',
          'transition': 'transform 0.4s'
        })
      }
    })

    if (st.out) {
      // 已經(jīng)是劃出來了慢洋,還要往左滑動,忽略
      if (movex < 0) return
      ins.setStyle({
        'transform': 'translateX(' + (st.transformx + movex) + 'px)',
        'transition': ''
      })

      return
    }

    if (movex > 0) movex = 0

    st.transformx = movex

    ins.setStyle({
      'transform': 'translateX(' + movex + 'px)',
      'transition': ''
    })

    ownerInstance.callMethod('wxsTouchmove')

    return
  }

}


var touchend = function(event, ownerInstance) {
  var ins = event.instance
  var st = ins.getState()
  if (!st.isMoving) return
  st.isMoving = false
 

  swipeDirection = 0;
  if (event.changedTouches.length == 1) {
    //手指移動結(jié)束后水平位置
    var endX = event.changedTouches[0].clientX;
    var endY = event.changedTouches[0].clientY;
    //觸摸開始與結(jié)束陆盘,手指移動的距離
    var disX = st.startX - endX;
    var disY = st.startY - endY;
    var delBtnWidth = st.delBtnWidth;
    // if ((Math.abs(disY) > 10 && disX < delBtnWidth) || disX<0) {
    if (Math.abs(event.changedTouches[0].pageX - st.startX) < st.throttle || event.changedTouches[0].pageX - st.startX > 0) {
      st.out = false
      ins.setStyle({
        'transform': 'translateX(0px)',
        'transition': 'transform 0.4s'
      })
      ownerInstance.callMethod('scrollYFn', {
        scrollY: true
      })
      return;
    }


    //如果距離小于刪除按鈕的1/2普筹,不顯示刪除按鈕
    var txtStyle = disX > delBtnWidth / 2 ? "-" + delBtnWidth : "0";

    ins.setStyle({
      'transform': 'translateX(' + (txtStyle) + 'px)',
      'transition': 'transform 0.4s'
    })
    st.out = true;
    st.transformx = -Math.abs(txtStyle)
    if (disX <= delBtnWidth / 2) {
      ownerInstance.callMethod('scrollYFn', {
        scrollY: true
      })
    }
  }
  ownerInstance.callMethod('show')
}


var hideButton = function(event, ownerInstance) {
  var goods = ownerInstance.selectAllComponents('.good-con')

  goods.map(function(item) {
    if (item.hasClass('touchmove')) {
      item.setStyle({
        'transform': 'translateX(0px)',
        'transition': 'transform 500ms'
      })
    }
  })

  st.transformx = 0
  ownerInstance.callMethod('buttonTapByWxs', {
    id: event.currentTarget.dataset.id
  })
  return false
}

var delBtnWidthFn = function(newVal, oldVal, ownerInstance, ins) {
  var st = ins.getState()
  st.transformx = 0
  st.delBtnWidth = newVal;
  st.throttle = 40 // 固定值
}

module.exports = {
  touchstart: touchstart,
  touchmove: touchmove,
  touchend: touchend,
  hideButton: hideButton,
  delBtnWidthFn: delBtnWidthFn

}
//wxml
<wxs src="./../common/slideview.wxs" module="slideHander"></wxs>

//...
<view class="good-con flex"  bindtouchstart="{{slideHander.touchstart}}" bindtouchmove="{{slideHander.touchmove}}" bindtouchend="{{slideHander.touchend}}" delbtnwidth="{{delBtnWidth}}" change:delbtnwidth="{{slideHander.delBtnWidthFn}}"></view>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市隘马,隨后出現(xiàn)的幾起案子太防,更是在濱河造成了極大的恐慌,老刑警劉巖酸员,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜒车,死亡現(xiàn)場離奇詭異,居然都是意外死亡幔嗦,警方通過查閱死者的電腦和手機(jī)酿愧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崭添,“玉大人寓娩,你說我怎么就攤上這事叛氨『粼” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵寞埠,是天一觀的道長屁置。 經(jīng)常有香客問我,道長仁连,這世上最難降的妖魔是什么蓝角? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮饭冬,結(jié)果婚禮上使鹅,老公的妹妹穿的比我還像新娘。我一直安慰自己昌抠,他們只是感情好患朱,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炊苫,像睡著了一般裁厅。 火紅的嫁衣襯著肌膚如雪冰沙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天执虹,我揣著相機(jī)與錄音拓挥,去河邊找鬼。 笑死袋励,一個胖子當(dāng)著我的面吹牛侥啤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播插龄,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼愿棋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了均牢?” 一聲冷哼從身側(cè)響起糠雨,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徘跪,沒想到半個月后甘邀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡垮庐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年松邪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哨查。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡逗抑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寒亥,到底是詐尸還是另有隱情邮府,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布溉奕,位于F島的核電站褂傀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏加勤。R本人自食惡果不足惜仙辟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鳄梅。 院中可真熱鬧叠国,春花似錦、人聲如沸戴尸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吆玖,卻和暖如春筒溃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沾乘。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工怜奖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翅阵。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓歪玲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親掷匠。 傳聞我的和親對象是個殘疾皇子滥崩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

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

  • 因新工作主要負(fù)責(zé)微信小程序這一塊,最近的重心就移到這一塊讹语,該博客是對微信小程序整體的整理歸納以及標(biāo)明一些細(xì)節(jié)點(diǎn)钙皮,初...
    majun00閱讀 7,345評論 0 9
  • 引言 WXS(WeiXin Script)是小程序的一套腳本語言,結(jié)合 WXML顽决,可以構(gòu)建出頁面的結(jié)構(gòu)短条。 注意 w...
    OzanShareing閱讀 1,397評論 0 3
  • 1官方解讀 wxs 與 javascript 是不同的語言,有自己的語法才菠,并不和 javascript 一致茸时。其實(shí)...
    嘻洋洋閱讀 7,450評論 0 4
  • 在我們?nèi)松母鱾€階段里好像永遠(yuǎn)繞不過去一個字,就是“怕”赋访。幼兒園時怕黑可都,小學(xué)時怕寫作業(yè),中學(xué)時怕考不上重點(diǎn)高中蚓耽、重...
    circle_local閱讀 315評論 0 2
  • 堅(jiān)持分享26天 俗話說萬事開頭難渠牲,有些事,如果不行動田晚,我們永遠(yuǎn)發(fā)現(xiàn)不了這些事其實(shí)我們是可以做得到的嘱兼。...
    一祉微笑閱讀 112評論 0 0