一、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>