Vue.js中的条件<router-link>取决于prop值?

时间:2017-06-29 15:56:21

标签: vue.js vuejs2 vue-component

希望这是一个相当简单的问题/答案,但我在文档中找不到太多信息。

是否有办法启用或禁用<router-link>生成的锚点,具体取决于是否传入道具?

<router-link class="Card__link" :to="{ name: 'Property', params: { id: id }}">
  <h1 class="Card__title">{{ title }}</h1>
  <p class="Card__description">{{ description }}</p>
</router-link>

如果没有id传递给此组件,我想要禁用正在生成的任何链接。

有没有办法在不将内容加倍到v-if

的情况下执行此操作

谢谢!

5 个答案:

答案 0 :(得分:8)

假设您要禁用锚标记,因为无法点击并且看起来已禁用,该选项正在使用CSS。 isActive 应该通过检查prop id返回true。

<router-link class="Card__link" v-bind:class="{ disabled: isActive }" :to="{ name: 'Property', params: { id: id }}">
  <h1 class="Card__title">{{ title }}</h1>
  <p class="Card__description">{{ description }}</p>
</router-link>

<style>
 .disabled {
    pointer-events:none; 
    opacity:0.6;        
 }
<style>

如果您只想禁用导航,可以使用路线保护。

beforeEnter: (to, from, next) => {
            next(false);
 }

答案 1 :(得分:3)

我有时会做这样的事情:

<component
    :is="hasSubLinks ? 'button' : 'router-link'"
    :to="hasSubLinks ? undefined : href"
    :some-prop="computedValue"
    @click="hasSubLinks ? handleClick() : navigate"
>
    <!-- arbitrary markup -->
</component>

...

computed: {
    computedValue() {
        if (this.hasSubLinks) return 'something';
        if (this.day === 'Friday') return 'tgif';
        return 'its-fine';
    },
},

但是我基本上总是包裹路由器链接,因此您可以控制禁用状态,或者在呈现链接之前预先检查任何状态或道具,如下所示:

<template>
    <router-link
        v-slot="{ href, route, navigate, isActive, isExactActive }"
        :to="to"
    >
        <a
            :class="['nav-link-white', {
                'nav-link-white-active': isActive,
                'opacity-50': isDisabled,
            }]"
            :href="isDisabled ? undefined : href"
            @click="handler => handleClick(handler, navigate)"
        >
            <slot></slot>
        </a>

    </router-link>
</template>

<script>
export default {
    name: 'top-nav-link',

    props: {
        isDisabled: {
            type: Boolean,
            required: false,
            default: () => false,
        },

        to: {
            type: Object,
            required: true,
        },
    },

    data() {
        return {};
    },

    computed: {},

    methods: {
        handleClick(handler, navigate) {
            if (this.isDisabled) return undefined;
            return navigate(handler);
        },
    },

};
</script>

现在在我的应用程序中,我注意到@click="handler => handleClick(handler, navigate)"的某些组合在性能上会受到很大影响。

例如,这会非常缓慢地更改路线:

@click="isDisabled ? undefined : handler => navigate(handler)"

但是上面我完整的示例代码中的模式有效,并且没有性能问题。

通常,@click中的三元运算符可能非常简单,因此,如果遇到问题,不要立即放弃,请尝试多种不同的方式对谓词进行分叉或基于<component :is=""进行切换在状态上。导航本身是一个繁琐的工作,因为它需要隐式的第一个参数才能起作用。

我还没有尝试过,但是您应该可以使用Function.prototype.call()Function.prototype.apply()Function.prototype.bind()之类的东西。

例如,您可能可以做到:

@click="handler => setupNavigationTarget(handler, navigate)"

...

setupNavigationTarget(handler, cb) {
    if (this.isDisabled) return undefined;
    return this.$root.$emit('some-event', cb.bind(this, handler));
},

...

// another component
mounted() {
    this.$root.$on('some-event', (navigate) => {
        if (['Saturday', 'Sunday'].includes(currentDayOfTheWeek)) {
            // halt the navigation event
            return undefined;
        }

        // otherwise continue (and notice how downstream logic
        // no longer has to care about the bound handler object)
        return navigate();
    });
},

答案 2 :(得分:2)

如果您需要经常使用它,请考虑以下问题:

创建新组件

<template>
  <router-link
    v-if="!disabled"
    v-bind="$attrs"
  >
    <slot/>
  </router-link>

  <span
    v-else
    v-bind="$attrs"
  >
    <slot/>
  </span>
</template>

<script>
export default {
  name: 'optional-router-link',

  props: {
    params: Object,
    disabled: {
      type: Boolean,
      default: false,
    },
  },
};
</script>

可选,全局注册:

Vue.component('optional-router-link', OptionalRouterLink);

按以下方式使用它:

<optional-router-link
  :disabled="isDisabled"
  :to="whatever"
>
    My link
</optional-router-link>

答案 3 :(得分:1)

问题是router-link呈现为html锚标记,并且锚标记不支持disabled属性。但是,您可以将tag="button"添加到router-link

<router-link :to="myLink" tag="button" :disabled="isDisabled" >

Vue随后会将您的链接呈现为一个按钮,该按钮自然支持disabled属性。问题解决了!缺点是您必须提供其他样式以使其看起来像一个链接。但是,这是实现此功能的最佳方法,并且不依赖于任何pointer-events hack。

答案 4 :(得分:0)

您还可以使用以下内容:

<router-link class="Card__link" :to="id ? { name: 'Property', params: { id: id }} : {}">
  <h1 class="Card__title">{{ title }}</h1>
  <p class="Card__description">{{ description }}</p>
</router-link>

如果未定义id,则路由器不会将页面重定向到链接。