微信小程式基礎加強總結

2022-10-13 18:02:07
本篇文章給大家帶來了關於的相關問題,其中主要介紹了一些基礎內容,包括了自定義元件、樣式隔離、資料、方法和屬性等等內容,下面一起來看一下,希望對大家有幫助。

程式設計師必備介面測試偵錯工具:

【相關學習推薦:】

1、自定義元件

1.1、建立元件

  • 在專案的根目錄中,滑鼠右鍵,建立 components -> test 資料夾

  • 新建的 components -> test 資料夾上,滑鼠右鍵,點選新建 Component

  • 鍵入元件的名稱之後回車,會自動生成元件對應的 4 個檔案,字尾名分別為 .js、.json、.wxml 和 .wxss

1.2、參照元件

  • 區域性參照:元件只能在當前被參照的頁面內使用

  • 全域性參照:元件可以在每個小程式頁面中使用

1.3、區域性參照元件

在頁面的 .json 組態檔中參照元件的方式,叫做區域性參照。範例程式碼如下:

# 在頁面的 .json 檔案中,引入元件
{
  "usingComponents": {
    "my-test": "/components/test/test"
  }
}
# 在頁面的 .wxml 檔案中,使用元件
<my-test></my-test>
登入後複製

1.4、全域性參照元件

在 app.json 全域性組態檔中參照元件的方式,叫做全域性參照。範例程式碼如下:

# 在 app.json 檔案中,引入元件
{
  "usingComponents": {
    "my-test": "/components/test/test"
  }
}
登入後複製

1.5、全域性參照 VS 區域性參照

根據元件的使用頻率和範圍,來選擇合適的參照方式:

  • 如果某元件在多個頁面中經常被用到,建議進行全域性參照

  • 使用某元件只在特定的頁面中被用到,建議進行區域性參照

1.6、元件和頁面的區別

從表面來看,元件和頁面都是由 .js、.json、.wxml 和 .wxss 這四個檔案組成的。但是,元件和頁面的 .js 與 .json 檔案有明顯的不同:

  • 元件的 .json 檔案中需要宣告 "component": true 屬性

  • 元件的 .js 檔案中呼叫的是 Component() 函數

  • 元件的事件處理常式需要定義到 methods 節點中

2、樣式隔離

2.1、元件樣式隔離

預設情況下,自定義元件的樣式只對當前元件生效,不會影響到元件之外的 UI 結構。

防止外界的樣式影響元件內部的樣式

防止元件的樣式破壞外界的樣式

2.2、元件樣式隔離的注意點

app.wxss 中的全域性樣式對元件無效

只有 class 選擇器會有樣式隔離效果,id 選擇器、屬性選擇器、標籤選擇器不受樣式隔離影響

在元件和參照元件的頁面中建議使用 class 選擇器,不要使用 id、屬性、標籤選擇器

2.3、修改元件的樣式隔離選項

預設情況下,自定義元件的樣式隔離特效能夠防止元件內外樣式互相干擾的問題。但有時,我們希望在外界能夠控制元件內部的樣式。此時,可以通過 stylelsolation 修改元件的樣式隔離選項,用法如下:

# 在元件的 .js 檔案中新增如下設定
Component({
  options: {
    stylelsolation: 'isolated'
  }
})
# 或在元件的 .json 檔案中新增如下設定
{
  "stylelsolation": "isolated"
}
登入後複製

2.4、stylelsolation 的可選值

| 可選值 | 預設值 | 描述 |

| :----------: | :----: | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |

| isolated | 是 | 表示啟用樣式隔離 | 表示啟用樣式隔離,在自定義元件內外,使用 class 指定的樣式將不會互相影響 |

| apply-shared | 否 | 表示頁面 wxss 樣式將影響到自定義元件,但自定義元件 wxss 中指定的樣式不會影響頁面 |

| shared | 否 | 表示頁面 wxss 樣式將影響到自定義元件,自定義元件 wxss 中指定的樣式也會影響頁面和其他設定了 apply-shared 或 shared 的自定義元件 |

3、資料、方法和屬性

3.1、data 資料

在小程式元件中,用於元件模板渲染和私有資料,需要定義到 data 節點中,範例如下:

Component({
  <!-- 元件的初始資料 -->
  data: {
    count: 0
  }
})
登入後複製

3.2、methods 資料

在小程式元件中,事件處理常式和自定義方法需要定義到 methods 節點中,範例程式碼如下:

Component({
   <!-- 元件的方法列表 -->
  methods: {
    <!-- 事件處理常式 -->
    addCount() {
      this.setData({count: this.data.count + 1});
      <!-- 通過 this 直接呼叫自定義方法 -->
      this._showCount()
    },
    <!-- 自定義方法建議以 _ 開頭 -->
    _showCount() {
      wx.showToast({
        title: 'count值為:' + this.data.count,
        icon: 'none'
      })
    }
  }
})
登入後複製

3.3、properties 屬性

在小程式元件中,properties 是元件的對外屬性,用來接收外界傳遞到元件中的資料,範例程式碼如下:

Component({
  <!-- 屬性定義 -->
  properties: {
    <!-- 完整定義屬性的方式 -->
    max: {
      type: Number,
      value: 10
    },
    <!-- 簡化定義屬性的方式 -->
    max: Number
  }
})
登入後複製

3.4、data 和 properties 的區別

在小程式的元件中,properties 屬性和 data 資料的用法相同,它們都是可讀可寫的,只不過:

  • data 更傾向於儲存元件的私有資料

  • properties 更傾向於儲存外界傳遞到元件中的資料

Component({
  methods: {
    showInfo() {
      <!-- 結果為 true,證明 data 資料和 properties 屬性本質上是一樣的,都是可讀可寫的 -->
      console.log(this.data === this.properties)
    }
  }
})
登入後複製

3.5、使用 setData 修改 properties 的值

由於 data 資料和 properties 屬性在本質上沒有任何區別,因此 properties 屬性的值也可以用於頁面渲染,或使用 setData 為 properties 中的屬性重新賦值,範例程式碼如下:

# 在組建的 .wxml 檔案中使用 properties 屬性的值
<view>max屬性的值為:{{max}}</view>
Component({
  properties: { max: Number },
  methods: {
    addCount() {
      this.setData({ max: this.properties.max + 1 })
    }
  }
})
登入後複製

4、資料監聽器

4.1、什麼是資料監聽器

資料監聽器用於監聽和響應任何屬性和資料欄位的變化,從而執行特定的操作。它的作用類似於 vue 中的 watch 偵聽器。在小程式元件中,資料監聽器的基本語法格式如下:

Component({
  observers: {
    '欄位A, 欄位B': function(欄位A的心智, 欄位B的新值) {
    }
  }
})
登入後複製

4.2、資料監聽器的基本用法

Component({
  data: { n1: 0, n2: 0, sum: 0 },
  methods: {
    addN1() { sthis.setData({ n1: this.data.n1 + 1 })},
    addN2() { sthis.setData({ n2: this.data.n2 + 1 })}
  },
  observers: {
    'n1, n2': function(n1, n2) {
      this.setData({sum: n1 + n2})
    }
  }
})
登入後複製

4.3、監聽物件屬性的變化

# 資料監聽器支援監聽物件中單個或多個屬性的變化,範例程式碼如下:
Component({
  observers: {
    '物件.屬性A, 物件.屬性B': function(屬性A的新值, 屬性B的心智){}
  }
})
# 監聽物件中所有屬性的變化
Component({
  observers: {
    'obj.**': function(obj){}
  }
})
登入後複製

5、純資料欄位

5.1、什麼是純資料欄位

純資料欄位指的是那些不用於介面渲染的 data 欄位。

應用場景:例如有些情況下,某些 data 中的欄位既不會展示在介面上,也不會傳遞給其他元件,僅僅在當前元件內部使用。帶有這種特性的 data 欄位適合備設定為儲資料欄位

好處:純資料欄位有助於提升頁面更新的效能

5.2、使用規則

在 Component 構造器的 options 節點中,指定 pureDataPattern 為一個正規表示式,欄位名符合這個正規表示式的欄位將成為純資料欄位,範例程式碼如下:

Component({
  options: {
    <!-- 指定所有 _ 開頭的資料欄位為純資料欄位 -->
    pureDataPattern: /^_/
  },
  data: {
    a: true, // 普通資料欄位
    _b: true // 純資料欄位
  }
})
登入後複製

6、元件的生命週期

6.1、元件的全部生命週期函數

01.png

6.2、元件主要的生命週期函數

在小程式元件中,最重要的生命週期函數有 3 個,分別是 created、attached、detached。它們各自的特點如下:

  • 元件範例剛被建立好的時候,created 生命週期函數會被觸發

此時還不能呼叫 setData

通常在這個生命週期函數中,只應該用於給元件的 this 新增一些自定義的屬性欄位

  • 在組建完全初始化完畢、進入頁面節點樹後,attached 生命週期函數會被觸發

此時,this.data 已被初始化完畢

這個生命週期很有用,絕大多數初始化的工作可以在這個時機進行

  • 元件離開頁面節點樹後,detached 生命週期函數會被觸發

退出一個頁面時,會觸發頁面內每個自定義元件的 detached 生命週期函數

此時適合做一些清理性質的工作

6.3、lifetimes 節點

在小程式元件中,生命週期函數可以直接定義在 Component 構造器的第一級引數中,可以在 lifetimes 欄位內進行宣告(這是推薦的方式,其優先順序最高)。範例程式碼如下:

Component({
  <!-- 推薦用法 -->
  lifetimes: {
    attached() {}, // 在元件範例進入頁面節點樹時執行
    detached() {}, // 在元件範例被從頁面節點樹移除時執行
  },
  <!-- 以下是舊的定義方式 -->
  attached() {}, // 在元件範例進入頁面節點樹時執行
  detached() {}, // 在元件範例被從頁面節點樹移除時執行
})
登入後複製

6.4、什麼是元件所在頁面的生命週期

有時,自定義元件的行為依賴於頁面狀態的變化,此時就需要用到元件所在頁面的生命週期

02.png

6.5、pageLifetimes 節點

# 元件所在頁面的生命週期函數,需要定義在 pageLifetimes 節點中
Component({
  pageLifetimes: {
    show: function() {}, // 頁面被展示
    hide: function() {}, // 頁面被隱藏
    resize: function(size) {} // 頁面尺寸變化
  }
})
登入後複製

7、插槽

7.1、什麼是插槽

在自定義元件的 wxml 結構中,可以提供一個 slot 節點(插槽),用於承載元件使用者提供的 wxml 結構。

7.2、單個插槽

在小程式中,預設每個自定義元件中只允許使用一個 slot 進行佔位,這種個數上限制叫做單個插槽

<!-- 元件的封裝者 -->
<view class="wrapper">
  <view>這裡是元件的內部節點</view>
  <!-- 對於不準確的內容,可以使用 slot 進行展位 -->
  <slot></slot>
</view>
<!-- 元件的使用者 -->
<component>
  <view>這裡是插入到元件slot中的內容</view>
</component>
登入後複製

7.3、啟用多個插槽

在小程式的自定義元件中,需要使用多個 slot 插槽是,可以在元件的 .js 檔案中,通過如下方式進行啟用,範例程式碼如下:

Component({
  options: {
    multipleSlots: true // 在元件定義時,啟用多個 slot 支援
  }
})
登入後複製

7.4、定義多個插槽

可以在元件的 .wxml 中使用多個 slot 標籤,以不同的 name 來區分不同的插槽。範例程式碼如下:

<!-- 元件模板 -->
<view class="wrapper">
  <!-- name 為 before 的第一個 slot 插槽 -->
  <slot name="before"></slot>
  <view>這是一段固定的文字內容</view>
  <!-- name 為 after 的第二個 slot 插槽 -->
  <slot name="after"></slot>
</view>
登入後複製

7.5、使用多個插槽

在使用帶有多個插槽的自定義元件時,需要用 slot 屬性來將節點插入到不同的 slot 中。範例程式碼如下:

<!-- 參照元件的頁面模板 -->
<component>
  <!-- 這部分內容將被放置在元件 <slot name="before"></slot> 的位置上 -->
  <view slot="before">這裡是插入到元件 slot name="before"中的內容</view>
  <!-- 這部分內容將被放置在元件 <slot name="after"></slot> 的位置上 -->
  <view slot="after">這裡是插入到元件 slot name="after"中的內容</view>
</component>
登入後複製

8、父子元件之間的通訊

8.1、父子元件之間的通訊的 3 種方式

屬性繫結

用於父元件向子元件的指定屬性設定資料,僅能設定 JSON 相容的資料

事件繫結

用於子元件向父元件傳遞資料,可以傳遞任意資料

獲取元件範例

父元件還可以通過 this.selectComponent() 獲取子元件範例物件

這樣舊可以直接存取子元件的任意資料和方法

8.2、屬性繫結

屬性繫結用於實現父向子傳值,而且只能傳遞普通型別的資料,無法將方法傳遞給子元件。父元件的範例程式碼如下:

<!-- 父元件的 data 節點 -->
data: {
  count: 0
}
<!-- 父元件的 wxml 結構 -->
<my-child count="{{count}}"></my-child>
登入後複製
<!-- 子元件的 properties 節點 -->
properties: {
  count: Number
}
<!-- 子元件的 wxml -->
<view>子元件種,count值為:{{count}}</view>
登入後複製

8.3、事件繫結

事件繫結用於實現子向父傳值,可以傳遞任何型別的資料。使用步驟如下:

在父元件的 js 中,定義一個函數,這個函數即將通過自定義事件的形式,傳遞給子元件

<!-- 在父元件定義 syncCount 方法,將來傳遞給子元件,供子元件進行呼叫 -->
syncCount() {
  console.log('syncCount')
}
登入後複製

在父元件的 wxml 中,通過自定義事件的形式,將步驟 1 中定義的函數參照,傳遞給子元件

<!-- 使用bind:自定義事件名稱(推薦:結構清晰) -->
<my-test count="{{count}}" bind:sync="syncCount"></my-test>
<!-- 使用bind後面直接協商自定義事件名稱-->
<my-test count="{{count}}" bindsync="syncCount"></my-test>
登入後複製

在子元件的 js 中,通過呼叫 this.triggerEvent('自定義事件名稱',{引數物件}),將資料傳送到父元件

<!-- 子元件的 wxml 結構 -->
<text>子元件中,count:{{count}}</text>
<button type="primary" bindtap="addCount">+1</button>
# 子元件的 js 程式碼
methods: {
  addCount() {
    this.setData({
      count: this.properties.count + 1
    })
    this.triggerEvent('sync', { value: this.properties.count })
  }
}
登入後複製

在父元件的 js 中,通過 e.detail 獲取到子元件傳遞過來的資料

syncCount(e) {
  this.setData({
    count: e.detail.value
  })
}
登入後複製

8.4、獲取元件範例

可在父元件裡呼叫 this.selectComponent('id 或 class 選擇器'),獲取子元件的範例物件,從而直接存取子元件的任意資料和方法。

<my-component count="{{count}}" bind:sync="syncCount" class="test" id="test"></my-component>
<button bindtap="getChild">獲取子元件範例</button>
<!-- 按鈕的 tap 事件處理常式 -->
getChild() {
  <!-- 可以傳遞 id選擇器,也可以傳遞 class 選擇器 -->
  const child = this.selectComponent('.test')
  <!-- 呼叫子元件的 setData 方法 -->
  child.setData({ count: child.properties.count + 1 })
  <!-- 呼叫子元件的 addCount 方法 -->
  child.addCount()
}
登入後複製

9、behaviors

9.1、什麼是 behaviors

behaviors 是小程式中,用於實現元件間程式碼共用的特性,類似於 Vue.js 中的 mixins

9.2、behaviors 的工作方式

每個 behavior 可以包含一組屬性、資料、生命週期函數和方法。元件參照它時,它的屬性、屬性和方法會被合併到元件中。

每個元件可以參照多個 behavior,behavior 也可以參照其它 behavior

9.3、建立 behavior

呼叫 Behavior(Object object) 方法即可建立一個共用的 behavior 範例物件,供所有的元件使用

# 呼叫 Behavior() 方法,建立範例物件
# 並使用 module.exports 將 behavior 範例物件共用出去
module.exports = Behavior({
  # 屬性節點
  properties: {},
  # 私有資料節點
  data: {},
  # 事件處理常式和自定義方法節點
  methods: {}
})
登入後複製

9.4、匯入並使用 behavior

在元件中,使用 require() 方法匯入需要的 behavior,掛載後即可存取 behavior 中的資料或方法,範例程式碼如下:

# 使用 require() 匯入需要自定義 behavior 模組
const myBehavior = require('my-behavior')
Component({
  <!-- 將匯入的 behavior 範例物件,掛載到 behaviors 陣列節點中即可生效 -->
  behaviors: [myBehavior]
})
登入後複製

9.5、behavior 中所有可用的節點

03.png

10、使用 npm 包

10.1、小程式對 npm 的支援與限制

目前,小程式已經支援使用 npm 安裝第三方包,從而來提高小程式的開發效率。但是,在小程式中使用 npm 包有如下 3 個限制:

  • 不支援依賴於 Node.js 內建庫的包

  • 不支援依賴於瀏覽器內建物件的包

  • 不支援依賴於 C++ 外掛的包

10.2、API Promise 化

  • 基於回撥函數的非同步 API 的缺點

預設情況下,小程式官方提供的非同步 API 都是基於回撥函數實現的,例如,網路請求的 API 需要按照如下的方式呼叫:

wx.request({
  method: '',
  url: '',
  data: {},
  success: () => {}
})
登入後複製

缺點:容易造成回撥地獄的問題,程式碼的可讀性、維護性差

  • 什麼是 API Promise 化

API Promise 化,指定是通過額外的設定,將官方提供的、基於回撥函數的非同步 API,升級改造為基於 Promise 的非同步 API,從而提高程式碼的可讀性、維護性、避免回撥地獄的問題

  • 實現 API Promise 化

在小程式中,實現 API Promise 化主要依賴於 minprogram-api-promise 這個第三方的 npm 包。它的安裝和使用步驟如下:

npm install --save minprogram-api-promise
# 在小程式入口檔案中(app.js),只需要呼叫一次 promisifyAll() 方法
import { promisifyAll } from 'minprogram-api-promise'
const wxp = wx.p = {}
promisifyAll(wx, wxp)
登入後複製
  • 呼叫 Promise 化之後的非同步 API

# 頁面的 .wxml 結構
<button bindtap="getInfo">vant按鈕</button>
# 在頁面的 .js 檔案中,定義對應的 tap 事件處理常式
async getInfo() {
  const { data: res } = await wx.p.request({
    method: 'GET',
    url: '',
    data: {}
  })
}
登入後複製

11、全域性資料共用

11.1、什麼是全域性資料共用

全域性資料共用(又叫做:狀態管理)是為了解決元件之間資料共用的問題

開發中常用的資料共用方案有:Vuex、Redux、MobX 等

11.2、小程式中的全域性資料共用方案

在小程式中,可使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 實現全域性資料共用。其中:

  • mobx-miniprogram 用來建立 Store 範例物件

  • mobx-miniprogram-bindings 用來把 Store 中的共用資料或方法,繫結到元件或頁面中使用

安裝 MobX 相關的包

# 在專案執行如下的命令,安裝MobX相關的包
npm install --save mobx-miniprogram mobx-miniprogram-bindings
登入後複製

注意:MobX 相關的包安裝完畢之後,記得刪除 miniprogram_npm 目錄後,重新構建 npm

建立 MobX 的 Store 範例

import { observable, action } from 'mobx-miniprogram'
export const store = observable({
  // 資料欄位
  numA: 1,
  numB: 2,
  //計算屬性
  get sum() {
    return this.numA + this.numB
  },
  // actions 方法,用來修改 store 中的資料
  updateNumA: action(function(step) {
    this.numA += step
  }),
  updateNumB: action(function(step) {
    this.numB += step
  }),
})
登入後複製

將 Store 中的成員繫結到頁面中

# 頁面的 .js 檔案
import { createStoreBindings } from 'mobx-miniprogram-bindings'
import { store } from './store'
Page({
  onLoad() {
    this.storeBindings = createStoreBindings(this, {
      store,
      fields: ['numA', 'numB', 'sum'],
      actions: ['updateNumA']
    })
  },
  <!-- 生命週期函數--監聽頁面解除安裝 -->
  onUnload() {
    this.storeBindings.destroyBindings()
  }
})
登入後複製

在頁面上使用 Store 中的成員

# 頁面的 .wxml
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler" data-step="{{1}}">numA + 1</van-button>
<van-button type="primary" bindtap="btnHandler" data-step="{{-1}}">numA - 1</van-button>
<!-- 按鈕 tap 事件的處理常式 -->
btnHandler(e) {
  this.updateNumA(e.target.dataset.step)
}
登入後複製

將 Store 中的成員繫結到元件中

import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from './store'
Component({
  behaviors: [storeBindingsBehavior],
  storeBindings: {
    store,
    fields: {
      numA: () => store.numA,
      numB: (store) => store.numB,
      sum: 'sum'
    },
    actions: {
      updateNumA: 'updateNumA'
    }
  }
})
登入後複製

在元件中使用 Store 中的成員

# 元件的 .wxml 結構
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler" data-step="{{1}}">numA + 1</van-button>
<van-button type="primary" bindtap="btnHandler" data-step="{{-1}}">numA - 1</van-button>
<!-- 按鈕 tap 事件的處理常式 -->
btnHandler(e) {
  this.updateNumA(e.target.dataset.step)
}
登入後複製

【相關學習推薦:】

以上就是微信小程式基礎加強總結的詳細內容,更多請關注TW511.COM其它相關文章!