vuejs / vue-router

🚦 The official router for Vue 2
http://v3.router.vuejs.org/
MIT License
18.99k stars 5.06k forks source link

Manual change of hash into the URL doesn't trigger the route in IE11 #1849

Open Aymkdn opened 7 years ago

Aymkdn commented 7 years ago

Version

3.0.1

Reproduction link

https://codepen.io/Aymkdn/pen/MENZPx

Steps to reproduce

  1. Use IE11
  2. Open codepen at https://codepen.io/Aymkdn/pen/MENZPx
  3. Click on "Open demo"
  4. Click on "Go to foo" or click on "Go to bar" to see it works correctly
  5. Manually change the hash into the URL from the IE11 address bar (for example replace "#/foo" with "#/bar")

What is expected?

The component to be loaded based on the current hash into the URL

What is actually happening?

The changes are not detected under IE11. It works with Firefox.


When the page is already opened and I want to copy/paste a link into the same page which has the same url but a different path/hash

Aymkdn commented 6 years ago

In the meantime, I use this workaround:

if ('-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style) { // detect it's IE11
  window.addEventListener("hashchange", function(event) {
    var currentPath = window.location.hash.slice(1);
    if (store.state.route.path !== currentPath) {
      router.push(currentPath)
    }
  }, false)
}
arcadeJHS commented 6 years ago

Thanx for the suggestion!

yuxizhe commented 6 years ago

same problem when using location.href='...'

learn from @Aymkdn

if (checkIE()) {
      window.addEventListener('hashchange', () => {
        var currentPath = window.location.hash.slice(1)
        if (this.$route.path !== currentPath) {
          this.$router.push(currentPath)
        }
      }, false)
   }
Aymkdn commented 6 years ago

Where i have to put the code example above? Anywhere after your Vue script. It's an "independant" code, but you need to make sure router and store are already defined.

If you use the code from @yuxizhe I think it's added into the mounted of the Vue.

margokopli commented 6 years ago

I think this is related to IE issue #3740423 https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3740423/

ghost commented 6 years ago

I also have something similar happening to me in IE and also in FF but all good in Safari and Chrome.

I'm having a problem with router.push not appending the correct locale in the url for example: mydomain.com/en. I have a Store set up in Nuxt and a plugin with my logic. I also have nuxt-i18n module installed:

My Store Logic

import Vuex from 'vuex'

const store = () => new Vuex.Store({

    state: {
        locales: ['en', 'de', 'cn', 'es', 'pt'],
    },

    mutations: {

        setLocale(state, locale) {
            if (state.locales.indexOf(locale) !== -1) {
                this.app.i18n.locale = locale;
            }

My Plugins logic with various console logs to output data:

export default async ({ app, store, commit, route }) => {

    // Only run on client-side
    if (process.server) return;

    console.log('BEFORE MUTATION: ' + app.i18n.locale);  // 'en' is default
    app.router.push(app.i18n.locale) ; // Works and appends to url '/en'. Works in all browsers
    store.commit('setLocale', 'es');  // Manually setting to es
    console.log('AFTER MUTATION: ' + app.i18n.locale); // es
    app.router.push(app.i18n.locale);  // Does not work in FF or IE resolves to '/' after mutation. Works fine in Chrome

}

Why would router.push not function like expected after passing in app.i18n.locale after it's been updated/mutated?

I also passed into the 2nd and 3rd arguments for router.push to see what's going on:

await store.commit('setLocale', 'es'); // Manually setting to es
    console.log('AFTER MUTATION: ' + app.i18n.locale); // es
    await app.router.push(
        app.i18n.locale,
        console.log('onComplete: ' + app.i18n.locale), //onComplete: es
        console.log('onAbort: ' + app.i18n.locale) // onAbort: es
    ); 
zanedev commented 6 years ago

@andrade1379 did you ever figure this out? I'm having a similar issue where somes routes aren't loading on FF or IE but everything else is fine.

aj-flynn commented 6 years ago

Using the workaround by @Aymkdn I ran into 2 issues. Where to put the code and I had an issue that required me to press the browser back button twice. I used mounted() to add the event handler and changing from .push to .replace fixed the back button issue.

new Vue({
    router: Router,
    mounted() {
        var app = this;

        if ("-ms-scroll-limit" in document.documentElement.style && "-ms-ime-align" in document.documentElement.style) { 
            window.addEventListener("hashchange",
                function () {
                    var currentPath = window.location.hash.slice(1);
                    if (app.$route.path !== currentPath) {
                        app.$router.replace(currentPath);
                    }
                },
                false);
        }
    }
});
binhphanduc commented 6 years ago

I faced the same issue. And also, hashchange didn't trigger when changing url by clicking on url.

zifnab87 commented 6 years ago

This still happened for me with version vue 2.5.17, vue-router 3.0.1 - I used this code (with minor changes from @yuxizhe and @Aymkdn) in created() - it should work in mounted() too:

let app = {
    data: function () {
    },
    methods: {

    },
    mounted () {

    },
    created() {
        if ('-ms-scroll-limit' in document.documentElement.style 
            && '-ms-ime-align' in document.documentElement.style) { // detect it's IE11
            window.addEventListener("hashchange", (event) => {
                var currentPath = window.location.hash.slice(1);
                if (this.$route.path !== currentPath) {
                    this.$router.push(currentPath)
                }
            }, false)
        }
   }
}
zifnab87 commented 6 years ago

I faced the same issue. And also, hashchange didn't trigger when changing url by clicking on url.

I had the same issue with one of my links - I was using <a href="/#/..."> instead of router-link. Is it your case too?

rickysang commented 6 years ago

Same problem in old version Chrome. I tested in Chrome v52.

Krabi commented 5 years ago

Our company paid for external developers to fix that problem and made pull request to fix that. And that pull request is wayting ca 1 year and with no results!!! Pleas fix that problem. We have wery close to decision to migrate away from VueJS.

tje3d commented 5 years ago

Using browser back and forward buttons does not trigger route ( sometimes ) in latest chrome and firefox.

tje3d commented 5 years ago

Returning undefined in beforeEnter caused my issue :)

Not Works:

beforeEnter: (to, from, next) => {
    if (isGuest()) {
        router.push('/im');
        return;
    }

    return next();
},

Works:

beforeEnter: (to, from, next) => {
    if (isGuest()) {
        return next('/im');
    }

    return next();
},
posva commented 5 years ago

@tje3d that's actually a completely unrelated thing: you must call next in navigation guards