静默更新url而不触发vue-router中的路由

Rin*_*nux 7 vue.js vue-router

我需要更新url的哈希,而无需实际触发vue-router转到该路由。诸如此类的东西:

router.replace('my/new/path', {silent:true})
Run Code Online (Sandbox Code Playgroud)

这会将url更新为.../#/my/new/path,但是路由器本身不会路由到该路径。

是否有一种优雅的方法来实现这一目标?

Man*_*piK 26

无需重新加载页面或刷新 dom,history.pushState即可完成这项工作。
在你的组件或其他地方添加这个方法来做到这一点:

addHashToLocation(params) {
  history.pushState(
    {},
    null,
    this.$route.path + '#' + encodeURIComponent(params)
  )
}
Run Code Online (Sandbox Code Playgroud)

因此,在您的组件中的任何位置,调用addHashToLocation('/my/new/path')以在 window.history 堆栈中使用查询参数推送当前位置。

要将查询参数添加到当前位置而不推送新的历史条目,请history.replaceState改用。

应该适用于 Vue 2.6.10 和 Nuxt 2.8.1。  

这种方法要小心!
Vue Router 不知道 url 发生了变化,所以在 pushState 之后不反映 url。

  • 要将此方法与动态 URL 结合使用,您可以使用 `resolve()` 方法: `const { href } = this.$router.resolve(route); window.history.pushState({}, null, href);` (2认同)

Sum*_*ai8 6

Vue 路由器要么打开要么关闭,所以你不能“让它不检测某些 url”。也就是说,如果 Vue 不需要销毁组件并允许您为 url 设置别名,那么它确实会重用组件。这允许您将 iframe 应用程序中的 url 作为路由中的别名,并在此期间保持相同的组件处于活动状态,防止重新加载 iframe。

// router.js
import Comp1 from "./components/Comp1";
import Comp2 from "./components/Comp2";

export default [
  {
    path: "/route1",
    component: Comp1,
    alias: ["/route2", "/route3", "/route4"]
  },
  {
    path: "/otherroute",
    component: Comp2
  }
];
Run Code Online (Sandbox Code Playgroud)
// main.js
import Vue from "vue";
import App from "./App";
import VueRouter from "vue-router";
import routes from "./router";

Vue.config.productionTip = false;
Vue.use(VueRouter);

const router = new VueRouter({
  routes
});

/* eslint-disable no-new */
new Vue({
  el: "#app",
  router,
  components: { App },
  template: "<App/>"
});
Run Code Online (Sandbox Code Playgroud)

在此示例中route1route2route3route4都将被视为route1必须加载,从而使您的组件Comp1保持活动状态。

编辑 Vue 模板

  • 我不明白这是如何回答这个问题的。如果 iframe 内的 url 发生变化,则没有用于更新父窗口 url 的代码。如果父窗口 url 更改,则没有用于更新 iframe 路由器的代码。 (5认同)

Tom*_*rae 6

如果您想要做的是更新 url 以显示页面状态(可能类似于?search=something),那么您可以执行这样的技巧。关键思想是使用切换this.respondToRouteChanges来忽略代码更新 url 时的更改。

更新路由时(例如,在组件中的 vue 方法中)

          this.respondToRouteChanges = false;
          this.$router.replace({query: { search: this.search })
              .finally(() => {
                this.respondToRouteChanges = true;
              });
Run Code Online (Sandbox Code Playgroud)

以及通常监视/处理路线更改的组件代码中

    setSearch() {
      if (!this.respondToRouteChanges){
        // console.log('ignoring since route changes ignored')
        return;
      }
      if (this.search !== this.querySearch)
        this.search = this.querySearch;
    },

Run Code Online (Sandbox Code Playgroud)
  watch: {
     // watch for changes in the url
    'querySearch': 'setSearch',

Run Code Online (Sandbox Code Playgroud)

请注意,这respondToRouteChanges只是data()组件中定义的布尔值

  data() {
    return {
      respondToRouteChanges: true,
      ...
Run Code Online (Sandbox Code Playgroud)

querySearch只是一个返回路线的计算值

    querySearch() {
      return this.$route.query.search || '';
    },
Run Code Online (Sandbox Code Playgroud)