In the first article we introduced the Dokit module into our own small program project, so the next step is to formally read the source code of Dokit.
I. Overview of wechat applets custom components
Dokit module is composed of a number of custom components, so before reading the source code, we need to briefly understand the basic knowledge of wechat small program custom components. Wechat applet can be said to be composed of multiple page pages, and each page is composed of multiple components, including wechat’s native components, including the user’s custom components.
The composition of a custom component is very similar to the composition of a Page Page, with four files: JS, JSON, WXML, and WXSS.
- Js files: logical files for pages/custom components
- WXML files: pages/custom componentstructureFiles, by analogy
HTML
, but there is no HTML div, P and other tags, instead of wechat small program components, such as View, button and so on - WXSS files: pages/custom componentsstyleFiles, by analogy
CSS
, but WXSS files within custom components cannot use ID selectors, attribute selectors, and tag name selectors - Json file: configuration file of a page or custom component. For a page, you can set whether to use custom components here. For custom components, set whether to use a custom component and, more importantly, declare the module as a custom component here
Reference custom components
Declare in the page or json file of a custom component that you want to reference :(custom components can reference other custom components)
{
"usingComponents": {
"dokit": ".. /.. /dist/index/index"}}Copy the code
Declare a module as a custom component
Declare this in the JSON file of your custom component:
{
"component": true."usingComponents": {
"back": ".. /.. /components/back/back"}}Copy the code
Ii. Overview of the project organization structure
As shown, the Dokit project body is in the dist folder
Let’s first understand the distribution of the project catalog, which helps us to have an overall control of the project:
assets
– there areimg
Folder, store icon and other image resourcescomponents
The core of Dokit includes eight custom components
- Apimock — a custom component of the data emulation functionality
- Appinformation — a custom component of an App’s information function
- Back – Custom component used to return. This component is not a functional component of Dokit, but is called by all custom components except index to return to the applet Page
- Debug – Custom components that perform main menu functions, listing various Dokit features
- H5door — Custom component for any door function of H5
- Httpinjector — A custom component that requested the injection function
- Positionsimulation — a custom component of the location simulation function
- Storage – a custom component of storage management functionality
index
— A custom component in the Dokit entry that introduces Dokit into your project by introducing this component into the target Pagelogs
— and the new micro channel applet in the sample programlogs
Page the same page, check the program startup log, currently do not know what this part of Dokit is usedutils
— There are two files in it,imgbase64.js
Dokit is used to convert various ICONS into Base64 format;util.js
It stores some common interface functions, including time output, jump page, deep copy, etc
Here’s a quick explanation of what base64 images are:
The base64 format is an encoding format that converts binary into character, while the base64 encoding of picture is to encode the data of a picture into a string. This front-end (such as HTML or WXML) can be converted directly from encoded strings to images. Base64 format can reduce the request of downloading images to the server for all kinds of small images. Note, however, that base64 encoded strings tend to be larger than the image itself, so this is only suitable for small, infrequently changing images.
More detailed Base64 encoding information can be found in this article. After a brief understanding of the directory distribution of the project, we start with the Dokit entry component Index and read the source code step by step. To determine our reading order before reading the source code, the custom component has four files. We read.json,.wxml, and WXSS files first, interspersing with.js files.
3. Dokit entry components
Remember when we first introduced the Dokit module to our applet project, we added the following statement to the page. Json file of the corresponding page:
"usingComponents": {
"dokit": ".. /.. /dist/index/index"
}
Copy the code
The custom component we introduced was the Index component in the Dist folder, which was the entry component to Dokit. Take a look at the component’s JSON file and determine what component it refers to:
{
"component": true."navigationBarTitleText": ""."usingComponents": {
"debug": ".. /components/debug/debug"."appinformation": ".. /components/appinformation/appinformation"."positionsimulation": ".. /components/positionsimulation/positionsimulation"."storage": ".. /components/storage/storage"."h5door": ".. /components/h5door/h5door"."httpinjector": ".. /components/httpinjector/httpinjector"."apimock": ".. /components/apimock/apimock"}}Copy the code
You can see that this component refers to all the functional components of Dokit in the Components folder. Then look at the WXML file to determine its structure/template and how it calls so many components:
<block wx:if="{{ curCom! = 'dokit' }}">
<debug wx:if="{{ curCom === 'debug' }}" bindtoggle="tooggleComponent"></debug>
<appinformation wx:if="{{ curCom === 'appinformation' }}" bindtoggle="tooggleComponent"></appinformation>
<positionsimulation wx:if="{{ curCom === 'positionsimulation' }}" bindtoggle="tooggleComponent"></positionsimulation>
<storage wx:if="{{ curCom === 'storage' }}" bindtoggle="tooggleComponent"></storage>
<h5door wx:if="{{ curCom === 'h5door' }}" bindtoggle="tooggleComponent"></h5door>
<httpinjector wx:if="{{ curCom === 'httpinjector' }}" bindtoggle="tooggleComponent"></httpinjector>
<apimock wx:if="{{ curCom === 'apimock' }}" bindtoggle="tooggleComponent" projectId="{{ projectId }}"></apimock>
</block>
<block wx:else>
<cover-image
bindtap="tooggleComponent"
data-type="debug"
class="dokit-entrance"
src="//pt-starimg.didistatic.com/static/starimg/img/W8OeOO6Pue1561556055823.png"
></cover-image>
</block>
Copy the code
The following points need to be noted:
wx:if
Conditions apply colours to a drawingbindtoggle
Communication between components{{curCom}}
Data binding
Let’s start with conditional rendering, where the view layer renders the current component only if the condition after wx:if is true, and otherwise renders the wx:else part of the component (note that conditional rendering is lazy and starts with false by default and does not render). Then we see that the condition in wx:if is “{{curCom! = ‘dokit’}}”, this is the data binding in the WXML syntax of wechat applet: the statement surrounded by two curly braces can only put a variable name or simple operation, the specific value of the internal variable is dynamic, actually comes from the value of the same attribute in the data of the.js file with the same name as the WXML file. If you look at the data property in index.js, you can see that the value of this variable is initialized to curCom: ‘Dokit’ so when the component is initialized for the first time, it renders the component inside
, i.e.
. Test the effect of data binding by changing curCom in data to DEBUG/appInformation. You can see that index displays a different function window depending on the curCom string. A simple illustration is as follows:
We can modifycurCom
The value of index can change what the component of the index condition is, while the component itself must be changed by the user’s click actioncurCom
The process is essentially communication between components.
BindXXX = Communication between toggleComponent components
Looking at the previous index.wxml file, we saw that each component has a bindXXX property with a toggleComponent value, which is how the component changes the curCom value: events. Communication between components, in addition to the parent component to the child through data binding, there is also a way called event listening from the child component to the parent component data:
- Event system is one of the main ways of communication between components. Custom components can trigger arbitrary events that pages referencing components can listen for; Events are the communication mode from the view layer to the logical layer, which can feed back the user’s behavior to the logical layer for processing.
- Events can be bound to components, and when a triggering event is reached, the corresponding event handler functions in the logical layer are executed. Event objects can carry additional information, such as ID, dataset, and Touches.
- The way to listen for custom component events is exactly the same as the way to listen for underlying component events.
Component communication is achieved using events in the following ways:
- The parent component listens for events
- The child component fires the event
In the index component, add the bind attribute to the child as < component name bind event name =” event handler “>
<debug bindtoggle="toggleComponent"></debug>
Copy the code
Then add event handlers to the.js logical layer, which should be executed when the parent component receives an event from the child component.
methods: {
toggleComponent(e) {
const componentType = e.currentTarget.dataset.type || e.detail.componentType
this.setData({
curCom: componentType
})
}
}
Copy the code
Let’s leave the reading of this handler behind and look at how the child component fires the event: When a custom component fires an event, you need to use the triggerEvent method, specifying the event name, detail object, and event options. Let’s take a look at any feature component and see how it specifies the event name toggle. Take the Debug component as an example:
onGoBack () {
this.triggerEvent('toggle', { componentType: 'dokit'})}Copy the code
In this method, the first argument is that the event named toggle is triggered, and the second argument is that a detail object is built: property componentType, value dokit string. Having looked at the function that raises the event for the child, we can now return to how the parent responds to the event:
- The parameters of the response function are
e
, event, is an object that contains information passed by child components. - We define a variable inside the function
componentType
, assigns the detail object’s componentType value obtained from e, and calls the component’ssetData
Method to pass the value of the variable to the view layer and modify itindex
Property corresponding to data in the component.
And notice, Response function is more than the pop3access.componenttype = e.detail.com ponentType but e.c. with our fabrication: urrentTarget. Dataset. The type | | E.detail.com ponentType and | | operators are previous value of the source cover – image
<cover-image
bindtap="tooggleComponent"
data-type="debug"
class="dokit-entrance"
src="//pt-starimg.didistatic.com/static/starimg/img/W8OeOO6Pue1561556055823.png"
></cover-image>
Copy the code
The event monitored in this component is not toggle, but tap, which is triggered by the user clicking. The information passed in this component is not the detail object, but the value of the property type in the dataset. Dataset and currentTarget:
currentTarget
Is the current component of the event binding and has two properties: ID and dataset.dataset
Is a collection of custom attributes starting with data- on the current component that can be retrieved in an event for logical processing of the event.- In WXML,
dataset
Custom data starts with data-data-elementType
, will eventually be rendered in JS asevent.currentTarget.dataset.elementtype
Please refer to the applet official documentation for more details. So far, we have seen that the curCom in the data layer of the Index component is modified by events in response to various events, such as toggle or tap. But there is a question: where and when is the onGoBack function called, even though it triggers the toggle event?
Further observe the component communication process
As we now know, the logical layer methods are invoked in the view layer WXML file by way of event listening/response. So let’s just search for where the onGoBack function was called. Soon, we can find a statement like this in every component, again using the debug component as an example:
<back bindreturn="onGoBack"></back>
Copy the code
Bindtoggle =”toggleComponent” works the same way as in the previous section: The debug component responds to an event named return from the child component back and handles it through the onGoBack function. Back. Js and back. WXML:
methods: {
onbackDokitEntry () {
this.triggerEvent('return')}}Copy the code
<cover-image
bindtap="onbackDokitEntry"
data-type="debug"
class="dokit-back"
src="//pt-starimg.didistatic.com/static/starimg/img/W8OeOO6Pue1561556055823.png"
style="top: {{ top }}"
></cover-image>
Copy the code
As you can see, the way the back component triggers the return event is similar to the way the index component covers the image, which is bindtap+data-type. Finally, a diagram is used to sort out the communication process:
conclusion
So far, we are familiar with the overall directory structure of the Dokit applet and have read the source code for the entry component, the Index component. We learned how custom components communicate, how children use the event system to pass values to their parents, and how parents respond to their children. This reading of the code is not much, but we understand some features of the small program such as conditional rendering, data binding, event system, for us to continue to read the source code laid a simple foundation for the small program.