云開發(fā) 頁面渲染

2020-07-20 11:21 更新

在數(shù)據(jù)綁定章節(jié),我們已經(jīng)掌握如何把data里面的數(shù)據(jù)渲染到頁面,這一部分我們會(huì)介紹如何通過點(diǎn)擊組件綁定的事件處理函數(shù)來修改data里面的數(shù)據(jù),如何把事件處理函數(shù)獲取到的數(shù)據(jù)打印到頁面。

將變量值渲染到頁面

還記得我們之前在控制臺(tái)打印的Date對(duì)象、Math對(duì)象、字符串String對(duì)象以及常量么?在第一節(jié)里我們把這些對(duì)象賦值給了一個(gè)變量,然后通過控制臺(tái)可以把這些值給console.log()打印出來,那這些值可不可以渲染到小程序的頁面上呢?答案是肯定的。

將變量值渲染到頁面

使用開發(fā)者工具新建一個(gè)頁面比如data,然后在data.js的Page({})函數(shù)的前面,也就是不寫在Page函數(shù)里面,寫在data.js的第1行輸入以下代碼:



let lesson = "云開發(fā)技術(shù)訓(xùn)練營(yíng)";


let enname = "CloudBase Camp";


let x = 3, y = 4, z = 5.001, a = -3, b = -4, c = -5;


let now = new Date();

注意上面這些是JavaScript函數(shù)的語句,所以用的是分號(hào);分隔,這個(gè)不要和之前的逗號(hào)分隔給弄混了哦。如果語句是換行的,后面的分號(hào);也可以不必寫。

然后在data里面添加如下數(shù)據(jù)(注意沒有雙引號(hào),單雙引號(hào)里的是字符串)



data: {


    charat: lesson.charAt(4),


    concat: enname.concat(lesson),


    uppercase:enname.toUpperCase(),


    abs:Math.abs(b),


    pow: Math.pow(x, y),


    sign:Math.sign(a),


    now:now,


    fullyear:now.getFullYear(),


    date:now.getDate(),


    day: now.getDay(),


    hours: now.getHours(),


    minutes: now.getMinutes(),


    seconds: now.getSeconds(),


    time: now.getTime()


},

在data.wxml里輸入以下代碼:



<view>"云開發(fā)技術(shù)訓(xùn)練營(yíng)"第5個(gè)字符 {{charat}}</view>


<view>兩個(gè)字符串連接后的結(jié)果:{{concat}}</view>


<view>CloudBase Camp字母大寫:{{uppercase}}</view>


<view>b的絕對(duì)值:{{abs}}</view>


<view>x的y次冪:{{pow}}</view>


<view>返回a是正還是負(fù):{{sign}}</view>


<view>now對(duì)象:{{now}}</view>


<view>{{fullyear}}年</view>


<view>{{date}}日</view>


<view>星期{{day}}</view>


<view>{{hours}}時(shí)</view>


<view>{{minutes}}分</view>


<view>{{seconds}}秒</view>


<view>1970年1月1日至今的毫秒數(shù):{{time}}</view>

因?yàn)閐ata是一個(gè)對(duì)象Object,我們可以通過冒號(hào):的方式將變量值賦值給data里的各個(gè)屬性,而在數(shù)據(jù)綁定章節(jié),這些數(shù)據(jù)是可以直接渲染到小程序的頁面的。

toString()方法

我們發(fā)現(xiàn){{now}}渲染的結(jié)果是一個(gè)對(duì)象[object Object],而并沒有顯示出字符串文本,這個(gè)時(shí)候就需要用到對(duì)象的toString()方法,得到對(duì)象的字符串。將data里now的賦值改為如下:



now:now.toString(),

技術(shù)文檔:toString()方法

響應(yīng)的數(shù)據(jù)綁定

邏輯層js文件里的data數(shù)據(jù),無論是基礎(chǔ)的字符串、數(shù)組、對(duì)象等,還是通過變量給賦的值,都可以渲染到頁面。不僅如此,只要對(duì)邏輯層data里的數(shù)據(jù)進(jìn)行修改,視圖層也會(huì)做相應(yīng)的更新,我們稱之為響應(yīng)的數(shù)據(jù)綁定,而這是通過Page的setData()方法來實(shí)現(xiàn)的。

使用開發(fā)者工具在data.wxml里輸入:



<view style="background-color:{{bgcolor}};width:400rpx;height:300rpx;"></view>


<button bindtap="redTap">讓背景變紅</button>


<button bindtap="yellowTap">讓背景變黃</button>

然后在data.js里添加一個(gè)數(shù)據(jù)



bgcolor:"#000000",

然后在js里添加兩個(gè)button綁定的事件處理函數(shù)redTap和yellowTap:



redTap:function(){


    this.setData({


        bgcolor: "#cd584a"


    })


},


yellowTap:function(){


    this.setData({


        bgcolor: "#f8ce5f"


    })


},

點(diǎn)擊button,原來view組件的背景顏色由黑色變成了其他顏色,這是因?yàn)辄c(diǎn)擊組件觸發(fā)事件處理函數(shù),調(diào)用了Page的setData()方法修改了data里與之相應(yīng)的屬性的值(重復(fù)賦值就是修改),bgcolor由原來的”#000000″,變成了其他數(shù)據(jù)。

小任務(wù):通過以往的學(xué)習(xí)我們了解到無論是組件的樣式,圖片、鏈接的路徑,數(shù)組、對(duì)象里的數(shù)據(jù),他們都是可以進(jìn)行數(shù)據(jù)分離寫到data里面的,這也就意味著,我們通過點(diǎn)擊事件改變data里面的數(shù)據(jù)可以達(dá)到很多意想不到的效果,請(qǐng)發(fā)揮你的想象力做一些有意思的案例出來。

響應(yīng)的布爾操作

在前面我們已經(jīng)了解到,有些組件的私有屬性的數(shù)據(jù)類型為Boolean布爾值,比如視頻、Swiper輪播組件是否自動(dòng)播放、是否輪播,視頻組件是否顯示播放按鈕等等,這些我們都可以使用setData將true改為false,false改為true來達(dá)到控制的目的。

在交互方面,響應(yīng)的布爾操作可以用于單一屬性true與false的切換,比如顯示與隱藏、展開與折疊、聚焦與失焦、選中與不選中。

我們來看一個(gè)案例,使用開發(fā)者工具在data.wxml里輸入以下代碼:



<video id="daxueVideo" src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400" rel="external nofollow"  autoplay loop muted="{{muted}}" initial-time="100" controls event-model="bubble">


</video>


<button bindtap="changeMuted">靜音和取消靜音</button>

然后給在data.js的data里新增



muted: true,

然后添加changeMuted事件處理函數(shù)



changeMuted: function (e) {


  this.setData({


    muted: !this.data.muted


  })


},

在開發(fā)者工具的模擬器里點(diǎn)擊按鈕,我們發(fā)現(xiàn)靜音和取消靜音都是這個(gè)按鈕。這里的感嘆號(hào) !是邏輯非的意思,可以理解為not。

this.setData和 this.data都用到了一個(gè)關(guān)鍵字 this。 this和中文里的“這個(gè)的”有類似的指代作用,在方法中, this 指代該方法所屬的對(duì)象,比如這里的是Page對(duì)象, this.data就是指Page函數(shù)對(duì)象里的data對(duì)象。

響應(yīng)的數(shù)組操作

結(jié)合點(diǎn)擊事件以及數(shù)組操作的知識(shí),我們?cè)賮砜聪旅孢@個(gè)案例,了解如何通過點(diǎn)擊按鈕新增數(shù)組里的數(shù)據(jù)和刪除數(shù)組里的數(shù)據(jù)。

使用開發(fā)者工具在data.wxml里輸入以下代碼,注意這里視圖層只有一個(gè){{text}},也就是說我們之后會(huì)把所有的數(shù)據(jù)都賦值給data里的text。



<view>{{text}}</view>


<button bindtap="addLine">新增一行</button>


<button bindtap="removeLine">刪掉最后一行</button>

然后在data.js的Page()之前聲明變量,這里聲明extraLine為一個(gè)空數(shù)組,我們之后會(huì)往這個(gè)數(shù)組里添加和刪除數(shù)據(jù)。



let initData = '只有一行原始數(shù)據(jù)'


let extraLine = [];

然后再在Page的data里添加一條數(shù)據(jù),



text: initData,

我們先來看沒有事件處理函數(shù)時(shí),數(shù)據(jù)渲染的邏輯,首先我們把initData變量值賦值給text,這時(shí)渲染的結(jié)果只有initData里的數(shù)據(jù),所以頁面顯示的是“只有一行原始數(shù)據(jù)”,而extraLine和text沒有什么關(guān)系。

我們?cè)賮碓赑age里添加addLine和removeLine的事件處理函數(shù):



addLine: function (e) {


  extraLine.push('新增的內(nèi)容')


  this.setData({


    text: initData + '\n' + extraLine.join('\n')


  })


},


removeLine: function (e) {


  if (extraLine.length > 0) {


      extraLine.pop()


      this.setData({


        text: initData + '\n' + extraLine.join('\n')


      })


  }


},

首先回顧一下之前的數(shù)組操作知識(shí),push為往數(shù)組的末尾新增數(shù)據(jù),而pop則刪除數(shù)組末尾一行的數(shù)據(jù),join為數(shù)組數(shù)據(jù)之前的連接符。

點(diǎn)擊按鈕新增一行,觸發(fā)綁定的事件處理函數(shù)addLine,首先會(huì)執(zhí)行extraLine數(shù)組新增一條數(shù)據(jù)“新增的內(nèi)容”,但是這時(shí)extraLine和text還沒有關(guān)系,這時(shí)在setData()函數(shù)里將initData和extraLine進(jìn)行拼接(注意extraLine本來是一個(gè)數(shù)組,但是調(diào)用join方法后返回的是數(shù)組的值拼接好的字符串)。點(diǎn)擊按鈕刪除最后一行,會(huì)先刪除extraLine數(shù)組里最后一行的數(shù)據(jù)。

小任務(wù):新增內(nèi)容過于單一,我們可以給它后面添加一個(gè)隨機(jī)數(shù),將 extraLine.push('新增的內(nèi)容')改成 extraLine.push('新增的內(nèi)容'+Math.random()),再來看看新增數(shù)據(jù)的效果,關(guān)于Math.random()大家可以自行去MDN查閱。大家也可以把拼接的連接符由 \n換成其他字符。

函數(shù)與調(diào)用函數(shù)

函數(shù)的作用,可以寫一次代碼,然后反復(fù)地重用這個(gè)代碼。JavaScript的函數(shù)本身也是對(duì)象,因此可以把函數(shù)賦值給變量,或者作為參數(shù)傳遞給其他函數(shù)。

函數(shù)的定義和結(jié)構(gòu)

我們可以使用function關(guān)鍵詞來定義一個(gè)函數(shù),括號(hào)()里為函數(shù)的參數(shù),參數(shù)可以有很多個(gè),使用逗號(hào),隔開;函數(shù)要執(zhí)行的代碼(語句)使用大括號(hào){}包住:



function 函數(shù)名(參數(shù) 1, 參數(shù) 2, 參數(shù) 3) {


    代碼塊內(nèi)要執(zhí)行的語句


}

不帶參數(shù)的函數(shù)

比如,我們使用開發(fā)者工具在data.js的Page()函數(shù)前,添加如下代碼:



function greet() {


    console.log("你好,歡迎來到云開發(fā)訓(xùn)練營(yíng)");


};


greet(); //調(diào)用greet()函數(shù)

保存之后,我們可以在控制臺(tái)看到函數(shù)打印的字符串。定義一個(gè)函數(shù)并不會(huì)自動(dòng)的執(zhí)行它。定義了函數(shù)僅僅是賦予函數(shù)以名稱并明確函數(shù)被調(diào)用時(shí)該做些什么。調(diào)用函數(shù)才會(huì)以給定的參數(shù)真正執(zhí)行這些動(dòng)作。greet()函數(shù)沒有參數(shù),調(diào)用函數(shù)時(shí),直接寫函數(shù)名+括號(hào)即可。

只有一個(gè)參數(shù)的函數(shù)

下面定義了一個(gè)簡(jiǎn)單的平方函數(shù)square(),square為函數(shù)名,number為函數(shù)的參數(shù)(名稱可以自定義),使用return語句確定函數(shù)的返回值。我們繼續(xù)在data.js的Page()函數(shù)前,輸入以下代碼:



function square(number) { 


  return number * number;  


}; 


square(5);

square(5),就是把5賦值給變量number,然后執(zhí)行numbernumber,也就是55,然后返回return這個(gè)值。

這里的number被稱之為形參,而5被稱之為實(shí)參。大家可以結(jié)合案例就能大致了解形參和實(shí)參的意思。

  • 形參是在定義函數(shù)時(shí)使用的參數(shù),目的是用來接收調(diào)用該函數(shù)時(shí)傳進(jìn)來的實(shí)際參數(shù)。

  • 實(shí)參是在調(diào)用時(shí)傳遞給函數(shù)的參數(shù)

JavaScript允許傳入任意個(gè)參數(shù)而不影響調(diào)用,因此傳入的參數(shù)可以比定義的參數(shù)多,但是不能少。也就是說實(shí)參的數(shù)量可以多于形參但是不能少于形參。

對(duì)象的方法

在小程序里我們會(huì)經(jīng)常將一個(gè)匿名函數(shù)賦值給對(duì)象的一個(gè)屬性,而這個(gè)屬性我們可以稱之為對(duì)象的方法。

匿名函數(shù)

函數(shù)聲明function在語法上是一個(gè)語句,但函數(shù)也可以由函數(shù)表達(dá)式創(chuàng)建,這樣的函數(shù)沒有函數(shù)名稱(匿名)。

使用開發(fā)者工具在data.js的Page()函數(shù)前,輸入以下代碼:



let square = function(number) {


  return number * number


};


console.log(square(4))//使用console.log()輸出變量square

執(zhí)行后,可以在控制臺(tái)看到輸出的結(jié)果為16。上面這個(gè)function函數(shù)沒有函數(shù)名,相當(dāng)于是把函數(shù)的返回值賦值給了變量square。

箭頭函數(shù)

為什么叫箭頭函數(shù)(Arrow Function),因?yàn)樗x一個(gè)函數(shù)用的就是一個(gè)箭頭=>,我們來看兩個(gè)例子,在data.js的Page()函數(shù)前輸入以下代碼:



const multiply = (x, y) => {


  return x * y;


}


const sum= (x, y) => x + y;//連{}和return語句都可以省掉


console.log(multiply(20, 4));


console.log(sum(20, 4));

在控制臺(tái)我們可以看到箭頭函數(shù)打印的結(jié)果。箭頭函數(shù)相當(dāng)于匿名函數(shù),它沒有函數(shù)名,而且也簡(jiǎn)化了函數(shù)定義。箭頭函數(shù)可以只包含一個(gè)表達(dá)式,甚至連{ … }和return都可以省略掉。大家可以先只需要了解這個(gè)寫法就可以了,以后碰到不至于比較迷惑,見多了也試著嘗試多寫一下。

調(diào)用對(duì)象的方法

可以使用點(diǎn)表示法來調(diào)用對(duì)象的方法,這個(gè)和訪問對(duì)象的屬性沒有區(qū)別。而調(diào)用對(duì)象的方法和調(diào)用一個(gè)函數(shù)也是大同小異。

調(diào)用對(duì)象的方法我們?cè)谇懊婢鸵呀?jīng)接觸過大量的案例了,在前面我們已經(jīng)說過,wx是小程序的全局對(duì)象,而在第一節(jié)我們打印的很多API,就是調(diào)用了wx對(duì)象里的方法。

JavaScript函數(shù)的寫法

在點(diǎn)擊事件章節(jié)里,我們創(chuàng)建的事件點(diǎn)擊處理函數(shù)的寫法如下:



scrollToPosition() {


    },

而在這一節(jié)我們創(chuàng)建的事件點(diǎn)擊函數(shù)的寫法為:



yellowTap:function(){


},

這兩種寫法都是可以執(zhí)行的,大家可以把這兩種寫法互相修改一下試試看~

currentTarget事件對(duì)象

在前面的列表渲染里,我們知道點(diǎn)擊電影列表里的某一部電影,要進(jìn)行頁面跳轉(zhuǎn)顯示該電影的詳情,我們需要給該電影創(chuàng)建一個(gè)頁面,那如果要顯示數(shù)千部的電影的詳情,一一創(chuàng)建電影詳情頁顯然不合適,畢竟所有電影的詳情頁都是同一一個(gè)結(jié)構(gòu),有沒有辦法所有電影詳情都共用一個(gè)頁面,但是根據(jù)點(diǎn)擊的鏈接的不同,渲染相應(yīng)的數(shù)據(jù)?答案是肯定的,要解決這個(gè)問題,首先我們要了解鏈接組件的點(diǎn)擊信息。

當(dāng)點(diǎn)擊組件觸發(fā)事件時(shí),邏輯層綁定該事件的處理函數(shù)會(huì)收到一個(gè)事件對(duì)象,通過 event 對(duì)象可以獲取事件觸發(fā)時(shí)候的一些信息,比如時(shí)間戳、 detail 以及當(dāng)前組件的一些屬性值集合,尤其是事件源組件的id。

currentTarget是事件對(duì)象的一個(gè)屬性,表示的是事件綁定的當(dāng)前組件。使用開發(fā)者工具在data.wxml里輸入以下代碼



<view class="weui-navbar">


    <block wx:for="{{tabs}}" wx:key="index">


        <view id="{{index}}" class="weui-navbar__item {{activeIndex == index ? 'weui-bar__item_on' : ''}}" bindtap="tabClick">


            <view class="weui-navbar__title">{{item}}</view>


        </view>


    </block>


</view>


<view class="weui-tab__panel">


    <view hidden="{{activeIndex != 0}}">帝都</view>


    <view hidden="{{activeIndex != 1}}">魔都</view>


    <view hidden="{{activeIndex != 2}}">妖都</view>


    <view hidden="{{activeIndex != 3}}">漁村</view>


</view>

然后再往data.js的data里添加以下數(shù)據(jù):



tabs: ["北京", "上海", "廣州", "深圳"],


activeIndex:0,

然后再添加事件處理函數(shù)tabClick。



tabClick: function (e) {


  console.log(e)


  this.setData({


    activeIndex: e.currentTarget.id


  });


},

編譯之后在模擬器里預(yù)覽。當(dāng)我們點(diǎn)擊上面的tab時(shí),觸發(fā)tabClick事件處理函數(shù),這時(shí)候事件處理函數(shù)會(huì)收到一個(gè)事件對(duì)象e,我們可以看一下控制臺(tái)打印的e對(duì)象的內(nèi)容,關(guān)于e對(duì)象具體屬性的解釋可以看技術(shù)文檔。

技術(shù)文檔:事件對(duì)象

currentTarget就是事件對(duì)象的一個(gè)屬性,我們可以使用點(diǎn)表示法獲取到點(diǎn)擊的組件的Id,并將其賦值給activeIndex,所謂active就是激活的意思,也就是我們點(diǎn)擊哪個(gè)tab,哪個(gè)tab就激活。

  • 當(dāng)點(diǎn)擊的id為0,也就是第一個(gè)tab時(shí),activeIndex的值被事件處理函數(shù)修改為0;

  • activeIndex == index相同的tab,也就是激活的tab就會(huì)有weui-bar__item_on的class,也就顯示為綠色

  • !=是不等于操作符,activeIndex != 0顯然不成立條件為false,也就是組件hidden為false,即為顯示;而activeIndex != 1,2,3則都會(huì)true,hidden生效,組件不顯示,于是tab的效果就有了。

當(dāng)我們對(duì)字符串、Math對(duì)象、Date對(duì)象、數(shù)組對(duì)象、函數(shù)對(duì)象、事件對(duì)象所包含的信息不了解時(shí),把他們打印出來即可。打印出來的結(jié)果基本都是字符串、列表、對(duì)象,而在前面我們已經(jīng)掌握如何操作它們。通過實(shí)戰(zhàn),通過打印日志,既有利于我們調(diào)試代碼,也加強(qiáng)我們對(duì)邏輯的理解。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)