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

新手上路,请多包涵

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

有没有办法根据是否传入道具来启用或禁用 <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 的情况下做到这一点?

谢谢!

原文由 Michael Giovanni Pumo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 408
2 个回答

我有时会做这样的事情:

 <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="" 基于状态。 navigate 本身很烦人,因为它需要隐式的第一个参数才能工作。

我没试过,但你应该可以使用类似 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();
    });
},

原文由 agm1984 发布,翻译遵循 CC BY-SA 4.0 许可协议

假设您想要禁用锚标记,因为不可点击并且看起来已禁用,该选项正在使用 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);
 }

原文由 CuriousGuy 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题