This is the first day of my participation in the First Challenge 2022
Hi I am xiao 17 _, happy New Year, today is the first day of the Chinese New Year, before the development of wechat small program encountered some problems, the solution to share with you ~
Please refer to our latest document small program ~ : developers.weixin.qq.com/ebook?actio…
For rendering listsblock
The parcel
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
Copy the code
Blocks are not actually rendered to the page, but are simply wrapped elements that accept control properties
Write a custom component
The custom component is divided into four parts
- Properties Properties received by the component
properties: {
// The default prompt for the input box
placeholder: {
type: String.// The type of the attribute value
value: ' ' // Attribute default value}},Copy the code
- Data Component data
- Internal methods start with _
- Component lifecycle functions, typically using Ready, are executed after the component layout is complete, at which point node information can be retrieved (using SelectorQuery)
Calls the method passed in by the parent component
/ / child component
var myEventDetail = {value: ' '}; The detail object, provided to the event listener function, writes the data that needs to be passed outside
var myEventOption = {} // The option to trigger the event
this.triggerEvent('onclear', myEventDetail, myEventOption)
Copy the code
<! -- Parent component -->
<searchbar id="search-bar" bind:onsearch="onSearch" bind:onclear="onSearch" placeholder="Search article content"></searchbar>
<! -- Bind custom functions like bindtap -->
Copy the code
/ / the parent component
onSearch(e){
console.log(e.detail.value)
}
Copy the code
The parent component directly calls the child component’s methods
// The parent component uses the selectComponent to get the instance of the child component and call its methods directly
let searchBar = this.selectComponent('#search-bar');
searchBar.setData({ value: e.currentTarget.dataset.name })
searchBar.onClickSearch({ detail: {value: e.currentTarget.dataset.name}});
Copy the code
Gets the DOM width and height in the child component
// Get the screen width
let windowWidth = wx.getSystemInfoSync().windowWidth
// We need to write this inside the component
let query = wx.createSelectorQuery().in(this);
let that = this;
query.selectAll('.tagItem').boundingClientRect()
query.exec(function (res) {
let allWidth = 0;
res[0].map(item= >{
allWidth = allWidth + item.width
return allWidth
})
let length = res[0].length
let ratioWidth = allWidth / windowWidth
that.setData({
allLength: length,
iphone: ratioWidth + (length == 1 ? 0 : res[0].length * 0.0533)})})Copy the code
OnLoad is not called when the page returns
In onLoad, I called the interface, went to the details page from the article list, and then clicked on the upper left corner of the details page to go back to the list page. The number of views on the list page should have been updated, but it was not updated because the article list interface was not reset.
So call the article list interface part of the onShow.
Custom Tabbar optimization
For the first optimization, change the tabbar wrapped in components to the template form of a page
- I used to write it as a component, but I changed it to template; Tabbar ICONS are changed to iconfont, which will flash when clicking tabbar
<template name="tabbar">
<view class="tabbar-wrapper">
<block wx:for="{{tabbar.list}}" wx:key="item">
<navigator hover-class="none" class="tabbar_nav {{item.selected ? 'selected':''}}" url="{{item.pagePath}}" style="color:{{item.selected ? tabbar.selectedColor : tabbar.color}}" open-type="reLaunch">
<view class="tab-item"><text class="{{item.iconPath}}" style="width: {{item.iconWidth}}; height: {{item.iconHeight}}"></text>{{item.text}}<text class='red-tag' wx:if="{{tabbar.num && index==1}}">{{tabbar.num > 99 ? '99+' : tabbar.num}}</text></view>
</navigator>
</block>
</view>
</template>
Copy the code
- When clicking tabbar, you need to destroy the previous page and jump to the page you want to jump to, so it is used in the Navigator component
reLaunch
For the second optimization, all pages with tabbar are packaged into components and written on the page, and setData switches TAB in the page
<homePage id="home-page" wx:if="{{tabbarID == tabbarList.home}}" bind:onclicktab="setTabbar" ></homePage>
<articleLibraryPage id="article-page" wx:if="{{tabbarID == tabbarList.article}}"></articleLibraryPage>
<doclistPage id="doctor-page" wx:if="{{tabbarID == tabbarList.doctor}}"></doclistPage>
<mePage id="me-page" wx:if="{{tabbarID == tabbarList.me}}"></mePage>
<tabbar id="tab-bar" bind:onclick="onClickTabbar" tabbarID="{{tabbarID}}"></tabbar>
Copy the code
Modifications:
- Pages with tabbars are rewritten as components
- OnShow, onReachBottom, and onPullDownRefresh from the previous page are all called in the parent page because the component only has the ready method after it has been mounted
onPullDownRefresh: function () {
if (this.data.tabbarID === this.data.tabbarList.article) {
// Use selectComponent to find the component instance and call the internal method
let articlePage = this.selectComponent('#article-page');
articlePage.onPullDownRefresh();
} else if (this.data.tabbarID === this.data.tabbarList.doctor){
let doctorPage = this.selectComponent('#doctor-page');
doctorPage.onPullDownRefresh();
} else{ wx.stopPullDownRefresh(); }},Copy the code
Problems:
- Every Tabbar has the effect of a pull-down refresh, even if no pull-down refresh is required
- Clicking a button from another page and jumping directly to a TAB card on the front page can be problematic
Using iconfont
www.jianshu.com/p/1cfc074ee…
- Log in to iconfont. Cn to download the zip package
- Decompress the.ttf file into base64 format on transfonter.org/
- Write style.css to the newly created iconFont. WXSS, replacing the font file path with base64
- Import iconfont. WXSS in app.wxss
Note: The styles in the component themselves are not affected by app. WXSS, so when you want to use iconfont in the component, you need to manually cite either app. WXSS or iconfont
The left slide effect of the list
- Binds events to the parent element of the list
<view
class="list-container"
wx:for="{{doctorList.list}}"
wx:key="{{index}}"
>
<view
bindtouchstart='onTouchStartListItem'
bindtouchmove='onTouchMoveListItem'
style="{{item.txtStyle}}"
>Sliding content</view>
<view class="backCover">Slide the button to display</view>
</view>
Copy the code
.list-container{
position: relative;
width:100%;
height: 224rpx;
overflow: hidden;
}
.list-item{
position: absolute;
left: 0;
z-index: 5;
transition: left 0.2 s ease-in-out;
background-color: #fff;
}
.backCover{
box-sizing: border-box;
width: 200rpx;
height: 218rpx;
position: absolute;
right: 0;
top: 0;
z-index: 4;
}
Copy the code
- Modify the left value of the list item by judging the sliding distance
onTouchStartListItem: function (e) {
// Is a single finger touch
if (e.touches.length === 1) {
// Record the X-axis position of the touch point from the edge of the screen
this.setData({
startX: e.touches[0].clientX,
})
}
},
onTouchMoveListItem: function (e) {
var that = this
if (e.touches.length == 1) {
var disX = that.data.startX - e.touches[0].clientX;
var deleteBtnWidth = that.data.deleteBtnWidth;
var txtStyle = "";
if (disX < deleteBtnWidth / 4) {
txtStyle = "left:0rpx";
} else {
txtStyle = "left:-" + deleteBtnWidth + "rpx";
}
var index = e.currentTarget.id
var list = that.data.doctorList.list
list[index].txtStyle = txtStyle;
that.setData({
doctorList: {
list: list,
total: that.data.doctorList.total
}
})
}
},
onTouchEndListItem: function (e) {
var that = this
if (e.changedTouches.length == 1) {
var endX = e.changedTouches[0].clientX;
var disX = that.data.startX - endX;
var deleteBtnWidth = that.data.deleteBtnWidth;
var txtStyle = disX > deleteBtnWidth / 2 ? "left:-" + deleteBtnWidth + "px" : "left:0px";
var index = e.currentTarget.id
var list = that.data.doctorList.list
list[index].txtStyle = txtStyle;
that.setData({
doctorList: {
list: list,
total: that.data.doctorList.total } }); }},Copy the code