Since the runtime standard for applets has recently been reworked, I will write a separate article to clarify the important features of applets
The ultimate goal is to build a tree, put all this information into the tree, and finally get a subset of wechat
Json configuration:
- app.json
{
"pages": ["pages/index/index"."pages/logs/index"].// Matches the first one by default
"window": {
"navigationBarBackgroundColor": "#ffffff".// Top navigation bar background color
"navigationBarTextStyle": "black".// Top navigation bar text color
"navigationBarTitleText": "Wechat Interface Function Demonstration".// Top navigation bar text content
},
"tabBar": {
"list": [{"pagePath": "pages/index/index".// Page path
"text": "Home page".// The fine print below
"iconPath": "img/news.svg"./ / the default diagram
"selectedIconPath": "img/news-sel.svg" // The selected image
},
{
"pagePath": "pages/logs/logs"."text": "Log"}},"usingComponents": { // Public components
"component-tag-name": "path/to/the/custom/component"
},
"useExtendedLib": { // Reduce precompilation
"kbone": true."weui": true
},
"debug": true.// Enable debug mode to generate useful logs
"version": "v3".// You can use this field for version control
}
Copy the code
That’s what I think is important in app.json. In addition to supporting these fields, we need to deal with some minor details
1.Tabbar ICONS need to support SVG, PNG bitmaps will be distorted2.UseExtendedLib can be mademoduleFederation, to reduce precompilation3.Add a version field for version controlCopy the code
- [page].json
{
"navigationBarBackgroundColor": "#ffffff"."navigationBarTextStyle": "black"."navigationBarTitleText": "Wechat Interface Function Demonstration"."enablePullDownRefresh" : "true".// Start the pull-down refresh and trigger the onPullDownRefresh callback
"onReachBottomDistance": 50.// The distance to trigger the onReachBottom callback
"usingComponents": { // Page component
"component-tag-name": "path/to/the/custom/component"
},
"disableScroll": "true" // Disable the IOS bounce-back and onPageScroll methods
}
Copy the code
The page field is much simpler, with the exception of a few window fields that override app.json, only the useComponents field is important
A few things to watch out for:
1.App. json also supports uniform configuration of the fields listed above2.The drop-down refresh, bottom, and Scroll configurations are all specific to the page and need to be distinguished from the scroll viewCopy the code
2. App interface
- App()
App({
onLaunch (options) {
// When the app starts
},
onShow (options) {
// When app is activated
},
onHide () {
// App is inactivated
},
onError (msg) {
// Error collection
},
globalData: {}, // globaldata
})
Copy the code
- getApp()
const app = getApp()
console.log(app.globalData)
Copy the code
Applets don’t have a lot of stuff on the App instance, but some tool components are still attached
Page interface
- Page()
Page({
data: {
count: 0
},
onLoad: function(options) {
/ / page load
},
onShow: function() {
/ / page show
},
onReady: function() {
/ / page is ready
},
onHide: function() {
/ / hide the page
},
onUnload: function() {
/ / page unload
},
onPullDownRefresh: function() {
// Pull down the refresh callback
},
onReachBottom: function() {
// Bottom correction
},
onShareAppMessage: function () {
// Basically useless sharing
},
onPageScroll: function() {
// scrollTo
},
onResize: function() {
// Resize on PC
},
onTabItemTap(item) {
// TAB tap callback
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// Common events
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
})
// serialize to jSON-patch
this.setData({
"a.b.c[0]": 'Set some data for updating view.'})}})Copy the code
There are many events in Page, but they are mainly divided into three categories:
1.Life cycle -> in general2.Pull down, hit bottom, scroll callback3.Data, setData, normal eventsCopy the code
One of the most overlooked is the JSON-patch format of this.setData, which is the basis for the later custom component observer
- getCurrentPages()
const stack = getCurrentPages()
Copy the code
The page stack
This is a stack that you get with getCurrentPages, where the first element is the home page and the last element is the current page
API | Stack behavior |
---|---|
load | Home page into the stack |
wx.navigetTo | Into the stack |
wx.redirectTo | Top of stack replacement |
wx.navigateBack | Cycle out of the stack |
wx.switchTab | Clear the stack, and then the target page is pushed |
reload | Clear the stack, and then the current page is pushed |
The above stack behavior is related to the lifecycle, but in general, as long as the page is in the stack, the lifecycle goes show and hide, or load and unload if it is not in the stack
We’ll sort this out later
4. Component interface
- Component()
Component({
behaviors: [].properties: {
myProperty: { / / the property name
type: String.value: ' '
},
myProperty2: String // A simplified definition
},
data: {}, // Private data that can be used for template rendering
lifetimes: {
// Lifecycle
attached: function () {},moved: function () {},detached: function () {},},pageLifetimes: {
// The lifecycle of the page on which the component is located
show: function () {},hide: function () {},resize: function () {},},methods: {
onMyButtonTap: function(){
this.setData({
'A[0].B': 'myPrivateData'})},triggerParentEvent(){
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
}
observers: {
"A[0].B": function(newVal, oldValue) {
console.log(newVal)
}
}
})
Copy the code
Component is bolder than Page in terms of properties and observers
Properties and data share the same template scope. In general, they cannot have the same key. In wechat, Data overwrites props, while in VUE, an error is reported
I prefer the VUE treatment
observers
Observers are the same as the previous Watch, but with much improved performance, and I suspect copy-on-write using Proxy
It is worth mentioning that this piece directly compares the JSON-patch of setData and the Json-patch of observer
Json-patch not only improves the performance of observer, but also improves the performance of setData thread delivery
- Behavior()
const b = Behavior({
behaviors: [].properties: {
myBehaviorProperty: {
type: String}},data: {
myBehaviorData: {}},attached: function(){},
methods: {
myBehaviorMethod: function(){}}})Copy the code
It takes the same parameters as custom components and generally has three merge strategies:
1.Queues, such as lifecycle -> Behavior -> Component -> Child -> parent -> Front -> back2.Merge objects such as data, observer -> Component -> Behavior -> parent -> Child -> back -> front3.Replace, event, Properties -> rules same2
Copy the code
It is worth mentioning that the order of the life cycles here is bubbling, so let’s go on to tease out the life cycles
Life cycle
This should be mentioned separately because applets are two-threaded, and Page, Component, and even Behavior are lifecycle dependent
- Page life cycle, this is the simplest:
Onload: logic layer loaded, stack onready: view layer to load, equivalent to didmount onshow: native side show -- -- -- -- | onunload: Uninstall the logic layer, the stack | onshow and onhide switch back and forth | onhide: native hidden side -- -- -- --Copy the code
The onshow/onhide cycles are the same as Berial’s mount/unmount cycles
They switch back and forth, and IN Berial I used a stateful queue to do this
- Component lifecycle
Wechat’s Component is a view-only implementation, and its lifecycle is originally web-Component lifecycle, so this thing…
Attached: The render layer is loaded, equivalent to didmountdetachedThe render layer is unmounted, equivalent to didunmountCopy the code
- The order of the life cycle between the father and the child
In React, the life cycle sequence of the father and son is diving and then bubbling
<cmp-a>
<cmp-b>
<cmp-c></cmp-c>
</cmp-b>
</cmp-a>
cmp-a - componentWillMount
cmp-b - componentWillMount
cmp-c - componentWillMount
cmp-c - componentDidMount
cmp-b - componentDidMount
cmp-a - componentDidMount
Copy the code
The order of the applet is the same, its attached equivalent to componentDidMount, and naturally also from child to parent
Fourth, the WXS
This thing is in the view layer, I guess it emulates a CJS standard and runs with New Function
There’s nothing to say. It’s like…
Building data Structures
Basically, that’s it, and once you’ve sorted everything out, you can meditate on what the structure looks like
First it must be a tree, and then it looks something like this:
App
- [ // this is a stack
- Page1
- [
- Component1
-[
- Component3
-]
- Component2
- ]
- Page2
- ]
1.The overall structure is a tree2.Pages is a stack3.Behaviors is a tree4.The life cycle is a queueCopy the code
With this structure, it is easy to fill cases, such as:
export function getCurrentPages(){
reutn app.pageStack.values()
}
Copy the code
One line of code, aha
After this cleaning, I have a better understanding of the overall architecture of applets, which is equivalent to a low-profile version of VUE
I can’t reveal the implementation details, but I think I can build a satisfactory structure
Looking at the sky, the first time to write such a long article, feel really can not gather together ten thousand words, forgive me, we all have to make a living duck……