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 miniapp
Here 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
- Apimock — Data Mock functionality component
- Appinformation — App information viewing function component
- Back — a custom component used to return that is not a Dokit feature component and is used to return on other feature pages
- Debug – Main menu component that lists various Dokit features
- H5door — ANY door function component of H5
- Httpinjector — Requested an injection function component
- Positionsimulation — positionsimulation of functional components
- 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.type
It’s in WXMLdata-type
Attribute values. If the user clicks on a newer version feature, the one defined in this JS file will be calledonUpdate
Method (this method is analyzed below); If it is any other function, it is triggeredtoggle
Event with a detail object, which is then, as analyzed above, placed in the index pagebindtoggle
Listen and update according to the detail objectcurCom
Value, 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…
soonUpdate
The whole logic of the method is to check for a newer version and use it if it doesn’twx.showModal
The 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 calledonUpdateReady
A callback to remind the user to restart the new version of the application or call it if the download failsonUpdateFailed
In the callback (the source of the callback function content is empty, here I imitateonUpdateReady
Also 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
- 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/test
On the details page, you can also add multiple scenarios and set the return values for different scenarios. Here I have set two scenarios.Default
andScenario 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
- Simulate a network request
Add a button on the home page, when the button is clicked, to/test
The 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
- 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
- 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 use
pageInit
Method, which by its name is supposed to be an initialization method. - Called when the component is removed from the page to exit the feature
wx.setStorageSync
Method, 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.request
Rewrite, line 9 is to requestoptions
The incomingmatchUrlRequest
In, returns onesceneId
Overwrite the request if the value is not nulloptions
The URL in the dokit platform side is an andsceneId
Related interface, and rewritten after console outputoptions
Information, lines 15-17 rewrite the requestoptions
In thesuccess
The 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,matchUrlRequest
The 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,matchUrlRequest
Methods 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