05微信小程序-視圖與邏輯3

頁面導(dǎo)航

頁面導(dǎo)航就是頁面之間的跳轉(zhuǎn),小程序中頁面之間的導(dǎo)航有兩種方式:
① 聲明式導(dǎo)航:通過點擊 navigator 組件實現(xiàn)頁面跳轉(zhuǎn)的方式;
② 編程式導(dǎo)航:通過調(diào)用小程序的 API 接口實現(xiàn)跳轉(zhuǎn)的方式;

聲明式導(dǎo)航

導(dǎo)航到非 tabBar 頁面

tabBar 頁面指的是沒有被當作 tabBar 進行切換的頁面。

<navigator url="/pages/about/about">跳轉(zhuǎn)到 about 頁面</navigator>

注意事項

  • url 屬性設(shè)置需要跳轉(zhuǎn)的路徑
  • 頁面路徑應(yīng)該以 / 開頭,
  • 路徑必須提前在 app.jsonpages 節(jié)點下聲明
導(dǎo)航到 tabBar 頁面

navigator組件單純使用 url 屬性,無法導(dǎo)航到 tabBar 頁面,必須需要結(jié)合 open-type 屬性進行導(dǎo)航。

<navigator url="/pages/person/person" open-type="switchTab">跳轉(zhuǎn)到 tabBar 頁面</navigator>
后退導(dǎo)航

小程序如果要后退到上一頁面或多級頁面,需要把 open-type 設(shè)置為 navigateBack,同時使用 delta 屬性指定后退的層數(shù)

<navigator open-type='navigateBack' delta='1'> 返回上一頁 </navigator>
<navigator open-type='navigateBack' delta='2'> 返回上上一頁 </navigator>

編程式導(dǎo)航

導(dǎo)航到非 tabBar 頁面

通過 wx.navigateTo(Object object) 方法,可以跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面。
但是不能跳到 tabbar 頁面。
參數(shù)文檔wx.navigateTo 詳細文檔

// 跳轉(zhuǎn)到非導(dǎo)航頁面
handle: function () {
  wx.navigateTo({
    url: '/pages/about/about',
    success: function () {
      console.log('Hello about')
    }
  })
},
導(dǎo)航到 tabBar 頁面

通過 wx.switchTab(Object object) 方法,可以跳轉(zhuǎn)到 tabBar 頁面,
并關(guān)閉其他所有非 tabBar 頁面
參數(shù)文檔wx.switchTab 詳細文檔

// 跳轉(zhuǎn)到 tabBar 頁面
tabBarHandle: function () {
  wx.switchTab({
    url: '/pages/person/person',
    success: function() {
      console.log('Hello Person')
    }
  })
},
后退導(dǎo)航

通過 wx.navigateBack(Object object)方法,關(guān)閉當前頁面,返回上一頁面或多級頁面。
參數(shù)文檔wx.navigateBack 詳細文檔

handle: function () {
  wx.navigateBack({
    delta: 1
  })
},

twoHandle: function () {
  wx.navigateBack({
    delta: 2
  })
},

小程序?qū)Ш?-- 導(dǎo)航傳參

####### 聲明式導(dǎo)航傳參

navigator 組件的 url 屬性用來指定導(dǎo)航到的頁面路徑,同時路徑后面還可以攜帶參數(shù),參數(shù)與路徑之間使用 ? 分隔,參數(shù)鍵與參數(shù)值用 = 相連,不同參數(shù)用 & 分隔。

<navigator url="/pages/about/about?age=18&name=shuji">跳轉(zhuǎn)到 about 頁面</navigator>
編程式導(dǎo)航傳參

wx.navigateTo(Object object) 方法的 object 參數(shù)中,url 屬性用來指定需要跳轉(zhuǎn)的應(yīng)用內(nèi)非 tabBar 的頁面的路徑, 路徑后可以帶參數(shù)。參數(shù)與路徑之間使用 ? 分隔,參數(shù)鍵與參數(shù)值用 = 相連,不同參數(shù)用 & 分隔。

// 跳轉(zhuǎn)到 tabBar 頁面
tabBarHandle: function () {
  wx.switchTab({
    url: '/pages/person/person?age=18&name=shuji',
    success: function() {
      console.log('Hello Person')
    }
  })
},
接受傳遞的參數(shù)

不論是聲明式導(dǎo)航還是編程式導(dǎo)航,最終導(dǎo)航到的頁面可以在 onLoad 生命周期函數(shù)中接收傳遞過來的參數(shù)。

 onLoad: function (options) {
    // 打印傳遞出來的參數(shù)
    console.log(options)
  },
導(dǎo)航欄自定義編譯模式快速傳參

小程序每次修改代碼并編譯后,會默認從首頁進入,但是在開發(fā)階段,我們經(jīng)常會針對特定的頁面進行開發(fā),為了方便編譯后直接進入對應(yīng)的頁面,可以配置自定義編譯模式,步驟如下:

  • 單擊工具欄上的“普通編譯”下拉菜單
  • 單擊下拉菜單中的“添加編譯模式”選項
  • 在彈出的“自定義編譯條件窗口”,按需添加模式名稱、啟用頁面、啟動參數(shù)、進入場景等。


    image.png

網(wǎng)絡(luò)數(shù)據(jù)請求

配置服務(wù)器域名
  • 每個微信小程序需要事先設(shè)置一個通訊域名,小程序只可以跟指定的域名進行網(wǎng)絡(luò)通信。
  • 服務(wù)器域名請在 「小程序后臺-開發(fā)-開發(fā)設(shè)置-服務(wù)器域名」 中進行配置,配置時需要注意:
    • 域名只支持 https (requestuploadFiledownloadFile) 和 wss (connectSocket) 協(xié)議
    • 域名不能使用 IP 地址或 localhost
    • 域名必須經(jīng)過 ICP 備案
    • 服務(wù)器域名一個月內(nèi)可申請5次修改
      注意: 網(wǎng)絡(luò)配置詳情
跳過域名校驗
  • 在微信開發(fā)者工具中,可以臨時開啟 「開發(fā)環(huán)境不校驗請求域名、TLS 版本及 HTTPS 證書」 選項,跳過服務(wù)器域名的校驗。此時,在微信開發(fā)者工具中及手機開啟調(diào)試模式時,不會進行服務(wù)器域名的校驗。
    注意:在服務(wù)器域名配置成功后,建議開發(fā)者關(guān)閉此選項進行開發(fā),并在各平臺下進行測試,以確認服務(wù)器域名配置正確。
    注意: 網(wǎng)絡(luò)配置詳情

小程序發(fā)送 get 與 Post 請求

小程序發(fā)送請求使用 wx.request() 方法,

    1. 發(fā)起 get 請求:
getData: function () {
  wx.request({
    url: 'xxxx',
    method: 'get',
    success: function (res) {
      console.log(res)
    }
  })
},
    1. 發(fā)起 post 請求:
postData: function () {
  wx.request({
    url: 'https://www.liulongbin.top:8082/api/post',
    method: 'post',
    data: {
      name: 'shuji'
    },
    success: function (res) {
      console.log(res)
    }
  })
},

注意: method 如果不進行配置,默認參數(shù)是 get 請求方式
wx.request 詳細文檔說明

小程序中沒有跨域限制
  • 在普通網(wǎng)站開發(fā)中,由于瀏覽器的同源策略限制,存在數(shù)據(jù)的跨域請求問題,從而衍生出了 JSONP 和 CORS 兩種主流的跨域問題解決方案。
  • 注意:小程序的內(nèi)部運行機制與網(wǎng)頁不同,小程序中的代碼并不運行在瀏覽器中,因此小程序開發(fā)中,不存在數(shù)據(jù)的跨域請求限制問題
    關(guān)于微信小程序更多的數(shù)據(jù)請求內(nèi)容,請翻閱 wx.request() 的相關(guān)文檔:
    https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html

組件及組件之間的通訊

組件的創(chuàng)建
  • 在項目的根目錄中,鼠標右鍵,創(chuàng)建 components 文件夾 --> test
  • 在新建的 components -> test 文件夾上,鼠標右鍵,點擊“新建 Component”
  • 為新建的組件命名之后,會自動生成組件對應(yīng)的 4 個文件,后綴名分別為 .js.json.wxml.wxss
    注意:應(yīng)當盡量將不同的組件,存放到單獨的文件夾中,從而保證清晰的目錄結(jié)構(gòu)
組件的引用
  • 在需要引用組件的頁面中,找到頁面的 .json 配置文件,新增 usingComponents 節(jié)點
  • usingComponents 中,通過鍵值對的形式,注冊組件;鍵為注冊的組件名稱,值為組件的相對路徑
  • 在頁面的 .wxml 文件中,把注冊的組件名稱,以標簽形式在頁面上使用,即可把組件展示到頁面上
{
  "usingComponents": {
    "first-com": "../../component/com01/com01"
  }
}

注冊組件名稱時,建議把組件名稱使用中橫線進行連接,例如 vant-button 或 custom-button

使用樣式美化組件

小程序組件樣式 詳細文檔

  • 組件對應(yīng) wxss 文件的樣式,只對組件 wxml 內(nèi)的節(jié)點生效。編寫組件樣式時,需要注意以下幾點:
  • 組件和引用組件的頁面不能使用id選擇器(#a)、屬性選擇器([a])和標簽名選擇器,請改用 class 選擇器。
  • 組件和引用組件的頁面中使用后代選擇器(.a .b)在一些極端情況下會有非預(yù)期的表現(xiàn),如遇,請避免使用。
  • 子元素選擇器(.a>.b),只能用于 view 組件與其子節(jié)點之間,用于其他組件可能導(dǎo)致非預(yù)期的情況。
  • 繼承樣式,如 fontcolor ,會從組件外繼承到組件內(nèi)。
  • 除繼承樣式外, app.wxss 中的樣式、組件所在頁面的樣式對自定義組件無效。
使用 data 定義組件的私有數(shù)據(jù)
  • 小程序組件中的 data與小程序頁面中的 data 用法一致,區(qū)別是:
  • 頁面的 data 定義在 Page() 函數(shù)中
  • 組件的 data 定義在 Component() 函數(shù)中
  • 在組件的 .js 文件中:
  • 如果要訪問 data 中的數(shù)據(jù),直接使用 this.data.數(shù)據(jù)名稱 即可
  • 如果要為 data 中的數(shù)據(jù)重新賦值,調(diào)用 this.setData({ 數(shù)據(jù)名稱: 新值 }) 即可
  • 在組件的 .wxml 文件中
  • 如果要渲染 data 中的數(shù)據(jù),直接使用 {{ 數(shù)據(jù)名稱 }} 即可
使用 methods 定義組件的事件處理函數(shù)

組件間通信與事件 詳細文檔

  • 和頁面不同,組件的事件處理函數(shù),必須定義在 methods 節(jié)點中
methods: {
  handle: function () {
    console.log('組件的方法要定義在 methods 中')

    this.setData({
      num: this.data.num + 1
    })

    console.log(this.data.num)
  }
}

組件的 properties

properties 的作用

類似于 vue 組件中的 props, 小程序組件中的 properties,是組件的對外屬性,用來接收外界傳遞到組件中的數(shù)據(jù)。
在小程序中,組件的 properties 和 data 的用法類似,它們都是可讀可寫的,只不過:
data 更傾向于存儲組件的私有數(shù)據(jù)
properties 更傾向于存儲外界傳遞到組件中的數(shù)據(jù)

properties 語法結(jié)構(gòu)
Component({
  properties: {
    // 完整的定義方式
    propA: { // 屬性名
      type: String, // 屬性類型
      value: '' // 屬性默認值
    },
    propB: String // 簡化的定義方式
  }
})

注意:type 的可選值為 Number,String、Boolean、Object、Array、null(表示不限制類型)

為組件傳遞 properties 的值

使用數(shù)據(jù)綁定的形式,向子組件的屬性傳遞動態(tài)數(shù)據(jù)

<!-- 引用組件的頁面模板 -->
<view>
 <component-tag-name prop-a="{{dataFieldA}}" prop-b="{{dataFieldB}}">
 </component-tag-name>
</view>

注意:

  • 在定義 properties 時,屬性名采用駝峰寫法(propertyName);
  • 在 wxml 中,指定屬性值時,則對應(yīng)使用連字符寫法(property-name=“attr value”),
  • 應(yīng)用于數(shù)據(jù)綁定時,采用駝峰寫法(attr="{{propertyName}}")。
在組件內(nèi)修改 properties 的值

properties 的值是可讀可寫的,可以通過 setData 修改 properties 中任何屬性的值,

properties: {
  count: Number
 },
 methods: {
  add: function () {
  this.setData({ count: this.properties.count + 1 })
  } }

數(shù)據(jù)監(jiān)聽器

數(shù)據(jù)監(jiān)聽器可以用于監(jiān)聽和響應(yīng)任何屬性和數(shù)據(jù)字段的變化,從而執(zhí)行特定的操作。作用類似于 vue 中的watch。
數(shù)據(jù)監(jiān)聽器從小程序基礎(chǔ)庫版本 2.6.1 開始支持。
數(shù)據(jù)監(jiān)聽器的基本語法格式如下:

observers: {
  'propPrice, num': function (newPropPrice, newNum) {
    console.log(newPropPrice)
    console.log(newNum)
  }
}
案例1:監(jiān)控某個子數(shù)據(jù)的代碼
// 監(jiān)控某個子數(shù)據(jù)的代碼
Component({
  observers: {
    'some.subfield': function (subfield) {
      // 使用 setData 設(shè)置 this.data.some.subfield 時觸發(fā)
      // (除此以外,使用 setData 設(shè)置 this.data.some 也會觸發(fā))
    },
    'arr[12]': function (arr12) {
      // 使用 setData 設(shè)置 this.data.arr[12] 時觸發(fā)
      // (除此以外,使用 setData 設(shè)置 this.data.arr 也會觸發(fā))
    }
  }
})
案例2: 使用通配符 ** 監(jiān)聽所有子數(shù)據(jù)字段的變化
Component({
  observers: {
    'some.field.**': function (field) {
      // 使用 setData 設(shè)置 this.data.some.field 本身或其下任何子數(shù)據(jù)字段時觸發(fā)
      // (除此以外,使用 setData 設(shè)置 this.data.some 也會觸發(fā))
      field === this.data.some.field
    }
  }
})

組件的生命周期

組件的主要生命周期

組件的生命周期,指的是組件自身的一些函數(shù),這些函數(shù)在特殊的時間點或遇到一些特殊的框架事件時被自動觸發(fā)。

  • 最重要的生命周期是 created, attached, detached ,包含一個組件實例生命流程的最主要時間點。
    • 組件實例剛剛被創(chuàng)建好時, created 生命周期被觸發(fā)。此時還不能調(diào)用 setData 。 通常情況下,這個生命周期只應(yīng)該用于給組件 this 添加一些自定義屬性字段。
    • 在組件完全初始化完畢、進入頁面節(jié)點樹后, attached 生命周期被觸發(fā)。此時, this.data 已被初始化完畢。這個生命周期很有用,絕大多數(shù)初始化工作可以在這個時機進行。
    • 在組件離開頁面節(jié)點樹后, detached 生命周期被觸發(fā)。退出一個頁面時,如果組件還在頁面節(jié)點樹中,則 detached 會被觸發(fā)。
組件可用的全部生命周期函數(shù)
image.png
定義生命周期函數(shù)
  • 生命周期方法可以直接定義在 Component 構(gòu)造器的第一級參數(shù)中。
  • 自小程序基礎(chǔ)庫版本 2.2.3 起,組件的的生命周期也可以在 lifetimes 字段內(nèi)進行聲明(這是推薦的方式,其優(yōu)先級最高)。
Component({
 lifetimes: {
 attached() {}, // 在組件實例進入頁面節(jié)點樹時執(zhí)行
 detached() {}, // 在組件實例被從頁面節(jié)點樹移除時執(zhí)行
 },
 // 以下是舊式的定義方式,可以保持對 <2.2.3 版本基礎(chǔ)庫的兼容
 attached() {}, // 在組件實例進入頁面節(jié)點樹時執(zhí)行
 detached() {}, // 在組件實例被從頁面節(jié)點樹移除時執(zhí)行
 // ...
})

組件所在頁面的生命周期

有一些特殊的生命周期,它們并非與組件有很強的關(guān)聯(lián),但有時組件需要獲知,以便組件內(nèi)部處理。這樣的生命周期稱
為“組件所在頁面的生命周期”,在 pageLifetimes 定義段中定義。其中可用的生命周期包括:


image.png
Component({
 pageLifetimes: {
 show() { // 頁面被展示
 },
 hide() { // 頁面被隱藏
 },
 resize(size) { // 頁面尺寸變化
 }
 }
})

組件插槽

默認插槽
001 - 默認插槽

在組件的 wxml 中可以包含 slot 節(jié)點,用于承載組件使用者提供的 wxml 結(jié)構(gòu)。

  • 默認情況下,一個組件的 wxml 中只能有一個 slot。需要使用多 slot 時,可以在組件 js 中聲明啟用。
  • 注意:小程序中目前只有默認插槽和多個插槽,暫不支持作用域插槽。
  • 案例代碼:
    1.組件模板
// 組件模板

<view>
  <view>我是組件</view>
  <slot></slot>
</view>
  1. 引用組件的頁面模板
// 引用組件的頁面模板

<second-com>
  <view>你好,我是引用組件</view>
</second-com>
多個插槽

在組件中,需要使用多 slot 時,可以在組件 js 中聲明啟用。示例代碼如下:

Component({
  options: {
    multipleSlots: true
  },
})

可以在組件的 wxml 中使用多個 slot 標簽,以不同的 name 來區(qū)分不同的插槽。示例代碼如下:

<view>~~~~~~~~~~~~~~~~</view>
<slot name="before"/>
<view>~~~~~~~~~~~~~~~~</view>
<slot name="after"/>

使用時,用 slot 屬性來將節(jié)點插入到不同的 slot 中。示例代碼如下:


<!-- 引用組件的頁面模板 -->
<view>
 <component-tag-name>
 <!-- 這部分內(nèi)容將被放置在組件 <slot name="before"> 的位置上 -->
 <view slot="before">這里是插入到組件slot name="before"中的內(nèi)容</view>
 <!-- 這部分內(nèi)容將被放置在組件 <slot name="after"> 的位置上 -->
 <view slot="after">這里是插入到組件slot name="after"中的內(nèi)容</view>
 </component-tag-name>
</view>
組件間的通信
    1. 組件之間的三種基本通信方式
  • WXML 數(shù)據(jù)綁定:用于父組件向子組件的指定屬性傳遞數(shù)據(jù),僅能設(shè)置 JSON 兼容數(shù)據(jù)
  • 事件:用于子組件向父組件傳遞數(shù)據(jù),可以傳遞任意數(shù)據(jù)。
  • 父組件通過 this.selectComponent 方法獲取子組件實例對象,便可以直接訪問組件的任意數(shù)據(jù)和方法。

this.selectComponent(string)

<!-- wxml -->
<component-a class="customA" id= "cA" ></component-a>
<!--父組件的 .js 文件中,可以調(diào)用 selectComponent 函數(shù)并指定 id 或 class 選擇器,獲取子組件對象-->
Page({
 onLoad(){
 // 切記下面參數(shù)不能傳遞標簽選擇器(component-a),不然返回的是 null
 var component = this.selectComponent('.customA'); // 也可以傳遞 id 選擇器 #cA
 console.log(component);
 }
})
通過事件監(jiān)聽實現(xiàn)子向父傳值

事件系統(tǒng)是組件間通信的主要方式之一。自定義組件可以觸發(fā)任意的事件,引用組件的頁面可以監(jiān)聽這些事件。
通過事件監(jiān)聽實現(xiàn)子組件向父組件傳值的步驟:
① 在父組件的 js 中,定義一個函數(shù),這個函數(shù)即將通過自定義事件的形式,傳遞給子組件
② 在父組件的 wxml 中,通過自定義事件的形式,將步驟一中定義的函數(shù)引用,傳遞給子組件
③ 在子組件的 js 中,通過調(diào)用 this.triggerEvent('自定義事件名稱', { /* 參數(shù)對象 */ }) ,將數(shù)據(jù)發(fā)送到父組件
④ 在父組件的 js 中,通過 e.detail 獲取到子組件傳遞過來的數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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