Project background

In recent years, with the vigorous development of open source in China, some colleges and universities have begun to explore open source into the campus, so that students can feel the charm of open source when they are students. This is also a new teaching mode that colleges and universities and domestic leading Internet enterprises try together. This project will document the learning results of the students during this period.

More topic background reference: [DoKit& Peking University topic] origin

series

[DoKit& Peking University] Origin

【DoKit& Peking University special Topic 】- Read the small program source code (a)

【DoKit& Peking University special Topic 】- Read the small program source code (two)

The original

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 analogyHTML, 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 analogyCSS, 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 – Inside the IMG folder, storing icon and other image resources

  • Components — The core part of Dokit, including 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 of the Dokit entry that is introduced in the target Page when you introduce Dokit into your project

  • Logs — the same as the logspage page in the sample program when creating wechat applet. Check the program startup log. What is the use of this part in Dokit

  • Utils — there are two files, imgBase64. js, that convert Dokit ICONS to Base64; Util. Js 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 started from Dokit’s 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 of Dokit’s functional components in the Components folder, and 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 conditional rendering of communication between Bindtoggle 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 in wechat applet WXML syntax. Data binding: Statements enclosed in curly braces can contain only a variable name or a simple operation. The actual value of the internal variable is dynamic and actually comes from the value of the same property in the.js file data 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 change the component of the index condition by changing the value of curCom, and the component itself must change the value of curCom by the user’s clicking action. This process is actually communication between the 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:

1. The parent component listens for events. 2

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:

  1. The response function takes the parameter E, event, which is the object containing the information passed by the child component.
  2. A variable componentType is defined in the function, and its value is the componentType value of the detail object obtained from E, and the setData method of the component is called, and the value of the variable is passed to the view layer, and the corresponding attribute of data in the index component is modified.

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:

  1. CurrentTarget is the current component of the event binding and has two properties: ID and dataset.
  2. Dataset is aset of custom attributes starting with data- on the current component. These custom node data can be obtained in the event for logical processing of the event.
  3. Dataset in WXML custom data starting with data – data – elementType, will eventually be present in js for the event. The 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 called 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')
    }
  }

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

The author information

Author: As zhuang and As Harmonic

Original link: juejin.cn/post/694807…

Source: Nuggets