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 listsblockThe 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

  1. 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
  1. Data Component data
  2. Internal methods start with _
  3. 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

  1. 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
  1. 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 componentreLaunch

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:

  1. Pages with tabbars are rewritten as components
  2. 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:

  1. Every Tabbar has the effect of a pull-down refresh, even if no pull-down refresh is required
  2. 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…

  1. Log in to iconfont. Cn to download the zip package
  2. Decompress the.ttf file into base64 format on transfonter.org/
  3. Write style.css to the newly created iconFont. WXSS, replacing the font file path with base64
  4. 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

  1. 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
  1. 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