In recent months, due to the business needs of the company, I have been torturing small programs, from completely unfamiliar at the beginning to tortured by various pits at the back. It is time to write a summary, so as to avoid the next time I encounter a solution that cannot be found.
Configuration items app.json and page.json
app.json
First, you need to make sure that app.json is the global configuration of the applet and is placed in the root directory.
Some commonly used fields are as follows:
- Pages: this is used to set the path of the page, usually visit the page in the pages folder inside, and must be set up in the global configuration file path, or visit the complains to find the path, written in the book pages field is the first page of the front page of this small program (open small program to see the first page)
- Window: global style configuration
- Navigation bar related: you can configure the background color, title color and title content of the navigation bar.
- You can hide the navigation bar (set navigationStyle to custom, but note that the custom navigation bar still retains the upper right corner capsule, and there is no return key. If you want to implement the return function, you need to customize the return style and function), == This setting is not valid for the Web-view component ==
- The backgroundColor of the window, the backgroundColor (the part that is shown when the applet is pulled down), and the ios only support backgroundColorTop and backgroundColorBottom, the backgroundColor of the top and bottom Windows
- Pull-down loading style, black and white only (dark/Light)
- EnablePullDownRefresh: by default, pages of the applet do not have the drop-down refresh function. If this parameter is set to true in app.json, all pages take effect. If you only want to use drop-down refresh on a single page, you need to configure this in the corresponding page.json
- OnReachBottomDistance, distance from the bottom of the page when pull-up loading takes effect, default 50px
- Screen rotation, pageOrientation, not used yet, auto/portrait/landscape supported, default portrait portrait display,
- Tabbar: Sets the TAB bar
- Position: Supports top and bottom (usually using the bottom TAB bar), position (bottom/top)
- TAB list: text and corresponding path
- Minimum 2, maximum 5
- PagePath, pagePath (must be the path defined in pages)
- Text, the text on the TAB
- IconPath, image path, (size limit is 40KB, 81px by 81px is recommended, network images are not supported)
- SelectedIconPath, the image path when selected. Limit as above
- Style related: color font color, selectedColor selected text color, backgroundColor is TAB bar backgroundColor, borderStyle border color,
- Custom Specifies whether to customize. The default value is no. For details, see Customizing tabBar
- NetworkTimeout (Sets the timeout time for network requests)
- request
- connectSocket
- uploadFile
- downloadFile
- Debug: Displays Page registration, Page routing, data update, and event triggering information, facilitating debugging of the life cycle
- NavigateToMiniProgramAppIdList, jump to other small program, need in the app. The first statement in json
- UsingComponents: If you declare the component in app.json, you can use the custom component globally, without declaring it in the PAGE JSON
- Call button’s open-type attribute to invoke authorization. In fact, it can be implemented through plug-in function pages, such as authorization nickname and user information function pages
page.json
The style configuration of the page takes precedence over window in the global configuration.
- You can set the navigation bar background color, navigation bar title color, navigation bar title,
- You can hide the navigation bar. Custom navigation bar retains only the capsule button in the upper right corner
- The background color of the window, and the background color of the top and bottom Windows supported by ios
- BackgroundTextStyle, a dropdown loading style, supports only dark/Light
- EnablePullDownRefresh Enables pull-down refresh. This attribute controls whether only the current page can be refreshed
- OnReachBottomDistance, distance from the bottom of the page when pull-up loading takes effect, default 50px
- PageOrientation, screen rotation Settings
- DisableScroll: If the value is true, the page cannot scroll up and down. This is valid only in the page configuration, not in app.json
- DisableSwipeBack: disables the page right swipe gesture to return
- UsingComponents, which uses custom components, will return an error if the component is not declared in the JSON of the page
Sitemap. json file (for wechat index)
The default rule is all indexed by default:
{"action": "allow", "page": "*"}
Grammatical differences between
WXML files differ from HTML:
- No div, p, span, view instead of div, text instead of span
- Wx :if is used in the same way as v-if in vUE, but it is slightly different. Both tags and text are interpolated using double curly braces.
wx:for="{{array}}"
. - Conditional rendering has wx:if, wx:elif, wx:else.
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
- In particular, if you use Boolean values, do not write them in double quotation marks, but in double braces. Such as
<checkbox checked="{{false}}"> </checkbox>
- The list of rendering
wx:for="{{array}}"
, you can use item and index directly, or you can usewx:for-item="idx"
, andwx:for-item="itemName"
Respecify index and item keys,Spaces between curly braces and quotes will eventually be parsed as strings - One of the tags in the WXML file is a block, which is just a wrapper element that doesn’t do any rendering in the page and only accepts control attributes
- Wx: the key can only be a string or “*this”,
wx:key="*this"
Represents the item itself in the for loop, but ensures that the item itself is a unique string or number. An error is reported when the key is bound to an object
Problem thinking?
Wx: How should if and Hidden judge the use of the scene?
- Wx :if is lazy and only partially rendered when it is true. When wx:if’s conditional value is switched, the conditional block is destroyed or re-rendered on the switch.
- And the hidden is always rendered, it just controls show and hide
- So hidden is better if you need to switch frequently, and wx:if is better if conditions are unlikely to change at runtime
component
Based on the component
- Component common properties:
- id, class, style, hidden, data-, bind/catch*
- View container:
- Movable: movable-area, movable-view. The movable-View must be in the movable-area component and must be a direct child node
- Covering native components: cover-view and cover-image are mainly used to cover high-level native components such as Map, video, Canvas, camera, live-player, and live-pusher. Note that only a cover-view, cover-image, and button can be nested within a cover-view
- Scrollable view area: Scrollable view. For vertical scrolling, you need to set a fixed height for the scrollable view
- Slider view container: swiper, in which only swiper-Item components can be placed (often used in rotation diagrams)
- The view container, if you want to use the hover style, can specify the style class and the attributes related to the hover: hover-class, hover-stop-Propagation, hover-start-time, hover-stay-time
- Icon icon, in the small program can use some icon icon, you can set type, size, color, details view, small program icon component
- Progress bar, progress, normal progress bar including animation can use this component directly
- Rich text, rich-txt, (you can use this component to render HTML content, passing in HTML strings)
- Text, text, (If you need to display multiple Spaces, you can set the space property)
- Button, button, (Can be disabled by setting the disabled property to prevent multiple clicks from triggering events)
- Radio, radio-goup, checkbox, checkbox-group
- Rich text editor, editor
- Form, supports switch Input checkbox Slider radio picker submission
- Password displays the password type (you can control the text in the lower right corner of the keyboard by using the confirm-type property, including “Send”, “search”, “Next”, “Go”, and “done”). Note: Font family cannot be set for input, system font is used
- Scroll selector, picker, support ordinary, multi-column, time, date, province selector,
- The scroll selector embedded in the page, picker-view, picker-view-column
- Slider, which is like a progress bar but you can drag it
- Switch, the switch
- Multi-line input box, textarea
- Navigate, navigator (similar to a TAB, with navigate, redirect, switchTab, reLaunch, navigateBack, exit, etc.)
- System camera, camera, can be used to scan two-dimensional code
- (Note that using the video component in the list will cause the page of the small program to freeze or even crash. The solution in the current project is to replace the video component with the frame cut picture of the video uploaded by Ali Cloud, and the video will play only after clicking the picture. According to the online information, the SRC of the video is empty by default. Fixed bug with viode automatic download, using custom-cache=”{{false}}” can fix video cache stuck, but haven’t tried it yet)
- The official account focuses on the component, official-Account
- Web-view is a container for carrying web pages (it is suitable for embedding content of third-party websites, and it is necessary to configure business domain names on public platforms). It is recommended to add encodeURIComponent to avoid Chinese characters in links. The white screen may open in iOS
Limitations on native components
- Native components include:
- camera
- canvas
- Input (native component only in Focus)
- live-player
- live-pusher
- map
- textarea
- video
- Level: highest, no other component can be overlaid on the native component, no matter how much z-index is set
- Native components cannot be animated, fixed layouts cannot be set, and the display area of native components cannot be trimmed using Overflow: Hidden.
- The bind: eventName format cannot be used for event monitoring. Only bindeventName is supported. The catch and Capture event bindings are not supported
The event system
-
Event handler function. The parameter is event. The event contents include:
- type
- TimeStamp, the timeStamp at which the event was generated
- Target, the source component that triggers the event
- CurrentTarget, the current component of the event binding
- Detail, the data carried by the custom event
- Touches, an array of touches, each of which is a Touch object
- changedTouches
-
The dataset: In the target or currentTarget event object, can get some of the current custom data through the dataset, (in JS file using the event. The currentTarget. The dataset, the attribute of the dataset will automatically convert strings, Hyphen is converted to camel, and uppercase characters are automatically converted to lowercase.)
-
Mark, similar to dataset, (if there is a mark of the same name, the mark of the parent node will be overwritten by the quilt node)
-
Page user behavior:
- Refresh onPullDownRefresh
- Pull up to onReachBottom
- Page scroll onPageScroll
- The user forwards onShareAppMessage
Think about:
- What is the difference between a bind event and a catch event in a small program?
- Bind event binding does not prevent bubbling events from bubbling up,
- Catch event bindings prevent bubbling events from bubbling up
- What’s the difference between Target and currentTarget?
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
Copy the code
As in the example above, clicking on the Inner View triggers handleTap3 and bubbles to handleTap2. For handleTap2, the target of the received event object is the inner element, and currentTarget is the middle part
- What’s the difference between Mark and dataset?
- Mark contains all mark: property values from the node that triggered the event to the root node;
- The dataset contains only the data-attribute value of one node
- The mark of the node does not do hyphen and case conversion
Applets – related mechanisms
- The logical layer of the applets framework does not run in the browser, so JavaScript in the Web some capabilities are not available, such as Window, document and so on
Running mechanism of applets: cold start and hot start
- Cold start: open the small program for the first time; Or small program destroyed after open. (Cold launch triggers the onLaunch lifecycle function in app.js)
- Hot launch: click on the upper right corner of the capsule to exit, or the home button to leave wechat, or slide back to wechat and other actions, are hot start, without destroying the small program (so hot launch will not trigger onLaunch function, but will trigger onShow function).
Start the scene
- Applet startup scenarios fall into two categories:
- From the discovery bar, another small program return, wechat pay, home page drop-down small program bar and so on are scenario A
- Scenario B: Open a specific page, such as forwarding a shared card link
- Hot start scene effect:
- If both the re-entry scenario and exit scenario are scenario A, retain the original status. For example: stay in the “personal center” Page, after exit, the small program list on the home Page will still stay in the “personal center” Page after entering, (trigger the “personal center” Page onShow function, but not trigger the onLoad function)
- If the current is scene A and the previous one is scene B, clear the original page stack and open the home page (i.e. perform wx.reLaunch to the home page). If the shared card is the page of “Student List”, click the card to stay and exit, and then enter the small program from the home page, then jump to the home page
- No matter what the previous scene is, if the current scene is B, such as clicking the sharing card of the small program, the original page stack will be cleared and the sharing page will be re-entered. The onShow function in the app will be triggered first, and then the onLoad function of the sharing page will be triggered. Of course, if the app has already jumped to other pages, Will not go to the share page.
- Cold start scene effect:
- The cold startup rule is simple. If scenario A is used for cold startup, the home page of the mini program is displayed
- If scenario B is displayed during cold startup, the corresponding page is displayed
Update mechanism
- The small program will first have a latest version in the background, generally speaking, it will send the new version information to the user within 24 hours, silently updated to the new version (at this time the user is not aware of the state).
- If the background version has not been updated in time, each cold boot will detect whether there is an updated version. If there is, it will asynchronously download and start the current old version package at the same time, so the new version will be applied only after the next cold boot
- If you want to get the latest version immediately upon startup, you need to use the Wx. getUpdateManager API and use wx.showModal to prompt the user whether to restart the application for update
ES6 support:
- Wechat applet already supports most OF the ES6 apis, but some apis are still not supported depending on the system version
- String normalize is not supported in ios9
- Array values are not supported in ios8 and android
- Array includes is not supported in ios8
- Proxy does not support ios8, ios9, and Android
Register applet
- App.js registered small program, the entire small program only one APP instance, is shared by all pages.
- Developers can use the getApp method to get globally unique App samples, get data on the App, or call functions that the developer has registered with the App
- In app.js you can assign this. GlobalData directly, but on other pages you need to get the instance through the getApp() method to use globalData
App({
onLaunch: function(options) {},
onShow: function(options) {},
onHide: function() {},
onError: function(msg) {},
globalData: 'I am global data'
})
Copy the code
Registration page and custom components
page
- Data is the initial data used for the first rendering of the page
- Triggered when the onLoad page loads. A page is called only once;
- OnShow is triggered when the page is displayed/cut to the foreground
- OnPageScroll, listen for the user to slide the page event, (please avoid in onPageScroll too often perform setData and other logical layer – rendering layer communication operations. In particular, a large amount of data is transmitted each time, which will affect the communication time.)
- Button component open-type=”share” and the upper right corner forwarding function (only if onShareAppMessage is defined in the Page, the upper right corner forwarding function will appear)
- SetData:
- Send data from the logical layer to the view layer (asynchronously) while changing the corresponding value of this.data (synchronous) (similar but different to react setState)
- Modifying this.data directly without calling this.setData will not change the state of the page and will cause data inconsistencies
- Do not set the value of any item in data to undefined
- If you need to process an event after the view layer has been updated, you can put the event in the setData callback function
Page constructor:
Page({
data: { text: "This is page data." },
onLoad: function(options) { },
onReady: function() { },
onShow: function() { },
onHide: function() { },
onUnload: function() { },
onPullDownRefresh: function() { },
onReachBottom: function() { },
onShareAppMessage: function () { },
onPageScroll: function() {}})Copy the code
Custom Components
- Pages that use custom components need to declare the usingComponents definition section in the PAGE’S JSON file
- When a component uses a page’s lifecycle method (that is, a method starting with ON), it should be in the Methods definition section
- Behaviors extracts code segments common to all pages. For example, if the same code is executed when all pages are created and destroyed, that code can be extracted into the behaviors
// page-common-behavior.js
module.exports = Behavior({
attached: function() {// Execute console.info() for page creation'Page loaded! ')
},
detached: functionConsole.info () {// Execute console.info('Page unloaded! '} // A var pageCommonBehavior = require('./page-common-behavior') Component({ behaviors: [pageCommonBehavior], data: { /* ... */ }, methods: { /* ... */ var pageCommonBehavior = require('./page-common-behavior') Component({ behaviors: [pageCommonBehavior], data: { /* ... */ }, methods: { /* ... * /}})Copy the code
- In the properties definition section, the propertyName is propertyName. In WXML, attribute values are specified using a hyphen (component-tag-name property-name=”attr value”) and applied to data binding using a hump (attr=””)
- Observers, similar to Watch in Vue, see Data Listeners
- Created, the component instance is just created (note that setData cannot be called at this time)
- DefinitionFilter, defines segment filters for custom component extensions (such as extending custom components with a computed property function)
Note:
- Use this.data to get internal data and attribute values; However, modifying it directly does not apply the changes to the interface. Instead, use setData
- Lifecycle functions are not accessible through this in component methods
Communication and events between components
- Parent to Child: parent component binding property value, child component through properties,
- Child component passes data to parent: use event passing
- Parent accessing child components: The parent can get the child component instance object through the this.selectComponent method, so that it can directly access any data and methods of the component
Here’s a second way to customize event passing data:
<component-tag-name bindmyevent= <component-tag-name bindmyevent="onMyEvent"/> // 2. The child component fires the WXML onMyEvent event. The parent component <! --> <button bindtap="onTap"> Clicking this button will trigger the "myevent" event </button> <! Component({properties: {}, methods: {onTap:function(){var myEventDetail = {} // detail object, provided to the event listener function var myEventOption = {} // the option to trigger the event this.triggerEvent()'myevent', myEventDetail, myEventOption)
}
}
})
Copy the code
For details, see inter-component Communication and Events
Note:
- Components and pages referencing components cannot use id selectors (#a), attribute selectors ([a]), and tag name selectors. Instead, use the class selector
- Avoid descendant selectors (.a.b)
- The child element selector (.a>.b) can only be used between a View component and its child nodes in cases where other components may cause unexpected consequences
- The styles in app.wxSS and the styles on the page where the component is located are not valid for custom components (except for inherited styles, such as font and color, which are inherited from the component)
Intercomponent relationship
Scenario: If A page needs to use component A and component B, and component A needs to communicate with component B, you can add the relations section to the component definition. For example, encapsulated UL and LI components need to have an associated parent-child relationship
- The relations definition must be included in both component definitions, otherwise it will not take effect
- Type: relative to the target component. Possible values are parent, child, ancestor, or descendant
- The other case is to associate a class of components (such as the relationship between form and input, checkbox, and so on) with behavior
For details, see Relationship between Components
Considerations for using setData:
- Do not frequently go to setData, otherwise it may cause Android users to feel stuck when sliding, or render delay
- Don’t pass a lot of new data every time you setData
- Don’t do setData in the background,
Applets run the flow
- Before opening the mini program, wechat will download the entire small program code package to the local
- The pages field in app.json lets you know all the page paths of your current applet
- The first page written in the Pages field is the home page of the mini program (the first page you see when you open the mini program), so wechat loads the home page code in
- The onShow function will be triggered when the app instance defined by app.js is launched, or the onShow function will be triggered when the foreground is cut and the page is returned from other pages. OnHide monitor small program cut background, (such as TAB switch, navigateTo, leave wechat, etc.); The onPageNotFound page does not have a listener
- The page rendering process starts. The wechat client will first generate an interface according to the JSON file configuration of the page.
- Then load the WXML structure and WXSS style for the page
- Finally, the client loads the PAGE JS file
- The Page constructor generates a Page, and as the Page is generated, the applet framework renders the data and index.wxml together to render the final structure and render the interface
- After rendering the interface, the page instance receives an onLoad callback
Life cycle function
There are three life cycles in the applet: the life cycle of the applet (handled in app.js), the life cycle of the page (handled in the PAGE’s JS file, or the life cycle function triggered by the component’s pageLifetimes), and the life cycle of the component
Applets life cycle function
- OnLaunch, triggered when applets initialization is complete, globally only triggered once
- OnShow, triggered when the small program starts, or enters the foreground display from the background
- OnHide, triggered when entering the background from the foreground
- OnError, triggered when a script error or API call error occurs in a small program
- OnPageNotFound, triggered when the page the applet wants to open does not exist
OnLaunch onShow parameters:
- Path: opens the page path of the applet
- Query: Opens the page parameter query of the applet
- Scene: The value of opening the applet.
- ShareTicket: indicates the forwarding share parameter
- ReferrerInfo: Return this field when the scene is opened from another applet or public number or App
- Referrerinfo. appId: appId of the source applets or public accounts or apps
- Referrerinfo. extraData: Data passed from the source applets, scene=1037 or 1038 support
Page life cycle function
- OnLoad, listening for page loading
- OnShow, monitor page display (such as TAB switch or leave wechat, or navigateTo)
- OnReady: listens for the first rendering of the page (a page is called only once, indicating that the page is ready)
- NavigateTo or the bottom TAB to switch to another page, small program into the background, etc.
- OnUnload, listening for page unloads (such as wx.redirectTo or wx.navigateBack to another page)
Component lifecycle functions
- Created is executed when the component instance has just been created. Note that setData cannot be called at this time
- Attached, executed when the component instance enters the page node tree
- Ready, executed after the component layout is complete
- Moved, executed when the component instance is moved to another location in the node tree
- Detached, executed when a component instance is removed from the page node tree
Note:
A component has a life cycle of the page on which the component resides, defined in pageLifetimes, where the available life cycles include:
- Show, executed when the page on which the component is located is displayed
- Hide, executed when the page on which the component is located is hidden
- Resize, executed when the page size of the component changes
network
- Server domain name configuration, when using the experience version or development version of the “server” error, most likely because debugging is not enabled, because in debug mode, the small program will not verify the validity of the domain name.
- Applet can only communicate with the specified domain name and network, including ordinary HTTPS request (wx.request), uploadFile (wx.uploadfile), downloadFile (wx.downloadfile) and WebSocket (wx.connectsocket).
- To access third-party web pages and use the Web-view component, you need to configure the service domain name
- The default timeout period is 60s. The timeout period can be configured using NetworkTimeout in app.json or game.json
- The maximum number of concurrent requests for wx.request, wx.uploadFile, and wx.downloadFile is 10. The maximum concurrency limit for wx.connectsockt is 5
- Return status, as long as the server returns are successfully received, regardless of the statusCode, the SUCCESS callback is entered
Custom tabBar
You can customize a tabBar by setting the tabBar TAB in app.json to a custom field of True.
- TabBar configuration items still need to be fully declared to be compatible with older versions and to distinguish between TAB pages
- A custom component is required to render the tabBar. The cover-view + Cover -image component with fixed at the bottom is recommended to keep the tabBar hierarchy relatively high
- Interfaces associated with tabBar styles, such as wx.settabBarItem, are disabled
- You can get a custom tabBar component instance of the current page under custom components through the getTabBar interface
Applets login process
Small program login needs to call the open interface of wechat, and the overall process is as follows:
- The applet gets a code from wx.login()
- Call the API of the backend, send the code with which the backend validates the interface, and return a custom login state
- The applet saves the login state to storage
- After accessing the server to send the service request, only the back end determines the login state query openID and session_key to return the service data
Applets optimize operations
- Shorten the white screen time:
- There is a large amount of content to be rendered on the first screen, and multiple pieces of data need to be collected for rendering: in this case, the content with a high priority can be displayed first
- The data on the first screen takes too long to be requested from the server: Analyze the reason why the data takes too long to be returned
- The one-time rendering data is too large or the dependent calculation is too complex: reduce the amount of rendered data and optimize the algorithm of rendering related data
- It takes too long to render the interface. It is necessary to check whether the area rendered at the same time is too large (for example, the list is too long).
- Script execution takes a long time: The logic of the script needs to be confirmed and optimized
- Frequent call of setData: Avoid frequent call of setData that is useless. The number of call of setData should not exceed 20 times per second.
// Don't call it too oftensetData this.setData({a: 1}) this.setData({b: 2}) // Most of the time can be optimized to this.setData({a: 1, b: 2}).Copy the code
- SetData data is too large, setData data after json.stringify does not exceed 256KB
- SetData An unbound variable
This.setdata ({myData: {a:}); // Do not set the data that is not used in the interface rendering, and put the data that is not relevant to the interface outside the data.'This string is used in WXML',
b: 'This string is not used in WXML, and it is long ………………………… '}}) // can be optimized to this.setData({'myData.a': 'This string is used in WXML'
})
this._myData = {
b: 'This string is not used in WXML, and it is long ………………………… '
}
Copy the code
- Enable HTTP cache control
- Control the number of WXML nodes
<view data-my-data="{{myData}}"> <! This view can be merged with the view in the next line --> <view class="my-class" data-my-data="{{myData}}" bindtap="onTap"> <text> <! - the text is usually not necessary - > {{myText}} < / text > < / view > < / view > <! -- can be simplified to --> <view class="my-class" data-my-data="{{myData}}" bindtap="onTap">
{{myText}}
</view>
Copy the code
- Control the size of the picture, the width and height of the picture should not exceed 3 times of the actual display width and height
- Control the number of network requests
- Control the number of image requests
- Scrolling: enable overflow: scrollin WXSS. In iOS, set -webkit-overflow-scroll: touch
- Avoid using the :active pseudo-class for click-throughs
- Maintain image size ratio
- None of the clickable elements should be less than 20px in width and height
- IphoneX compatible, compatible with the following WXSS:
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
Copy the code
- Avoiding JS exceptions
- Do not use obsolete interfaces
- Set the minimum base library version
- Remove inaccessible pages
- Remove a lot of unused styles
- Recycle timer: The timer is global and not bound to the page. When the applet routes from one page to another, the previous page timer should be recycled manually