現(xiàn)學(xué)現(xiàn)賣微信小程序開發(fā)(二)

現(xiàn)學(xué)現(xiàn)賣微信小程序開發(fā)(一)
現(xiàn)學(xué)現(xiàn)賣微信小程序開發(fā)(二)
現(xiàn)學(xué)現(xiàn)賣微信小程序開發(fā)(三):引入Rx腥刹,為小程序插上翅膀

一個Todo應(yīng)用的小程序版

好的把敞,那么下一步我們就先照貓畫虎刻获,新建一個todos文件夾,然后一套四樣同名文件準備齊全

新建todos目錄和相關(guān)文件
新建todos目錄和相關(guān)文件

先在app.json中報個到,在pages中加入 "pages/todos/todos"域醇。接下來把首頁 index.js 中的導(dǎo)航改為 ../todos/todos

//事件處理函數(shù)
  bindViewTap: function() {
    wx.navigateTo({
      url: '../todos/todos'
    })
  },

然后呢,我們簡單的先寫一個界面蓉媳,其實什么都沒有譬挚,就是一個view。把 todos.wxml 改成下面的模樣:

<!--todos.wxml-->
<view class="container todo-list">
  
</view>

然后把導(dǎo)航欄標(biāo)題設(shè)置一下酪呻,叫 Awesome Todos吧减宣,把 todos.json 改成下面的樣子:

{
    "navigationBarTitleText": "Awesome Todos"
}

樣式呢,也非常簡單粗暴的來一個吧:

.todo-list {
  display: block;
  padding: 40rpx;
  width: 100vw;
  margin: 0 auto;
}

快速搭建一個Web API

好的玩荠,下面我們要寫關(guān)鍵的 todos.js 了漆腌。在寫之前,我們需要一個服務(wù)器提供數(shù)據(jù)阶冈,這里介紹一個可以非趁颇颍快速便捷的搭建一個仿真Web API的利器:json-server。 使用 npm i -g json-server 安裝女坑,然后隨便挑一個目錄建一個todos-data.json 文件:

{
  "todos": [
    {
      "id": 1,
      "desc": "have breakfast",
      "completed": false
    },
    {
      "id": 2,
      "desc": "have lunch",
      "completed": false
    },
    {
      "id": 3,
      "desc": "take a break",
      "completed": false
    },
    {
      "id": 4,
      "desc": "having fun",
      "completed": false
    },
    {
      "id": 5,
      "desc": "新的服務(wù)器版本不錯",
      "completed": true
    }
  ]
}

這個時候填具,你的Web API就差一步之遙了,現(xiàn)在在命令行窗口敲入 json-server ./todos-data.json就大功告成了。

json-server服務(wù)啟動了
json-server服務(wù)啟動了

你可以打開瀏覽器輸入 http://localhost:3000/todos 看看是否返回的是我們的數(shù)據(jù)劳景。這個Web API是完全RESTful的誉简,也就是說

  • 查詢所有待辦事項:以GET方法訪問http://localhost:3000/todos
  • 查詢單個待辦事項:以GET方法訪問http://localhost:3000/todos/id,比如id是1盟广,那么訪問http://localhost:3000/todos/1
  • 更新某個待辦事項:以PUT方法訪問http://localhost:3000/todos/id
  • 刪除某個待辦事項:以DELETE方法訪問http://localhost:3000/todos/id
  • 增加一個待辦事項:以POST方法訪問http://localhost:3000/todos

回到正題闷串,開始Todo的開發(fā)

我們一開始的 todos.js 是這個樣子的:

const URL = 'http://localhost:3000/todos'

let pageParams = {
  data: { todos: [], desc: '' }
}

pageParams.onLoad = function () {
  const that = this
  wx.request({
    url: URL,
    data: JSON.stringify({}),
    header: { 'content-type': 'application/json' },
    method: 'GET',
    success: res => {
      console.log(res.data)
      that.setData({
        todos: res.data
      })
    },
    fail: () => console.error('something is wrong'),
    complete: () => console.log('todos loaded')
  })
}

Page(pageParams)

這段代碼非常簡單,創(chuàng)建一個pageParams對象并給本地數(shù)據(jù)初始化筋量。然后定義onLoad生命周期函數(shù)烹吵,利用 wx.request 創(chuàng)建一個 HTTP GET 請求取得返回的數(shù)據(jù),然后用setData去更新本地數(shù)據(jù)桨武。注意一點 const that = this 是一個常用的避免 this 的context出現(xiàn)切換時出現(xiàn)問題的小技巧年叮。再有就是我們無法直接寫入data,只能使用setData方法來進行更新玻募。

那么我們看看是否成功吧只损,點擊左側(cè)的調(diào)試,然后點首頁的頭像進入我們的todo頁面七咧,當(dāng)然現(xiàn)在界面上啥也沒有跃惫,但Console中還是有料滴。

Console中可以看到我們的Web API返回的結(jié)果
Console中可以看到我們的Web API返回的結(jié)果

既然API調(diào)通了艾栋,我們就來讓結(jié)果顯示到頁面上吧爆存,首先改造頁面如下。

<!--todos.wxml-->
<view class="container todo-list">
  <block wx:for="{{todos}}" wx:for-item="todo" wx:key="todo.id">
    <view class="todo-item">
      <text class="desc">{{todo.desc}}</text>
    </view>
  </block>
</view>

這段代碼中蝗砾,view 是個視圖容器先较,感覺可以把它想象成HTML中的div。微信小程序中除了 view 之外悼粮,目前還提供了 scroll-viewswiper 兩種容器闲勺,顧名思義 scroll-view 是用于可滾動的場景,而 swiper 是用于可以手指滑動切換內(nèi)容的場景扣猫。

在組件上使用 wx:for 綁定一個數(shù)組菜循,即可使用數(shù)組中各項的數(shù)據(jù)重復(fù)渲染該組件。wx:for-item 意思是設(shè)定數(shù)組當(dāng)前元素的變量名申尤。wx:key 設(shè)置列表中項目的唯一的標(biāo)識符癌幕。注意提供wx:key可以提升重新渲染時的性能,所以盡量提供昧穿。

block 是一個挺怪的設(shè)計勺远,它不是一個可視化的元素,感覺純粹為提供數(shù)據(jù)綁定而準備时鸵,在數(shù)據(jù)綁定時胶逢,以 block 來組織比較復(fù)雜的組件組合。所以block這一段的意思就是對于數(shù)組todos中的每一個todo,重復(fù)渲染下面這段

<view class="todo-item">
  <text class="desc">{{todo.desc}}</text>
</view>

當(dāng)然我們也需要拓展一下css宪塔,哦,不對囊拜,是wxss某筐。

.todo-list {
  display: block;
  padding: 40rpx;
  width: 100vw;
  margin: 0 auto;
}
.todo-item {
  display: flex;
  flex-direction: row;
  flex-basis: 1;
  justify-content: space-around;
  align-items: stretch;
  width: 80 vw;
  padding: 20rpx;
  border-bottom: 1rpx solid #ededed;
}
.desc {
  vertical-align: middle;
  flex-grow: 1;
}

現(xiàn)在看一下效果,列表成功顯示了冠跷。

todos列表
todos列表

事件的處理

現(xiàn)在我們給Todos添加兩個功能吧:Toggle(切換完成狀態(tài))和Remove(刪除該事項)南誊。這樣的話,需要給todo的描述之前加一個完成狀態(tài)的復(fù)選框以及一個在todo的描述之后的刪除按鈕蜜托。我們沒有使用微信提供的 checkbox 抄囚,而是用 icon 組件和 wx:if 來做處理,目的也是多展示一些特性橄务。

<!--todos.wxml-->
<view class="container todo-list">
  <block wx:for="{{todos}}" wx:for-item="todo" wx:key="todo.id">
    <view class="todo-item">
      <icon bindtap="toggleTodo" data-todo="{{todo}}" class="icon" type="success" wx:if="{{todo.completed}}"></icon>
      <icon bindtap="toggleTodo" data-todo="{{todo}}" class="icon" type="success_circle" wx:if="{{!todo.completed}}"></icon>
      <text bindtap="toggleTodo" data-todo="{{todo}}" class="desc">{{todo.desc}}</text>
      <icon bindtap="removeTodo" data-todo="{{todo}}" class="remove" type="clear"></icon>
    </view>
  </block>
</view>

上面的模版中幔托,我們看到多了一些新面孔:

  • wx:if:這個比較好理解,就是條件渲染蜂挪,在todo已完成的狀態(tài)下顯示一個icon重挑,未完成狀態(tài)下顯示另一個icon。
  • bindtap:這個是什么呢棠涮?它是微信小程序提供的綁定事件的機制谬哀,其綁定表達式為:bind+事件="事件處理函數(shù)"。我們上面的例子中的 bindtap="toggleTodo" 就是對于tap(觸碰后馬上離開)事件處理是一個在Page中定義的叫 toggleTodo 的函數(shù)严肪。
  • data-todo:很多時候我們需要在事件傳遞時攜帶一些數(shù)據(jù)過去史煎,比如Toggle這個功能,我們需要在事件處理函數(shù)中知道是哪個todo要切換完成狀態(tài)驳糯。data-todo就是定義要傳輸?shù)臄?shù)據(jù)用的篇梭,data表明是要在 事件中傳輸?shù)臄?shù)據(jù),而后面的todo表明這個數(shù)據(jù)在dataset中的key酝枢,通過這個key我們可以在Page中使用 event.target.dataset.todo得到這個數(shù)據(jù)很洋。這也意味著我們可以通過多個key傳遞多個數(shù)據(jù)。

值的注意的一點是除了 bindXXX 這種綁定事件的形式外隧枫,還有一種形式是 catchXXX喉磁,它們的區(qū)別是 bind 事件綁定不會阻止冒泡事件向上冒泡,catch 事件綁定可以阻止冒泡事件向上冒泡官脓。什么是冒泡呢协怒?事件會繼續(xù)向上(父組件或父節(jié)點)傳遞就是冒泡,反之就是非冒泡卑笨。

在微信小程序中孕暇,冒泡的事件如下表列出的,其他如沒有特殊的聲明都是非冒泡事件

事件 觸發(fā)條件
touchstart 手指觸摸動作開始
touchmove 手指觸摸后移動
touchcancel 手指觸摸動作被打斷,如來電提醒妖滔,彈窗
touchend 手指觸摸動作結(jié)束
tap 手指觸摸后馬上離開
longtap 手指觸摸后隧哮,超過350ms再離開

對于這些冒泡事件來說,如果我們要阻止其冒泡的行為座舍,可以使用 catchXXX 來綁定事件沮翔。

const URL = 'http://localhost:3000/todos'

let pageParams = {
  data: { todos: [], desc: '' }
}

pageParams.onLoad = function () {
  const that = this
  wx.request({
    url: URL,
    data: JSON.stringify({}),
    header: { 'content-type': 'application/json' },
    method: 'GET',
    success: res => {
      console.log(res.data)
      that.setData({
        todos: res.data
      })
    },
    fail: () => console.error('something is wrong'),
    complete: () => console.log('get req completed')
  })
}

pageParams.toggleTodo = function (event) {
  const that = this
  const selectedTodo = event.target.dataset.todo
  const url = `${URL}/${selectedTodo.id}`
  const updatedTodo = Object.assign({}, selectedTodo, {completed: !selectedTodo.completed})

  wx.request({
    url: url,
    data: JSON.stringify(updatedTodo),
    header: { 'content-type': 'application/json' },
    method: 'PUT',
    success: res => {
      console.log(res.data)
      that.setData({
        todos: that.data.todos.map(todo => {
          if(todo.id === updatedTodo.id){
            return updatedTodo
          }
          return todo
        })
      })
    },
    fail: () => console.error('something is wrong'),
    complete: () => console.log('toggle req completed')
  })
}

pageParams.removeTodo = function (event) {
  const that = this
  const selectedTodo = event.target.dataset.todo
  const url = `${URL}/${selectedTodo.id}`;
  
  wx.request({
    url: url,
    data: JSON.stringify(selectedTodo),
    header: { 'content-type': 'application/json' },
    method: 'DELETE',
    success: res => {
      console.log(res.data)
      that.setData({
        todos: that.data.todos.filter(todo => todo.id !== selectedTodo.id)
      })
    },
    fail: () => console.error('something is wrong'),
    complete: () => console.log('delete req completed')
  })
}

Page(pageParams)

接下來的事情就變的很簡單,我們在 todos.js 中增加兩個處理函數(shù)用于處理toggle和remove曲秉,事件處理函數(shù)有一個參數(shù)就是event采蚀。處理邏輯還是先提交HTTP請求處理服務(wù)器端數(shù)據(jù),處理成功后再處理本地內(nèi)存數(shù)據(jù)承二。

當(dāng)然 wxss 再更新一下:

.todo-list {
  display: block;
  padding: 40rpx;
  width: 100vw;
  margin: 0 auto;
}
.todo-item {
  display: flex;
  flex-direction: row;
  flex-basis: 1;
  justify-content: space-around;
  align-items: stretch;
  width: 80 vw;
  padding: 20rpx;
    border-bottom: 1rpx solid #ededed;
}
.icon {
  vertical-align: middle;
}
.remove {
  float: right;
  align-self: flex-end;
}
.desc {
  vertical-align: middle;
  flex-grow: 1;
}

現(xiàn)在的效果是這樣滴

可以工作的todo榆鼠,當(dāng)然還沒有新增todo的功能
可以工作的todo,當(dāng)然還沒有新增todo的功能

新增Todo亥鸠、過濾器妆够、優(yōu)化代碼結(jié)構(gòu)、引入Rx等話題我們后面繼續(xù)负蚊,這次就先到這里责静。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盖桥,隨后出現(xiàn)的幾起案子灾螃,更是在濱河造成了極大的恐慌,老刑警劉巖揩徊,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腰鬼,死亡現(xiàn)場離奇詭異,居然都是意外死亡塑荒,警方通過查閱死者的電腦和手機熄赡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來齿税,“玉大人彼硫,你說我怎么就攤上這事×杌” “怎么了拧篮?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牵舱。 經(jīng)常有香客問我串绩,道長,這世上最難降的妖魔是什么芜壁? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任礁凡,我火速辦了婚禮高氮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘顷牌。我一直安慰自己剪芍,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布窟蓝。 她就那樣靜靜地躺著罪裹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疗锐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天费彼,我揣著相機與錄音滑臊,去河邊找鬼。 笑死箍铲,一個胖子當(dāng)著我的面吹牛雇卷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颠猴,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼关划,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了翘瓮?” 一聲冷哼從身側(cè)響起贮折,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎资盅,沒想到半個月后调榄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡呵扛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年每庆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片今穿。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缤灵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蓝晒,到底是詐尸還是另有隱情腮出,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布芝薇,位于F島的核電站利诺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏剩燥。R本人自食惡果不足惜慢逾,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一立倍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侣滩,春花似錦口注、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至策添,卻和暖如春材部,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唯竹。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工乐导, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浸颓。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓物臂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親产上。 傳聞我的和親對象是個殘疾皇子棵磷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)晋涣,斷路器仪媒,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 這是vue官網(wǎng)的一個例子,挺適合作為vue應(yīng)用的入門的谢鹊。通過這個應(yīng)用规丽,我們能學(xué)到vue的【雙向綁定】,【v-for...
    進擊的前端閱讀 10,051評論 3 33
  • 昨天看了一下微信小程序官方文檔,總結(jié)一下自己學(xué)習(xí)的個人心得. 首先從官方文檔給的框架說起,微信小程序官方文檔給出了...
    Mr大大大閱讀 47,159評論 9 68
  • 最近做了一個投票的微信小程序,開發(fā)過程主要還是參考官方文檔:https://mp.weixin.qq.com/de...
    june5253閱讀 22,000評論 1 11
  • 微信小程序在無論在功能撇贺、文檔及相關(guān)支持方面赌莺,都是優(yōu)于前面幾種微信賬號類型,它提供了很多原生程序才有的接口松嘶,使得我們...
    伍華聰_開發(fā)框架閱讀 1,601評論 0 53