The article continues above, Ways and skills of small programs nesting H5 (1)
4, Refresh the embedded H5 page of WEV view
1) Why should we refresh the embedded H5 page of WEV view?
Many business scenarios require developers to update the page data every time they open the page. It is relatively simple for native applets to update page data. It is usually handled in onshow. Each time they enter the onshow life cycle, they can directly call the interface to refresh the data. However, it is not so simple for applets to refresh page data by nesting H5 with web view components. Let me use the actual scene as an example.
We use three pages: home page, page A and page B. the three pages have different shells and nested different H5 pages.
Home page: page elements include banner diagram. Click banner diagram to enter activity description page A
Activity description page A: the elements of the page include the conditions that need to be met to participate in the activity, the number of people who get rewards, the list of participants who get rewards, and the button to participate in the activity
Activity details page B: the elements of the page include the main page of the activity and the button to return to the previous page
2) The conventional method has the problem of fallback twice
The user enters page B from page A. after B participates in the activity, the user returns to the previous page to page A. at this time, the user needs to refresh the page. We usually write this:
wxml file
<web-view src="{{src}}"></web-view>
// home page Page({ data: { }, onReady(){ setTimeout(()=> { // Click the simulation page to jump to the activity page A wx.navigateTo({ url: '/pages/A/A' }) }, 5000) } }) // page A Page({ /** * Initial data of the page */ data: { src: "" }, /** * Life cycle function -- monitor the completion of the first rendering of the page */ onReady: function () { setTimeout(()=>{ // Simulation Click to jump to the page B wx.navigateTo({ url: '/pages/B/B' }) }, 5000) }, /** * Life cycle function -- monitor page display */ onShow: function () { let t = +new Date(); this.setData({ src: `https://www.baidu.com?t=${t}` }) } }) // page B code Page({ /** * Initial data of the page */ data: { src: "" }, /** * Life cycle function -- listening for page loading */ onLoad: function (options) { this.setData({ src: `https://developers.weixin.qq.com/community/homepage` }) } })
After the above described process: home page → activity description page A → activity details page B → return to the previous page and return to activity description page A; At this time, we click the return button in the upper left corner. Our expected effect is to return to the home page, but the actual effect is that the H5 page nested in Web view is refreshed and does not return to the home page.
3) Trying to fix the problem will lead to other more serious problems
Try to solve this problem by modifying the code of page A as
<!--page A of wxml--> <view wx:if="{{src}}"> <web-view src="{{src}}"></web-view> </view> // page A Page({ /** * Initial data of the page */ data: { src: "" }, /** * Life cycle function -- monitor the completion of the first rendering of the page */ onReady: function () { setTimeout(()=>{ // Simulation Click to jump to the page B wx.navigateTo({ url: '/pages/B/B' }) }, 5000) }, /** * Life cycle function -- monitor page display */ onShow: function () { let t = +new Date(); this.setData({ src: `` }) this.setData({ src: `https://www.baidu.com?t=${t}` }) } })
After modifying the code, go through the process: home page → activity description page A → activity details page B → return to the previous page and return to activity description page A; Page A is found to be blank and the console reports an error: [render layer error] only one '< web view / >' can be inserted into A page
4) Hard work pays off, and finally find a perfect solution
After many attempts, it is found that it is feasible to hide web view (uninstall we bview) in onHide, and paste the code of all files
<!--Homepage wxml--> <view class="container"> </view> // home page Page({ data: { motto: 'home page' }, onReady(){ setTimeout(()=> { // Click the simulation page to jump to the activity page A wx.navigateTo({ url: '/pages/A/A' }) }, 5000) } }) <!--page A of wxml--> <view wx:if="{{src}}"> <web-view src="{{src}}"></web-view> </view> // page A Page({ /** * Initial data of the page */ data: { src: "" }, /** * Life cycle function -- monitor the completion of the first rendering of the page */ onReady: function () { setTimeout(()=>{ // Simulation Click to jump to the page B wx.navigateTo({ url: '/pages/B/B' }) }, 5000) }, /** * Life cycle function -- monitor page display */ onShow: function () { let t = +new Date(); this.setData({ src: `https://www.baidu.com?t=${t}` }) }, onHide: function () { this.setData({ src: `` }) } }) <!-- page B of wxml --> <web-view src="{{src}}"></web-view> // page B code Page({ /** * Initial data of the page */ data: { src: "" }, /** * Life cycle function -- listening for page loading */ onLoad: function (options) { // The page does not need to be refreshed, so write onLoad In the life cycle this.setData({ src: `https://m.mi.com/` }) } })
The page refresh scenario of Web view is very common and inseparable from our later chapters. Therefore, it is still described in detail. I hope it can help other developers.
5) Keep improving and streamline code
Combined with my previous articles, How do wechat applets rewrite the Page method? And the benefits of rewriting the Page method to developers We can make the code more concise: re the Page method and extract the code that unloads the web view in the onHide life cycle. If there are many pages that need the web view to refresh H5, it will greatly save our workload and code.
First, we need to define the page variables of Web view and their meanings
refreshSrc: if this variable is defined in the data of the page and used to render the web view, the page needs to be refreshed every time the page is opened; Note: for pages that do not need to be refreshed, do not define the src attribute of the rendered web view as the variable name
Streamlined code
app.js // app.js (function(){ // Applet original Page method let originalPage = Page; // Our custom Page method Page = function(config){ // todo Here we can process the configuration object // Continue to pass the configuration object to the applet Page method config.onHide = function(){ //If this variable is defined on the page and the variable has a value onHide The lifecycle sets the value to null if(this.data.refreshSrc){ this.setData({ refreshSrc: '' }) } } originalPage (config); } })(); App({ onLaunch() { }, globalData: { } }) <!--Homepage wxml--> <view class="container"> </view> // home page Page({ data: { motto: 'home page' }, onReady(){ setTimeout(()=> { // Click the simulation page to jump to the activity page A wx.navigateTo({ url: '/pages/A/A' }) }, 5000) } }) <!--page A of wxml--> <view wx:if="{{refreshSrc}}"> <web-view src="{{refreshSrc}}"></web-view> </view> // page A Page({ /** * Initial data of the page */ data: { refreshSrc: "" }, /** * Life cycle function -- monitor the completion of the first rendering of the page */ onReady: function () { setTimeout(()=>{ // Simulation Click to jump to the page B wx.navigateTo({ url: '/pages/B/B' }) }, 5000) }, /** * Life cycle function -- monitor page display */ onShow: function () { let t = +new Date(); this.setData({ refreshSrc: `https://www.baidu.com?t=${t}` }) } }) <!-- page B of wxml --> <web-view src="{{src}}"></web-view> // page B code Page({ /** * Initial data of the page */ data: { src: "" }, /** * Life cycle function -- listening for page loading */ onLoad: function (options) { // The page does not need to be refreshed, so write onLoad In the life cycle this.setData({ src: `https://m.mi.com/` }) } })
This part is also for many pages in the applet to refresh the H5 nested in the web view. If there are few pages similar to page A in the applet, this part can be ignored