將小程式玩出花

胖大人本胖發表於2020-02-07

子元件直接呼叫父元件方法

我們先寫一個header元件,元件左側為返回按鈕,中間為標題,正常情況左側按鈕被點選時應該返回上一級,但某些場景下,我們可能希望它不要返回上一級,而是跳轉到指定頁面。

需求有了,我們來梳理實現思路,父元件可以給子元件傳一個跳轉的方法,子元件返回按鈕被點選,我們先判斷父元件是否有傳進來返回方法,如果有直接呼叫父元件的方法,如果沒有直接返回上一級。

子元件

示例程式碼所以樣式就沒寫,樣式也不是重點

  • wxml
<view class="header">
	<view class="back" bindtap="handleBack">返回</view>
	<view class="content">
		<slot></slot>
	</view>
</view>
複製程式碼
  • js
Component({
  properties: {
    // 接收自定義返回函式,不限制型別,預設值undefined
    customBack: {
      type: null,
      value: undefined,
    }
  },
  methods: {
    // 返回
    handleBack() {
      const { customBack} = this.data;
      // 這裡其實也應該再加個判斷customBack是否是函式
      if (customBack) {
        customBack();
        return;
      }
      wx.navigateBack();
    },
  }
})

複製程式碼

父元件

json檔案引入也不寫了,這是基礎

  • wxml
<view class="page">
	<Header customBack="backFn">頁面標題</Header>
</view>
複製程式碼
  • js
Page({
  /**
   * 頁面的初始資料
   */
  data: {
    backFn() {
      console.log('這就是要給子元件傳的返回方法,這個方法必須得寫在data中,作為普通方法寫在data外面,經測試無法傳進子元件');
      wx.redirectTo({
      	url: '填寫你要跳轉的路徑,用哪個路由跳轉方法隨意,redirectTo是我隨便寫的'
      })
    },
  },
})

複製程式碼

將常規元件改造為通過JS呼叫

有沒有遇到過產品設計的提示框或者確認框,與小程式本身的不一樣得情況。

寫一個自定義提示元件,來通過js的來呼叫。

子元件

示例程式碼,無樣式

  • wxml: modal.wxml
<view class="container" wx:if="{{isShow}}">
	<view class="contant">
		<view class="title">{{title}}</view>
		<view class="text">{{content}}</view>
		<view class="btn" catchtap="hidden">我知道了</view>
	</view>
</view>
複製程式碼
  • js: modal.js
Component({
  data: {
    isShow: false, // 控制元件顯示,預設隱藏
    title: '', // 提示框的標題
    content: '', // 自定義提示內容
  },
  methods: {
    // 呼叫元件顯示 接收一個一個物件
    show({title = '溫馨提示',content = ''}) {
      this.setData({
        isShow: true,
        title,
        content
      })
    },
    // 元件隱藏
    hidden() {
      this.setData({
        isShow: false,
        title: '',
        content: '',
      })
    }
  }
})
// 對外提供個方法 第二個引數為當前頁面this
export const showModal = (options, self) => {
  const { id = '#modal' } = options; // 取元件id, 預設modal
  const ctx = self.selectComponent(id); // 拿元件例項
  ctx.show(options); // 呼叫元件方法 把資料傳進去
  return ctx; // 最後把元件例項返回,以方便頁面對元件做其他處理
}

複製程式碼

父元件

json引入元件就不寫了

  • wxml
<view class="page">
	<!-- 元件id很重要 -->
	<modal id="modal"></modal>
	<view class="btn" bindtap="handleBtnClick">彈出提示框</view>
</view>
複製程式碼
  • js
import {showModal} from 'modal.js';
Page({
  handleBtnClick() {
  	// 如果元件的id與預設id不同,就需要在傳個id進去
  	showModal({title: '提示', content: '您的操作很危險'}, this);
  }
})

複製程式碼

小程式的計算屬性observers

observers 是小程式自帶的資料監聽器,在某些場景下是可以做為計算屬性來使用的。小程式也提供了計算屬性的擴充套件包 ,但不在這塊講解範圍內。

在做表單提交的時候,我們經常需要在表單所有的必填項填完之後才允許使用者點選提交按鈕,在填完之前表單一直是禁用狀態,此時就可以使用observers

示例模擬程式碼

  • wxml
<view class="page">
	<view class="form">
		<view class="item">
			<view class="label">姓名:</view>
			<input data-key="name" bindinput='handleInput'/>
		</view>
		<view class="item">
			<view class="label">簡介:</view>
			<input data-key="description" bindinput='handleInput'/>
		</view>
		<button disabled="disabled">提交</button>
	</view>
</view>
複製程式碼
  • js

Component({
  data: {
  	name: '', // 姓名
  	description: '', // 簡介
  	disabled: true, // 是否禁用
  },
  observers: {
    // 監聽name和description的變化,接收變化後的值
    'name,description': function(name,description) {
      // 對其進行取反,name和description都填寫之後不禁用,否則禁用
      this.setData({disabled: !Boolean(name && description)});
    }
  },
  methods: {
    handleInput({detail: {value}, target: {dataset: {key}}}) {
      this.setData({
        [key]: value
      })
    }
  }
})

複製程式碼

通過Component()來定義頁面

像上個例子的observers 用來處理表單提交非常好用,但遺憾的是這個方法只能在元件中使用,不能再page中使用。而且小程式的自定義元件behaviors ,page中就不能使用,所以我們就想怎麼使用Component() 來構造頁面。幸好騰訊提供了使用Component() 構造頁面的方法,接下來我們就把上個例子改成用Component() 構造。

第一步

在頁面的頁面json 檔案中新增usingComponents 內容

{
  "usingComponents": {}
}
複製程式碼

第二步

普通頁面是page() 構造的,我們將page 改成component

// 將這裡改了,本應是page
Component({
  data: {
  	name: '', // 姓名
  	description: '', // 簡介
  	disabled: true, // 是否禁用
  },
  observers: {
    // 監聽name和description的變化,接收變化後的值
    'name,description': function(name,description) {
      // 對其進行取反,name和description都填寫之後不禁用,否則禁用
      this.setData({disabled: !Boolean(name && description)});
    }
  },
  methods: {
    handleInput({detail: {value}, target: {dataset: {key}}}) {
      this.setData({
        [key]: value
      })
    }
  }
})

複製程式碼

第三步

正常從其他頁面通過路徑傳過來的引數我們通過onLoad(options){} 來接收,通過component 構造的頁面接收引數就需要properties 來接收,例如:

訪問頁面 /pages/detail/index?id=123&type=2 ,對於引數我們就需要這麼接收

// 將這裡改了,本應是page
Component({
  properties: {
    id: Number,
    type: Number,
  },
})

複製程式碼

第四步

頁面的宣告週期在普通頁面是與data 平級的,在使用component 構造頁面後,頁面的生命週期 就需要寫在methods 中。

onLoad: function() {
      this.data.paramA // 頁面引數 paramA 的值
      this.data.paramB // 頁面引數 paramB 的值
    }
Component({
  properties: {
    id: Number,
    type: Number,
  },
  methods: {
    onLoad() {},
    onShow() {},
    // ...
  }
})
複製程式碼

小程式的抽象節點

相關文章