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)

【DoKit& Peking University Special Topics 】- Read the small program source code (three)

Implementation of DoKit For Web request capture tool (I) Product research

【DoKit& Peking University topics 】-DoKit For small program source analysis

The original

DoKit profile

DoKit is an efficiency platform for the whole life cycle of pan-front-end product development. As the project with the most Stars under DiDi, it now has 17K +Stars. The purpose of this article is to analyze the source code of DoKit small program direction.

Project introduction and use

Note: SRC/is used to read source code or to develop DoKit. The dist/ SRC directory should be different from dist: SRC is the source code, dist is the js file from SRC packaged and output

Writing in the front

aboutDoKit for miniappHere are two PPT of DoKit teachers. I think “dancing in the framework of” this sentence to describe very appropriate, small program on WeChat client, has limitations in the development process, if you want to develop some auxiliary functions, big probability is through to the WeChat small program for certain modifications to achieve the official API, below the analysis of the source code has been in this thought.

DoKit project structure

` `

Assets — Assets folder, currently contains the icon file Components — the core part of Dokit, which contains eight custom components

  1. Apimock — Data Mock functionality component
  2. Appinformation — App information viewing function component
  3. Back — a custom component used to return that is not a Dokit feature component and is used to return on other feature pages
  4. Debug – Main menu component that lists various Dokit features
  5. H5door — ANY door function component of H5
  6. Httpinjector — Requested an injection function component
  7. Positionsimulation — positionsimulation of functional components
  8. Storage – Storage management function component

Index — a custom component of the Dokit entry that is introduced in the target Page when Dokit is introduced into the project

Logs — Same as logs in the wechat applet sample project, there seems to be no use of utils — imgBase64. js to convert Dokit ICONS into base64 format; Util.js stores some common utility functions, including time output, jump page, deep copy, etc

Reference article: juejin.cn/post/694807… In harmony with the law

The index component

An entry to the DoKit toolset. This component acts as a shell, and other functional components are displayed on the Index component page.

The code analysis

  • index.json
{
  "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

So index itself is a custom component, and it introduces all the other functionality of DoKit what is a custom component?

Developers can abstract functional modules within a page into custom components that can be reused across different pages. Complex pages can also be broken up into low-coupling modules to aid code maintenance. Custom components are very similar to the base components when used.

  • index.wxml
<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

Wx :if is the list rendering syntax of the WXML file, so the index page shows the different functional components according to the values of {{curCom}}.

  • index.js
Component({
  properties: {
    projectId: {
      type: String.value: ' ',}},data: {
    curCom: 'dokit',},methods: {
      tooggleComponent(e) {
        const componentType = e.currentTarget.dataset.type || e.detail.componentType
          this.setData({
            curCom: componentType
          })
      }
  }
});
Copy the code

The initial value of {{curCom}} is ‘dokit’, so the WX :else block is displayed and there is only one icon on the page

Bindtap listens for click events. Clicking on the icon will call the tooggleComponent method in the JS file, passing in event E. This method can obtain e.c. with our fabrication: urrentTarget. Dataset. Type | | e.detail.com ponentType these two values and update the curCom value, you can print out for validation, the first value is the debug, the second value undefined.

The change of the curCom value affects the components displayed on the page. Therefore, the debug component is displayed on the page after clicking the icon. The third line of output from the console in the figure above is the symbol of the Debug component entering the node tree on the page. Try to change the data in the WXML file – type = “debug” value is the name of the other components, click again will show the corresponding new components, which proves the e.c. with our fabrication: urrentTarget. Dataset. The type of value is determined by the data – the type attribute.

Further observation, when clicking the icon of other functions on the Debug component, such as App information, the Debug component in the shell index will be replaced. The output of the console is shown in the figure below, indicating that it is indeed the curCom value that determines the component displayed on the Index page. Notice that the tooggleComponent method is fired again. According to the code, the only source of the tooggleComponent method is bindtoogle. Observe the e.c. with our fabrication: urrentTarget. Dataset. Type | | e.detail.com ponentType first value becomes undefined, the second value for appinformation.

Current doubts

I know bindtap is listening to the click event, but what is the purpose of bindtoggle, and how they relate to e.c. with our fabrication: urrentTarget. Dataset. The type | | e.detail.com ponentType relationship is what? (Analysis below)

The back component

This component is referenced by other components except index and appears as a Dokit logo in the pages of other components. Clicking the logo will return you to the original Index page. The Back component works simply and is a good place to learnCommunication between components and custom events.

The principle of analysis

Click each button in DoKit to switch the corresponding component, which is realized by the custom events in the component. To use custom components, you need to have listeners and triggers. The child component triggers the event and the parent component listens for the event. Taking the back component, which is referenced by each functional component, as an example, the code in back.wxml is as follows

<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

The back component is represented as an image. The image listens for the click event. When the event is triggered, the onbackDokitEntry method is called. (In addition, I think the source code of data-type=”debug” is not used, according to the following analysis, the event is triggered without this data)

 onbackDokitEntry (e) {
      // console.log(e)
      this.triggerEvent('return')}Copy the code

As you can see, the onbackDokitEntry method fires a return event. In the WXML of other components, using the AppInformation component as an example, the back component is used as follows

  <back bindreturn="onGoBack"></back>
Copy the code

This indicates that the back component in the AppInformation component is listening for a custom event named return, and if it is listening, it calls the onGoBack method, as defined in the js file below

 onGoBack () {
   // Triggers the event, carrying the detail object
   this.triggerEvent('toggle', { componentType: 'dokit'})}Copy the code

The onGoBack method triggers an event named toggle and carries a detail object {componentType: ‘dokit’}. Returning to the outermost Index shell page where the other components are loaded, you can see that the appInformation component is used as follows:

<appinformation wx:if="{{ curCom === 'appinformation' }}" 
                bindtoggle="tooggleComponent">
</appinformation>
Copy the code

You can see that you are listening for the event named Toggle and calling the tooggleComponent method, which is defined as follows

tooggleComponent(e) {      
        const componentType = e.currentTarget.dataset.type || e.detail.componentType
          this.setData({
            curCom: componentType,        
          })
      }
Copy the code

According to the value of componentType in the detail object carried by toogle event, the value of curCom is changed to ‘dokit’. As mentioned in the previous analysis of index component, the value of curCom directly affects the display of the component in index. When the value is ‘dokit’, the index page will look like a primitive logo. So, this explains how the back component works — by listening for a click on the logo icon, it triggers a series of custom return events from the inside out to be displayed on the Index page. It also explains some of the functions of bindtoggle mentioned above (this event is not only used to return, but also to get from the Debug component to other functional components, as discussed below).

The flow chart of the Back component is as follows

The debug components

This component acts as a function menu, showing all the functions that DoKit currently has, and clicking on each icon takes you to the corresponding function component.

Function display

debug.wxml

<view wx:for="{{tools}}" wx:key="index" class="debug-collections card">
Copy the code

debug.js

lifetimes: {
  attached () {
    this.setData({
      tools: this.getTools() }); }},getTools() {
    return[{"type": "common"."title": "Common Tools"."tools": [{"title": "App information"."image": img.appinfoicon,
            "type": "appinformation"
          },
          // omit...]]}},Copy the code

Attached is a component life cycle method, which is executed when the component instance enters the node tree of the page. It can be seen from the code that every time the DEBUG component enters the index page, the getTools method assigns the value to the Tools variable of the component, and the getTools method returns the information of other functional components. Then in WXML, the list is rendered using wx:for=”{{tools}}” to loop through all the functionality.

Feature selection

debug.wxml

<view wx:for="{{item.tools}}"
              wx:for-index="idx"
              wx:for-item="tool"
              wx:key="idx"
              data-type="{{tool.type}}"
              bindtap="onToggle"
              class="card-item">
Copy the code

In the list loop, each icon listens for the click event and calls the onToggle method after the click occurs. The data-type attribute can be used to add information to the event so as to determine which function the user clicks.

You can attach custom data to component nodes. In this way, the custom node data can be retrieved in the event for the logical processing of the event. In WXML, this custom data begins with data- and multiple words are hyphenated. In this script, the hyphen is converted to the hump, and uppercase characters are automatically converted to lowercase characters. Such as:

  • Data – element – type, eventually will be present for the event. The currentTarget. Dataset. ElementType;
  • Data – elementType, eventually will be present for the event. The currentTarget. Dataset. ElementType.

WeChat development documentation, developers.weixin.qq.com/miniprogram…

degub.js

onToggle (event) {
  const type = event.currentTarget.dataset.type;
  if(type === 'onUpdate') {
    this[type]();
  } else {
    // Triggers the event, carrying the detail object
    this.triggerEvent('toggle', { componentType: type })
  }
},
Copy the code

According to official documentation and code,event.currentTarget.dataset.typeIt’s in WXMLdata-typeAttribute values. If the user clicks on a newer version feature, the one defined in this JS file will be calledonUpdateMethod (this method is analyzed below); If it is any other function, it is triggeredtoggleEvent with a detail object, which is then, as analyzed above, placed in the index pagebindtoggleListen and update according to the detail objectcurComValue, so as to realize the switch of the corresponding functional components in the page.The flow chart is as follows

At the end of the back component section, I mentioned that Bindtoggle has two functions, so I can summarize now:

  • Listen for the click logo return event in all components
  • Listen for feature selection events in the debug component

As you can see, the lowest trigger condition for these nested custom events is TAP, or click action.

Version update function

This function is used to check whether the latest release version of the applet is higher than the current version on the device

onUpdate () {
  const updateManager = wx.getUpdateManager();
  updateManager.onCheckForUpdate(function (res) {
    if(! res.hasUpdate) {// Request a callback for the new version information
      wx.showModal({
        title: 'Update Prompt'.content: 'Current is the latest version'}}})); updateManager.onUpdateReady(function () {
    // The new version was downloaded successfully
    wx.showModal({
      title: 'Update Prompt'.content: 'The new version is ready. Do you want to restart the application? '.success(res) {
        if (res.confirm) {
          // The new version has been downloaded. Call applyUpdate to apply the new version and restart
          updateManager.applyUpdate()
        }
      }
    })
  });
  updateManager.onUpdateFailed(function () {
    // Failed to download the new version
     wx.showModal({
       title: 'Update Prompt'.content: 'Download failed'.success(res){}})})},Copy the code

As mentioned earlier, the onUpdate method above is called in the Debug menu component if the update version function is clicked. Wx. getUpdateManager is wechat official interface, used to get the small program global unique version UpdateManager UpdateManager object, in order to manage the update of the small program, the object has four methods.

  • UpdateManager.applyUpdate()

Forces the applets to restart and use the new version. Called after the new version of the applet is downloaded (that is, the onUpdateReady callback is received).

  • UpdateManager.onCheckForUpdate(function callback)

Monitor the event that requests the wechat background to check the update result. Wechat will automatically check for updates when the small program starts cold, without being triggered by the developer.

  • UpdateManager.onUpdateReady(function callback)

Listen for a version update event in the applet. The client automatically triggers the download (without triggering by the developer), and the download is successfully triggered

  • UpdateManager.onUpdateFailed(function callback)

Listen for applets update failure event. There is a new version of the small program. The client automatically triggers the download (no need to be triggered by the developer), and the download fails (possibly due to network reasons)

WeChat development documentation, developers.weixin.qq.com/miniprogram…

soonUpdateThe whole logic of the method is to check for a newer version and use it if it doesn’twx.showModalThe mode dialog box is displayed indicating that the current version is the latest. If it exists, the wechat client will automatically download the new version of the small program. If the download is successful, it will be calledonUpdateReadyA callback to remind the user to restart the new version of the application or call it if the download failsonUpdateFailedIn the callback (the source of the callback function content is empty, here I imitateonUpdateReadyAlso added a dialog box for the callback in.

Positionsimulation components

It is used for position simulation of small program side, including position authorization, position view, position simulation, recovery position setting and other major functions. It can realize any position simulation and position restoration through simple click operation. The realization principle of this function is to re-write the method of wx.getLocation, and then simulate the position. In the small program all call location query methods will return you set the location, restore will restore the native method DoKit document, github.com/didi/Doraem…

Rapid authorization

<button class="fast-authorization" open-type="openSetting">Rapid authorization</button>
Copy the code

With open-type wechat open capability, click button to open the mini program authorization setting page

Check the position of

Using a custom openMyPosition method, defined as follows

 openMyPosition (){
   wx.getLocation({
     type: 'gcj02',
     success (res) {
       wx.openLocation({
         latitude:res.latitude,
         longitude:res.longitude,
         scale: 18}}}})),Copy the code

The type attribute is ‘gcj02’, which is a coordinate that can be used for wx.openLocation. If the interface is successfully called, the coordinate will be passed to the wx.openLocation method. Use wechat’s built-in map to view your current location.

Select location

Preliminary knowledge:

The ** object.defineProperty ()** method directly defines a new property on an Object, or modifies an existing property of an Object, and returns the Object. Reference: developer.mozilla.org/zh-CN/docs/…

Use a custom choosePosition method, defined as follows

choosePosition (){
  wx.chooseLocation({
    success: res= > {
      this.setData({ currentLatitude: res.latitude });
      this.setData({ currentLongitude: res.longitude })
      Object.defineProperty(wx, 'getLocation', {
        get(val) {
          return function (obj) {
            obj.success({latitude: res.latitude, longitude: res.longitude})
          }
        }
      })
    }
  })
},
Copy the code

First call wechat official wx.chooseLocation method to open wechat built-in map to select location. After successful call, use Object.defineProperty method to rewrite wx.getLocation method. So when we change the get function of this property, we actually rewrite the function definition of getLocation. In the new function definition, we take an object parameter, Call its SUCCESS method and pass in the coordinate data we selected, so that every time we call the wx.getLocation method in the future, the success callback function is passed in the coordinate data we selected. (Get function does not need parameters, source code should be a mistake)

To summarize, we overwrote the **wx.getLocation** method so that it passes the value we set to its callback function.

reduction

Use a custom resetPosition method

const app = getApp()
app.originGetLocation = wx.getLocation


/ / to omit...

resetPosition (){
  Object.defineProperty(wx, 'getLocation', {get(val) {
      return app.originGetLocation
    }
  });
  wx.showToast({title:'Restore successful! '})
  this.getMyPosition()
},
Copy the code

In the beginning, we use app.origingetLocation to save the original function definition in wx.getLocation for later restoration. Later, similar principle is used to rewrite wx.getLocation back using object.defineProperty method to achieve restore.

conclusion

Apimock components

What is the mock

Mock intercepts network requests and returns a mock server response, enabling developers to complete front-end development even before the back-end interface is implemented.

Results demonstrate

  1. Create a new data mock on the platform side

Set the interface name to test, the interface class to test, and the request path to/testOn the details page, you can also add multiple scenarios and set the return values for different scenarios. Here I have set two scenarios.DefaultandScenario 1

  1. Check out the mock feature on the applet

First make sure to pass in the projectId attribute on the component page that introduces DoKit. ProjectId can be found on the platform side

  <dokit projectId="5fcd3ef4b4f88839cd7bff5848bfe3ca">
  </dokit>
Copy the code

Open the ApiMock component and you can see the Test interface that we registered earlier

  1. Simulate a network request

Add a button on the home page, when the button is clicked, to/testThe interface sends a GET request and, if successful, prints the result back

mock_test(){
    wx.request({
      url: 'https://localhost/test'.method:"GET".success:function(res){
        console.log(res)
      }
    })
  },
Copy the code
  1. The test results

Turn on the mock switch and set the scene value toDefault, click the button to send the request, observe the console, you can see that is the return value we set beforeSet the scene value toScene: the value of 1, the test again found that the return value did change accordingly

  1. The template function

After the mock interface is successfully requested, the returned data is saved as template data for easy uploading

The code analysis

The principle of the view layer is very simple, which has been involved in the previous analysis of other components, so I will not repeat it here, and directly analyze the logical layer according to the top-down method, first look at the life cycle of the component

lifetimes: {
  created () {
  },
  attached () {
    this.pageInit()
  },
  detached () {
    wx.setStorageSync('dokit-mocklist'.this.data.mockList)
    wx.setStorageSync('dokit-tpllist'.this.data.tplList)
  }
},
Copy the code
  • Called when the component enters the page for usepageInitMethod, which by its name is supposed to be an initialization method.
  • Called when the component is removed from the page to exit the featurewx.setStorageSyncMethod, which synchronously sets up the local cache and, from the name of the key, caches the mock interface and template data.

The pageInit method is defined as follows

// Page initialization
pageInit () {
  // Initialize the mock list
  this.initList()
  / / add RequestHooks
  this.addRequestHooks()
},
Copy the code

This method does two things, initializing the mock list and adding RequestHooks, which are examined in turn

initList()

// Initialize the mock list
initList () {
  const that = this
  const opt = {
    url: `${mockBaseUrl}/api/app/interface`.method: 'GET'.data: { projectId: this.getProjectId(), isfull: 1 }
  }
  that.request(opt).then(res= > {
    const { data } = res.data
    if(data && data.datalist && data.datalist.length) { that.updateMockList(data.datalist) that.updateTplList(data.datalist) }  }).catch() },/ / get projectId
 getProjectId () {
   if (!this.data.projectId) {
     console.warn("You have not set projectId yet, go to the quick platform to experience it: https://www.dokit.cn")
     return
   } else {
     return this.data.projectId
   }
 },

// Construct the Promise object
request (options) {
  return new Promise((resolve, reject) = >{ app.originRequest({ ... options,success: res= > resolve(res),
      fail: err= > reject(err)
    })
  })
},
Copy the code

Lines 4-8 set an object constant opt. The property URL is a backquoted template string, where ${mockBaseUrl} has previously been set to a constant with a value of “mock.dokit.cn”, which is the dokit platform address. The getProjectId method is called in the initialization of the property data, which is defined in line 18. Although projectId is a component property, it is also accessed through this.data and its value is passed in the page where we introduce the Dokit tool. If not, the console outputs a warning and returns; Returns the value of the property if passed. The structure of the opt object looks very much like the object passed in when using the wx.request method, and the following analysis will confirm this conjecture.

Lines 9-15 invoke a Request method, defined on line 28, that constructs and returns a Promise object. Before moving on, it’s worth a brief introduction to what promises are. In my opinion, promises are a means of controlling asynchronous operations to achieve synchronization, avoiding layers of nested callback functions and executing a series of asynchronous operations in the desired order.

To learn more about Promise, visit

Blog.csdn.net/zzh990822/a…

www.liaoxuefeng.com/wiki/102291…

What is the difference between the then second argument in a Promise and the catch argument blog.csdn.net/gogo_steven…

Line 31 app.originRequest is set at the beginning of the js file (not shown in this article) with a value of wx.request. Why not use wx.request directly? Because the ApiMock component works by overwriting the wx. Request method, you need to save it beforehand if you want to ensure that the normal Wx. Request method is still available at all times.

Going back to lines 9-15, if we already understand how Promise works, we can figure out what this code means — take our projectId and send a request to the Dokit platform side interface that should return mock information based on projectId that we set up on the platform side, After ensuring that the request was successful and returned, the returned data is validated and, if valid, the relevant methods are invoked to update the MockList data. The order of execution here is important, and this is where promises come in. It’s worth noting that the catch method on line 15 does not have a callback for passing in exception handling. I think it would be nice to have one to make the program more robust.

.catch((err) = >{
  console.log(err)
})
Copy the code

addRequestHooks()

Hooks are the act of adding additional flow control to an already-functioning program. In plain English, that is, intercepting specific messages, handling them in your own way, and then releasing them.

addRequestHooks () {
  Object.defineProperty(wx,  "request" , { writable:  true });
  console.group('addRequestHooks success')
  const matchUrlRequest = this.matchUrlRequest.bind(this)
  const matchUrlTpl = this.matchUrlTpl.bind(this)
  wx.request = function (options) {
    const opt = util.deepClone(options)
    const originSuccessFn = options.success
    const sceneId = matchUrlRequest(options)
    if (sceneId) {
      options.url = `${mockBaseUrl}/api/app/scene/${sceneId}`
      console.group('request options', options)
      console.warn('Intercepted.')
    }
    options.success = function (res) {
      originSuccessFn(matchUrlTpl(opt, res))
    }
    app.originRequest(options)
  }
},
Copy the code

Line 2 object.defineProperty, which we analyzed earlier, adds or modifies a property to the Object, in this case setting wx.request to allow the assignment operator to change. Bind (this), which ensures that when both methods are called later, this in the function body refers to the current component object.

Bind () creates a function in which the value of this object is bound to the value of the first argument to bind(), for example, f.bind(obj), which is essentially obj.f(), and this in f naturally points to obj.

Lines 6-19 are correctwx.requestRewrite, line 9 is to requestoptionsThe incomingmatchUrlRequestIn, returns onesceneIdOverwrite the request if the value is not nulloptionsThe URL in the dokit platform side is an andsceneIdRelated interface, and rewritten after console outputoptionsInformation, lines 15-17 rewrite the requestoptionsIn thesuccessThe callback function (analyzed below), line 18 calls the original saved wechat request method, which is now passed the modified oneoptions.It’s possible to speculate here,matchUrlRequestThe method should match the request we would have sent to the list of mock interfaces and, if successful, return the Id of the scenario previously selected for the mock interface. Looking at the rewritten URL, we can confirm that the Dokit platform determines what data to respond to based on the scene Id. To be specific,matchUrlRequestMethods are defined as follows

// Matches the URL request
matchUrlRequest (options) {
  let flag = false, curMockItem, sceneId;
  if (!this.data.mockList.length) { return false }
  for (let i = 0,len = this.data.mockList.length; i < len; i++) {
    curMockItem = this.data.mockList[i]
    if (this.requestIsmatch(options, curMockItem)) {
      flag = true
      break; }}if (curMockItem.sceneList && curMockItem.sceneList.length) {
    for (let j=0,jLen=curMockItem.sceneList.length; j<jLen; j++) {
      const curSceneItem = curMockItem.sceneList[j]
      if (curSceneItem.checked) {
        sceneId = curSceneItem._id
        break; }}}else {
    sceneId = false
  }
  return flag && curMockItem.checked && sceneId
},
  
// judge url is match
requestIsmatch (options, mockItem) {
  const path = util.getPartUrlByParam(options.url, 'path')
  const query = util.getPartUrlByParam(options.url, 'query')
  return this.urlMethodIsEqual(path, options.method, mockItem.path, mockItem.method) 
  && this.requestParamsIsEqual(query, options.data, mockItem.query, mockItem.body)
},
Copy the code

Line 3 declares three variables: flag records whether a match is successful, curMockItem records the mock interface information, and sceneId records the sceneId. Lines 5-11 loop through the mock list, where the real match is the requestIsmatch method on line 7, defined in line 26. By looking at the method names called in line 7, you can roughly guess what the match is based on: request path, request method, query parameter, request body. Return to lines 12-24, if mock information is successfully matched, continue to check which scene is selected under the mock interface. The selected sceneId is stored in sceneId. Line 23 is written to return the value of sceneId if flag and curmockitem. checked are true. Otherwise return false.

MatchUrlTpl (opt, RES) matchUrlTpl(opt, RES

matchUrlTpl (options, res) {
  let curTplItem,that = this
  if(! that.data.tplList.length) {return res }
  for (let i=0,len=that.data.tplList.length; i<len; i++) { curTplItem = that.data.tplList[i]if (that.requestIsmatch(options, curTplItem) && curTplItem.checked && res.statusCode == 200) {
      that.data.tplList[i].templateData = res.data
    }
  }
  wx.setStorageSync('dokit-tpllist', that.data.tplList)
  return res
},
Copy the code

In a nutshell, what this method does is, if the request matches the list of mock interfaces, save the data RES returned by the successful request as a template in local storage, and then return the RES as normal to continue with the original SUCCESS callback.

conclusion

At this point, the core code of the data Mock function has been analyzed. The basic principle of the data Mock function is to rewrite the wx.request method and match the request to the mock interface set by the user before sending the request. If the match is successful, the request information (THE URL and the successful callback function) is modified before sending the request.

conclusion

This is the first time for me to try to read and analyze the code of open source project, and I have learned a lot in this process. I would like to thank my DoKit project teachers and classmates for their guidance and help. Since my understanding of applets and JavaScript is just getting started, I feel free to correct any errors in this article.

2021/4/27

The author information

Author: Top scholar in seven provinces

Original link: juejin.cn/post/695578…

Source: Nuggets