It’s been a long time since the first one was published, because this one really stepped in a lot of holes.. In the future, try not to create a new project, just like a flag T T

The main contents of this paper are as follows

  • To use vue-router, you may need to know the base attribute in addition to the mode attribute
  • The choice of hash and History modes
  • About how to handle wechat authorization
  • How to dance in chains under domain name restrictions

To use vue-router, you may need to know the base attribute in addition to the mode attribute

First of all, introduce the background of the project, without the background to talk about the needs are blind, this activity page is independent of the main site project (SPA) of the new independent project, but due to the strong reliance on wechat, the new project still needs to be hung under the main domain name.

The domain name is m.kurisu. FM /my(yes, the domain name is m.kurisu. This is a fake domain name) all this path is directly pointing to the vUE project directory, very perfect running, this is also a wechat security domain name, so login should also be safe. But here’s the thing… It can’t pay… The domain name is not an affordable domain name, so we have to change the domain name.

FM /pay/:id, so I have to ask my colleague to help me set up a path of M.kurisu. FM /pay/my. Ok, after restart, it’s cold. A blank screen, static resources are loaded, #app is mounted, but router-view is not displayed. What the hell is this? Looking at the vue-Router documentation, I found this thing – the application base path which means we should change the configuration of the router

let link = ' '

if (window.location.host === 'm.kurisu.fm') {
  link = '/pay/my'
}

export default new Router({
  base: link, // Set the base path of the application here
  /* if window.location.host === 'm.kiurisu. FM', the route will change the path '/' to '/pay/my'. If this is not configured, the router will still match the route '/'. Users will not be able to access the page */
  routes: [
    {
      path: '/'.name: 'JXGlobal'.component: JXGlobal
    },
    {
      path: '/auth'.component: Auth
    }
  ]
})
Copy the code

After the modification, we can happily carry out the following development ~ but also can run the various functions of wechat online [indifference]

The choice of hash and History modes

When it comes to router, it is necessary to discuss mode. I want to talk about both modes because they are used in development. In the end, I conclude that hash routing is strongly recommended

Although I still used the history mode in the end, due to the historical reasons of the project, I still used the history mode in this development. The specific reasons will be explained in the following section.

Hash Routing

Vue-router default hash mode — Uses the URL hash to simulate a full URL, so that the page does not reload when the URL changes.

When you use this pattern, you will see a very strange ‘#’ in the URL, but there is nothing wrong with this pattern except that it is a little ugly. Especially when running single page application on wechat, it is the choice of conscience.

But why didn’t I end up with this model? Next, I would like to talk about the reasons for my choice based on the reality of the project

The root cause is that a maximum of 3 authorized payment directories can be configured, and the path depth cannot be greater than 2 levels. After hash is used, there will be ‘#/’ after our URL, which leads to the problem of matching directories in wechat pay. After the test, wechat seems to judge the path hierarchy based on ‘/’, so if ‘#/’ is used, it means that there is a natural path layer missing. After weighing up, we still give up using the hash mode

Routing in History mode

The introduction of History routing is a bit of a hoot, but it relies on a new HTML5 API called History. pushState.

For a variety of reasons (see Hash section above) I chose history mode to run this project, and there were some bumps along the way.

Because the project is mainly running on wechat, in general, the pit is that wechat JSSDK is not satisfactory for the single-page application compatibility

  • If you use JSSDK on Android and iOS, you may find that there are some differences in the performance between the two systems, such as the judgment of the initial location, the same URL will have different results when paying…
    • On iOS, wechat does not change the current href according to history.pushState. This can cause many problems, such as copying links incorrectly, authorization may not succeed, payment may be problematic; On Android, there’s no problem. The solution is relatively rough, in the iOS system, to determine the need to interact with wechat JSSDK page is forced to refresh to ensure the normal interaction.

    • When testing payment, I found an interesting phenomenon. When I adjusted the payment, which worked well on iOS, it died on Android. In Android, the payment is up, but the final payment popup doesn’t appear. The payment parameters on both ends are exactly the same, what’s the problem? After struggling for a long time, I still found the answer on the Internet. Android does not allow the url to end with ‘/’, otherwise the payment will not be able to be adjusted properly

Wechat authorization processing mode

Since the router has two modes, there are some differences in processing, but generally the same.

First of all, it is better to have a separate page (component) to handle authority-related events, because in the actual development situation there may be multiple different avenues of authorization at the same time, and having a separate page helps us to decouple from the main business.

Redirect_uri must be whitelisted domain name, otherwise it is not normal to initiate authorization.

With a normal redirect to the specified URL, congratulations, you’ve taken a big step toward 1 percent authorization processing. Redirect url with code(&state…) , we just need to take this code to the back end to request the login data.

At this step, the two routing modes are handled slightly differently.

  • In history mode, we can get the relevant parameters directly from $route.query, and then proceed with the following request. This is not a separation of authorization, but in this case, I did have a separate authorization page, which was a bit of a dig. The first is the usage of router.push. At the beginning of the test, we could come back from the authorized wechat page smoothly, but it did not move after coming back, that is, we did not request the login interface, nor redirect back to the original page. Later, I found that the code was washed out, and the culprit was my own router.push, and I didn’t take the parameters in the push. Another thing to note is that after the authorization is completed, it is best to use window.location.href to skip back to the original page, which can avoid some JSSDK holes in the iOS system.

  • In the hash mode, we don’t need to avoid all the problems as in the History mode, but here we find that we can’t get the parameters we want with $route.query, because after we jump back from wechat, our URL will look like this: m.kirisu.fm /? Code =1234#/ Did you find a problem? ‘#/’ = ‘#/’; $route = ‘#/’; $route = ‘#/’;

function urlQuery2Object (search) {
  let result = {}
  search.split('? ') [1].split('&').forEach(function (part) {
    let item = part.split('=')
    result[item[0]] = decodeURIComponent(item[1])})return result
}
Copy the code

How to dance in chains under domain name restrictions

Due to the limitation of the path to initiate payment, the secondary page of the active page or even the home page cannot have an exclusive layer of routing. How to solve this problem? The quickest solution is to use route.query and watch to monitor route to achieve page switching.

The final url is m.Kurisu.fm /pay/my? : ID &: SID Where ID is the ID of this activity (there may be multiple activities using the same set of pages at the same time) and SID is the child activity page under each activity.

<div class="container__content" v-if="activity_init">
    <keep-alive>
        <jx-index :f_content="init_data" v-if=! ""$route.query.sid"></jx-index>
        <jx-subpage v-else></jx-subpage>
    </keep-alive>
</div>
Copy the code

On the page display, we only need to determine whether the page has a SID to know which template to display, and then listening for $route only needs to be done in the template of the child active page.

watch: {
    // Listen for changes in $route
    '$route' (to, from) {
        if(to.query.sid && (to.query.sid ! = =from.query.sid)) {
            // For the cache of sub-active pages, if there is a cache, the cached data is preferentially used, and new data is requested silently (without loading toast) to optimize the page experience
            if (window.sessionStorage.getItem(String(to.query.id) + String(to.query.sid))) {
                let data = window.sessionStorage.getItem(String(to.query.id) + String(to.query.sid))
                this.column = JSON.parse(data)
                this.page_init = true
                this.GetData(false)}else {
                this.GetData(true)}}}}Copy the code

conclusion

This series of articles is mainly a record of some solutions in the actual development process, this article is mainly around the routing related issues and wechat compatibility in the problem, hope to help you and I avoid the pit in the future.

The articles

  • Vue Development Activity page – Portal one
  • React, a homemade music player for mobile
  • Talk about the React – componentWillReceiveProps use