【问题标题】:How to disable a vuejs router-link?如何禁用 vuejs 路由器链接?
【发布时间】:2020-08-07 07:46:24
【问题描述】:

我有一个使用 vue 创建的单页应用程序,导航链接全部使用 router-link 标签完成。导航中有几项我的老板想在导航中添加但已禁用,以便人们可以一睹即将推出的一些功能。但是我不知道如何完全禁用路由器链接!

preventDefault 什么都不做,@click.native.prevent="stopClick()" 什么都不做(我尝试将它发送到一个函数以查看是否会阻止点击,但它只是调用函数和路由,尽管阻止),添加一个 disabled 类并设置 pointer-events: none; 的 css 规则什么都不做。我不确定还有什么可以尝试的,这是使禁用的链接成为正常文本而不是路由器链接的唯一方法吗?

【问题讨论】:

    标签: javascript vue.js vue-router routerlink


    【解决方案1】:

    今天仍然没有原生解决方案。但是在 vue-router repo 上有一个公开的 PR:https://github.com/vuejs/vue-router/pull/2098

    一种解决方法是使用:

    <router-link 
      :disabled="!whateverActivatesThisLink" 
      :event="whateverActivatesThisLink ? 'click' : ''"
      to="/link"
    >
      /link
    </router-link>
    

    【讨论】:

    【解决方案2】:

    你可以使用

    <router-link 
      :is="isDisabled ? 'span' : 'router-link'"
      to="/link"
    >
      /link
    </router-link>
    

    【讨论】:

      【解决方案3】:

      我认为这个问题没有合适的解决方案,因为路由器链接没有disabled 属性,但一个技巧是使用tag="button" 来添加所需的属性,如下所示:

      <router-link 
           to="/link"
           tag="button"
           :disabled="true"
      >
        Link
      </router-link>
      

      【讨论】:

      • 那是因为router-link呈现为html锚标签,而&lt;a&gt;也不支持禁用属性。添加tag="button" 将使routerlink 呈现为按钮,因此该按钮自然可以与:disabled 一起使用。
      【解决方案4】:

      没有内置任何东西,probably won't ever be。也就是说,对我来说最有用的是使用 CSS。

      <router-link to="/my-route" :class="{ disabled: someBoolean }" />
      
      .disabled {
          opacity: 0.5;
          pointer-events: none;
      }
      

      不透明度使它看起来被禁用,pointer-events: none; 使它看起来如此你不需要处理:hover 样式,或设置cursor 样式。

      【讨论】:

        【解决方案5】:

        方法一:阻止点击事件

        诀窍是在捕获阶段处理事件并阻止它向上传播。

        <router-link 
          to="/path"
          @click.native.capture.stop
        >
          Go to page
        </router-link>
        

        或者强制:

        <router-link 
          to="/path"
          @click.native.capture="handleClick"
        >
          Go to page
        </router-link>
        
        function handleClick(event) {
          if (passesSomeCheck) event.stopPropagation();
        }
        

        如果您想从 Vue Router 获取解析的路径以在没有 SPA 导航的情况下强制页面加载,这可能非常有用。

        function handleClick(event) {
          if (loadWithoutSpa) {
            event.stopPropagation();
            window.location.href = event.currentTarget.href;
          };
        }
        

        方法二:将默认事件改为空字符串

        <router-link 
          to="/path"
          event
        >
          Go to page
        </router-link>
        

        方法3:使用&lt;a&gt;标签

        <a :href="$router.resolve(route).href">
          Go to page
        </a>
        

        路由可以与您传递给router-link 上的to 道具的东西完全相同。

        【讨论】:

        • 使用 event.preventDefault() 而不是 event.stopPropagation() 为我禁用了路由器链接
        • 我不会推荐它,因为事件将不再传播,例如不会触发全局事件监听器。
        【解决方案6】:

        只需设置to="" 然后链接就不会去任何地方。

        【讨论】:

          【解决方案7】:

          您可以为每个路由设置路由保护

          const router = new VueRouter({
            routes: [
              {
                path: '/foo',
                component: Foo,
                beforeEnter: (to, from, next) => {
                  //here you can set if condition 
                  if (conditionTrue) {
                    //redirect to other route
                    next({path: '/bar'});
                  } else {
                    next();
                  }
                }          
              }
            ]
          })
          

          或者你可以全局设置

          routes: [
            {path: '/foo', component: Foo, meta:{conditionalRoute: true}}
          ]; 
          
          router.beforeEach((to, from, next) => { 
              if (to.matched.some(record => record.meta.conditionalRoute)) { 
                  // this route requires condition/permission to be accessed
                  if (!checkCondition ) { 
                      //check condition is false
                      next({ path: '/'});
                  } else { 
                      //check condition is true
                      next();
                  } 
              } else { 
                  next(); // Don't forget next
              } 
          })
          

          更多信息: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

          【讨论】:

            【解决方案8】:

            你可以试试:

              <router-link
               :event="whateverActivatesThisLink ? 'click' : ''"
              >
              Go to page
              </router-link>
            

            或者使用计算编写更简洁的代码:

              <router-link
              :event="handleWhatEverEvent"
              >
              Go to page
              </router-link>
            
            computed: {
              handleWhatEverEvent() {
                return this.whateverActivatesThisLink ? 'click' : '';
              }
            }
            

            【讨论】:

              【解决方案9】:

              为了防止点击,您可以像这样直接访问 router-link 元素的事件属性(您可以使用原生点击来做其他事情):

              <router-link 
              :event="clickable ? 'click' : ''" 
              @click.native="!clickable ? doOtherThing : ''" > Link </router-link>
              

              【讨论】:

                【解决方案10】:

                路由器 v4 更新:

                使用boolean 变量status 来确定链接是否处于活动状态,并将链接 (ctalink) 作为变量传递。

                偶然发现这里来自 nuxt-link 实现与更新中断,因此根据经验,这同样适用。

                    <router-link
                      v-slot="{ navigate }"
                      :to="ctalink"
                      custom
                    >
                      <div @click="status ? navigate(ctalink) : null">
                        <div :class="status ? 'text-green' : 'text-gray'"> 
                          Click me when active 
                        </div>
                      </div>
                    </router-link>
                

                来源:https://next.router.vuejs.org/api/#router-link-s-v-slot

                【讨论】:

                  【解决方案11】:

                  NuxtLink(Vue 路由器 v4)

                  对我来说,下面的代码很有吸引力。这是我在应用程序中使用nuxttailwind 的真实代码。

                                <nuxt-link
                                  v-slot="{ navigate }"
                                  :to="`lesson/${lesson.lesson_id}`"
                                  append
                                  custom
                                >
                                  <button
                                    class="focus:outline-none"
                                    :class="{
                                      'text-gray-500 cursor-default': !lesson.released,
                                    }"
                                    :disabled="!lesson.released"
                                    @click="navigate"
                                  >
                                    {{ lesson.title }}
                                  </button>
                                </nuxt-link>
                  

                  【讨论】:

                    【解决方案12】:

                    使用 div 元素或 span 元素代替 结合@click事件

                    <div @click="handleRouteNavigation">
                    your content..
                    </div>
                    

                    在脚本方法中定义

                    handleRouteNavigation(){
                    
                      if(conditionSatisfied){
                          this.$router.push('/mylink')
                       }
                    
                    }
                    

                    【讨论】:

                      【解决方案13】:

                      由于我必须使用 &lt;router-link&gt; 和自定义属性(并向路由添加自定义元数据),我能够像这样解决它:

                      <router-link :to="route.path"
                                        custom
                                        v-slot="{href, route, navigate, isActive, isExactActive}">
                                      <a v-bind="$attrs"
                                      :href="href"
                                      @click="checkClick($event, navigate, route.meta)">
                                      ...
                                      <slot></slot>
                                  </a>
                      </router-link>
                      

                      然后是函数

                      checkClick(event: any, navigate: any, meta: { enabled: boolean }) {
                                  if (meta.enabled) {
                                      navigate(event);
                                      return;
                                  }
                                  event.preventDefault();
                              },
                      

                      【讨论】:

                        猜你喜欢
                        • 2021-10-02
                        • 2018-02-15
                        • 2023-04-09
                        • 2019-05-11
                        • 2023-04-01
                        • 2018-02-04
                        • 2018-04-22
                        • 2020-08-30
                        • 2021-10-28
                        相关资源
                        最近更新 更多