微信小程序開發(fā)——Vant組件 & 自定義組件

一、Vant Weapp 組件

Vant組件介紹和使用具體參考Vant Weapp官網(wǎng)

1、下載Vant Weapp

步驟(1)npm包初始化

初始化包,自動生成package.json文件。

npm init

步驟(2)通過 npm 安裝 Vant Weapp

npm i @vant/weapp -S --production

步驟(3)修改 app.json

將 app.json 中的 "style": "v2" 去除,小程序的新版基礎(chǔ)組件強(qiáng)行加上了許多樣式,難以覆蓋,不關(guān)閉將造成部分組件樣式混亂。

步驟(4)構(gòu)建 npm 包

在詳情-本地設(shè)置中勾選 使用 npm 模塊 選項,并點(diǎn)擊 工具 -> 構(gòu)建 npm,構(gòu)建完成后,即可引入組件。

構(gòu)建完成后,會自動生成miniprogram_npm文件夾,表示構(gòu)建完成。

2、引入組件

在.json文件中配置使用的組件,可以在全局中配置,也可以在單獨(dú)頁面中配置。
在app.json或index.json中引入某個組件。

  "usingComponents": {
    "van-field": "@vant/weapp/field/index"
  },

3、Field 輸入框組件

label:輸入框左側(cè)文本
value:當(dāng)前輸入的值
type:可設(shè)置為任意原生類型, 如 number idcard textarea digit
border:是否顯示內(nèi)邊框
readonly:是否只讀
title-width:標(biāo)題寬度
placeholder:輸入框為空時占位符
custom-style:自定義樣式
autosize:是否自適應(yīng)內(nèi)容高度,只對 textarea 有效,可傳入對象,如 { maxHeight: 100, minHeight: 50 },單位為px

<van-field label="分類:" title-width="100rpx" model:value="{{ section_name }}" placeholder="請輸入分類" border="{{ true }}" readonly bindtap="openpopup" />
<van-field label="答案:" title-width="100rpx" model:value="{{ answer }}" placeholder="請輸入答案" border="{{ true }}" type="textarea" autosize custom-style="height:160rpx" />

效果圖:

4、Button 按鈕組件

type:按鈕類型,支持default、primary、info、warning、danger五種類型,默認(rèn)為default。
size:按鈕尺寸,可選值為 normal、large、small、mini,默認(rèn)為normal。
color:按鈕顏色,支持傳入linear-gradient漸變色。
custom-style:自定義樣式
loading:是否顯示為加載狀態(tài)
loading-text:加載狀態(tài)提示文字
icon:左側(cè)圖標(biāo)名稱或圖片鏈接。可選值參考,支持Icon組件里的所有圖標(biāo),也可以傳入圖標(biāo) URL。
round:是否為圓形按鈕
square:是否為方形按鈕
disabled:是否禁用按鈕
事件bind:click 點(diǎn)擊按鈕,且按鈕狀態(tài)不為加載或禁用時觸發(fā)。使用bindclick 配合loading屬性使用,可以實(shí)現(xiàn)節(jié)流效果。

<van-button icon="plus" type="primary" size="small" bindclick="addSubject" loading="{{isLoading}}" custom-style="width:130rpx" color="#8fb2c9">添加</van-button>

效果圖:

5、Popup 彈出層組件

彈出層容器,用于展示彈窗、信息提示等內(nèi)容,支持多個彈出層疊加展示。
show:是否顯示彈出層
position:彈出位置,可選值為top、bottom、right、left。
custom-style:自定義彈出層樣式
事件bind:close 關(guān)閉彈出層時觸發(fā)

<van-popup show="{{ isShow }}" bind:close="closepopup" position="bottom">彈出內(nèi)容</van-popup>

效果圖:

6、Picker 選擇器組件

columns:對象數(shù)組,配置每一列顯示的數(shù)據(jù)
value-key:選項對象中,文字對應(yīng)的 key。
show-toolbar:是否顯示頂部欄
toolbar-position:頂部欄位置,可選值為bottom、top
title:頂部欄標(biāo)題
loading:是否顯示加載狀態(tài)
defaultIndex:初始選中項的索引,默認(rèn)為 0
item-height:選項高度
confirm-button-text:確認(rèn)按鈕文字
cancel-button-text:取消按鈕文字
事件bind:confirm 點(diǎn)擊確認(rèn)按鈕時觸發(fā)。
事件bind:cancel 點(diǎn)擊取消按鈕時觸發(fā)。
事件bind:change 選項改變時觸發(fā)。

注意:Picker選擇器組件必須配合Popup彈出層組件使用,不能單獨(dú)使用。

<van-popup show="{{ isShow }}" bind:close="closepopup" position="bottom">
    <van-picker show-toolbar columns="{{ columns }}" value-key="Name" bind:cancel="onCancel" bind:confirm="onConfirm" title="請選擇分類" defaultIndex="{{activeIndex}}"/>
</van-popup>
Page({
    data: {
        isLoading:false,
        isShow:false,
        activeIndex:0,
        columns: [
            { Name: '杭州' },
            { Name: '寧波' },
            { Name: '溫州' },
          ]
    }
})

效果圖:

7、CountDown 倒計時組件

time:倒計時時長,單位毫秒
format:時間格式,DD-日,HH-時,mm-分,ss-秒,SSS-毫秒,默認(rèn)為HH:mm:ss
auto-start:是否自動開始倒計時,默認(rèn)為true
use-slot:是否使用自定義樣式插槽,默認(rèn)為false
timeData 格式:days-剩余天數(shù);hours-剩余小時;minutes-剩余分鐘;seconds-剩余秒數(shù);milliseconds-剩余毫秒

<van-count-down use-slot time="{{ time }}" bind:change="onChange">
        <text class="limit">限購</text>
        <text class="red">1杯</text>
        <text class="item">{{ timeData.days }}</text>
        <text class="red">天</text>
        <text class="item">{{ timeData.hours }}</text>
        <text class="red">:</text>
        <text class="item">{{ timeData.minutes }}</text>
        <text class="red">:</text>
        <text class="item">{{ timeData.seconds }}</text>
</van-count-down>
Page({
    data: {
      time: 310 * 67 * 60 * 1000,
      timeData: {},
    },
    onChange(e) {
        let {detail:{days, hours, minutes,seconds}}=e
        this.setData({
          timeData: {
            days:wx.$formatNumber(days), 
            hours:wx.$formatNumber(hours), 
            minutes:wx.$formatNumber(minutes),
            seconds:wx.$formatNumber(seconds)
          }
        });
      },
  })

效果圖:

8、Grid 宮格組件

宮格可以在水平方向上把頁面分隔成等寬度的區(qū)塊,用于展示內(nèi)容或進(jìn)行頁面導(dǎo)航。
column-num:列數(shù)
gutter:格子之間的間距,默認(rèn)單位為px,默認(rèn)值為0
border:是否顯示邊框,默認(rèn)為true
center:是否將格子內(nèi)容居中顯示,默認(rèn)為true
square:是否將格子固定為正方形,默認(rèn)為false
direction:格子內(nèi)容排列的方向,可選值為 horizontal、vertical
use-slot:是否使用自定義內(nèi)容的插槽。自定義宮格的所有內(nèi)容,需要設(shè)置use-slot屬性。

      <van-grid column-num="3" class="goods" border="{{false}}" center="{{false}}">
          <van-grid-item use-slot wx:for="{{coffeedata}}" wx:key="index" class="griditem">
              <image src="{{item.coffeeimg}}" class="goodsimg"></image>
              <view class="goodstitle">{{item.coffeename}}</view>
              <view class="goodstitle">{{item.coffeeprice}}</view>
              <view class="price">
                  <view class="left">
                      <view class="daoshou">到手價<view class="sjx"></view>
                      </view>
                      <view class="money">{{item.coffeenowprice}}</view>
                  </view>
                  <view class="right">
                      <image src="/assets/img/cart.PNG"></image>
                  </view>
              </view>
          </van-grid-item>
      </van-grid>
Page({
    data: {
      coffeedata: [{
          coffeeimg: 'https://img2.baidu.com/it/u=49756185,3106025596&fm=26&fmt=auto',
          coffeename: '厚乳拿鐵',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        },
        {
          coffeeimg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp7.itc.cn%2Fimages01%2F20200729%2Ffd60a84256e5495aba620a0116346bdc.jpeg&refer=http%3A%2F%2Fp7.itc.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639123029&t=779c7275557e3ddcd867b6d909330b36',
          coffeename: '隕石拿鐵',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        },
        {
          coffeeimg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fci.xiaohongshu.com%2F1affff12-dc7f-4319-4180-55a193c443d3%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fci.xiaohongshu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639123114&t=15ec823e0e7d9478c3e4dfd5a51b9384',
          coffeename: '芋泥一起大紅袍',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }, {
          coffeeimg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg2.doubanio.com%2Fview%2Fgroup_topic%2Fl%2Fpublic%2Fp275163182.jpg&refer=http%3A%2F%2Fimg2.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639123140&t=262a7dc689229f9905cba8d0000d8b0e',
          coffeename: '抹茶瑞納冰',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }, {
          coffeeimg: 'https://img1.baidu.com/it/u=2792718596,1723163661&fm=26&fmt=auto',
          coffeename: '小鹿料多多',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }, {
          coffeeimg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fqcloud.dpfile.com%2Fpc%2FLIpUEFVtAGyPgWr-yqgeJQb7fTtvawZ5sAInNXNpiScGuEGVW4L3mx2SmXf5pwCL5g_3Oo7Z9EXqcoVvW9arsw.jpg&refer=http%3A%2F%2Fqcloud.dpfile.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639123277&t=f9835f88b99afd9014352799cf8c6dc3',
          coffeename: '沖繩黑糖拿鐵',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }, {
          coffeeimg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F10%2F04%2F2157f3b2880c792.jpg&refer=http%3A%2F%2Fbpic.588ku.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639123376&t=0c7120755f992fa26ddf398d3bd92ae1',
          coffeename: '摩卡',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }, {
          coffeeimg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fqcloud.dpfile.com%2Fpc%2F4zrG0tCu-if32NP4qPJ843CmN584sw6-jCZTOA6ZLg4HEjJJXBYQjVbJZhnXA8kE5g_3Oo7Z9EXqcoVvW9arsw.jpg&refer=http%3A%2F%2Fqcloud.dpfile.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639123407&t=d2530897a42d20199479f5ceeb6089ae',
          coffeename: '焦糖瑪奇朵',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }, {
          coffeeimg: 'https://img1.baidu.com/it/u=3530766208,3669403873&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
          coffeename: '小隕石厚乳',
          coffeeprice: '¥ 28',
          coffeenowprice: '¥9.9'
        }
      ]
    },
  })

效果圖:

二、自定義組件

1、介紹

開發(fā)者可以將頁面內(nèi)的功能模塊抽象成自定義組件,以便在不同的頁面中重復(fù)使用;也可以將復(fù)雜的頁面拆分成多個低耦合的模塊,有助于代碼維護(hù)。具體參考自定義組件官方文檔

2、實(shí)現(xiàn)自定義組件

步驟(1)新建存放組件的目錄

在項目中新建一個 components 文件夾,用于存放我們以后開發(fā)中的組件。

步驟(2)新建組件文件夾

以實(shí)現(xiàn)一個自定義tab菜單為例子,我們需要在components目錄下新建一個tabMenu文件夾來存放tab菜單組件。然后 右擊tabMenu下新建 Component 并命名為tabMenu。

tabMenu文件夾會生成對應(yīng)的js、json、wxml、wxss4個文件,也就是一個自定義組件的組成部分。

步驟(3)在tabMenu.wxml文件中編寫組件模版

<view class="tabMenu">
  <view class="label">{{label}}</view>
  <view class="item {{activeIndex===index?'active':''}}" bindtap="click" data-index="{{index}}"
  wx:for="{{list}}" wx:key="index">{{item}}</view>
</view>

步驟(4)在tabMenu.wxss文件中編寫組件樣式

.tabMenu {
    display: flex;
    align-items: center;
    margin: 10rpx 0;
}
.tabMenu .label{
    font-weight: bold;
}
.tabMenu .item{
    border: 2rpx solid #ccc;
    padding: 5rpx 10rpx;
    margin: 0 5rpx;
    color: #8fb2c9;
}
.tabMenu .item.active{
    background-color: #8fb2c9;
    color: white;
}

步驟(5)編寫tabMenu.js文件

js文件中,使用Component 構(gòu)造器定義組件,并提供組件的屬性、數(shù)據(jù)、方法等。組件的屬性值和內(nèi)部數(shù)據(jù)將被用于組件 wxml 的渲染。

properties:組件的屬性列表,用于定義組件需要傳遞的屬性。屬性設(shè)置中可包含三個字段,type表示屬性類型、value表示屬性初始值、observer表示屬性值被更改時的響應(yīng)函數(shù)。
data:組件的內(nèi)部數(shù)據(jù),和properties一同用于組件的模板渲染。
methods:組件的方法列表,包括事件響應(yīng)函數(shù)和任意的自定義方法。(在頁面js文件中定義方法不需要寫在methods中,注意區(qū)分。)
triggerEvent方法: 觸發(fā)一個自定義事件,將值通過事件對象的方式回傳出去。(因為組件內(nèi)部的值發(fā)生變化時,頁面內(nèi)部的數(shù)據(jù)并不會隨之改變。所以就需要通過觸發(fā)自定義事件,將值回傳出去)

Component({
  /**
   * 組件的屬性列表,定義組件需要傳遞的屬性
   */
  properties: {
    // 菜單標(biāo)題
    label:{              // 屬性名  
      type:String,       // 類型(必填),類型包括String、Number、Boolean、Object、Array、null(表示任意類型)
      value:''           // 默認(rèn)值,設(shè)置為空
    },
    // 菜單選項內(nèi)容
    list:{
      type:Array         // 類型是數(shù)組
    },
    // 高亮索引
    activeIndex:{
      type:Number,     // 類型是Number   
      value:0          // 默認(rèn)值是0
    }
  },
  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {    
  },
  /**
   * 組件的方法列表
   */
  methods: {
    // 選項點(diǎn)擊事件
    click(e) {
      let {index} = wx.$key(e)      // 獲取數(shù)據(jù)參數(shù)index
      this.setData({
        activeIndex: index        // 更新高亮索引
      })
      // 觸發(fā)一個自定義事件,將值通過事件對象的方式回傳出去
      this.triggerEvent('syncData',index)
    }
  }
})

步驟(6)頁面中引入tabMenu組件

引入組件有兩種方式:① 全局引入,在app.json文件中引入組件;② 局部引入,只在需要使用該組件的頁面json文件中引入。
我選擇了局部引入,在需要使用組件的shopcart頁面中引用。
引用格式:"組件名":"組件路徑"

shopcart.json文件:

{
  "usingComponents": {
    "tabMenu":"/components/tabMenu/tabMenu"
  }
}

shopcart.wxml文件:
注意:在組件中通過triggerEvent定義的觸發(fā)事件,在頁面中調(diào)用格式為bind:事件名=""。例如bind:syncData="syncData"。

<view class="shopcart">
    {{sugarActive}}--{{plActive}}--{{wdActive}}
    <!-- 使用組件時,傳遞list屬性、label屬性和activeIndex屬性 -->
    <tabMenu data-active="sugarActive" label="甜度:" list="{{sugars}}" activeIndex="{{sugarActive}}" bind:syncData="syncData"></tabMenu>
    <tabMenu data-active="plActive" label="配料:" list="{{pls}}" activeIndex="{{plActive}}" bind:syncData="syncData"></tabMenu>
    <tabMenu data-active="wdActive" label="溫度:" list="{{wds}}" activeIndex="{{wdActive}}" bind:syncData="syncData"></tabMenu>
</view>

shopcart.js文件:

Page({
  data: {
    // 定義一個甜度數(shù)組
    sugars: ['全糖', '半糖', '少糖', '無糖'],
    // 甜度高亮索引
    sugarActive: 0,
    // 定義一個配料數(shù)組
    pls: ['珍珠', '紅豆', '椰果', '布丁'],
    // 配料高亮索引
    plActive: 0,
    // 定義一個溫度數(shù)組
    wds: ['常溫', '多冰', '少冰', '去冰'],
    // 溫度高度索引
    wdActive: 0,
  },
 
  //同步組件回傳的數(shù)據(jù)
  syncData(e){
    //獲取data參數(shù)(獲取指定的active)
    let {active} = e.currentTarget.dataset
    //獲取組件內(nèi)部回傳的值
    let {detail} = e
    this.setData({
      //給指定的active重新賦值
      [active]:  detail
    })
  }
})

步驟(7)自定義tab菜單效果

3、slot插槽的使用

使用組件時,如果要顯示兩個組件標(biāo)簽中間的內(nèi)容,需要使用slot插槽。

(1)tabMenu.wxml文件

組件中的slot標(biāo)簽,用于定義插槽。使用組件時,兩個組件標(biāo)簽中間的內(nèi)容都會放到插槽中。

<view class="tabMenu">
    <view class="label">{{label}}</view>
    <view class="item {{activeIndex===index?'active':''}}" wx:for="{{list}}" wx:key="index" bindtap="click" data-index="{{index}}" >{{item}}</view>
    <slot></slot>
</view>

(2)shopcart.wxml文件

調(diào)用組件的頁面,在自定義組件標(biāo)簽中添加slot屬性,就可以使用插槽。

<tabMenu slot data-active="wdActive" label="溫度:" list="{{wds}}" activeIndex="{{wdActive}}" bind:syncData="syncData">
    插槽內(nèi)容
</tabMenu>

(3)頁面效果

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

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