Nuxt项目v-show按日期隐藏过期文章不生效问题求解
修复方案
问题出在两个核心点:
- 指令优先级冲突:Vue 中
v-for优先级高于v-show,二者写在同一个DOM元素上时,v-show的显示判断逻辑会执行异常,无法正确给过期项添加display: none的隐藏样式,这是v-show不生效的直接原因。 - 日期比较逻辑不可靠:直接用ISO格式字符串做大小比较,只有当
article.eventDate严格为标准ISO 8601格式字符串时结果才准确,一旦活动日期存储格式为时间戳、YYYY/MM/DD类非标准格式字符串、Date对象,字符串比较的结果会完全错误,导致过期内容漏判。
另外你之前遇到「v-if控制的链接看不见但还能点击」的问题,本质是v-if绑定位置错误——你只给内部的nuxt-link标签加了判断,外层绑定了跳转事件的文章容器没有做控制,才会出现点到容器空白区域仍能跳转的情况,和v-if本身的逻辑无关。
推荐修复方式(从根源避免所有问题)
不要在模板层用v-show/v-if做单元素判断,直接用计算属性过滤出未过期的文章列表再渲染,DOM中不会存在任何过期内容节点,既不会浪费渲染性能,也完全不会出现隐藏元素可点击的问题。
模板部分代码
<div class="article" v-for="article in validArticles" :key="article.slug" > <!-- 文章内容、nuxt-link 按原有逻辑正常编写即可 --> </div>
JS部分代码
统一将日期转为时间戳(数字类型)做比较,彻底规避格式不一致导致的判断错误:
data() { return { // 存储当前时间的时间戳,不需要转ISO字符串 dateNow: Date.now() } }, computed: { validArticles() { return this.articles.filter(article => { // 无论活动日期存储的是时间戳、日期字符串还是Date对象,都统一转时间戳再比较 const eventTimestamp = new Date(article.eventDate).getTime() return eventTimestamp > this.dateNow }) } }
如果你坚持要用v-show的写法
必须把v-for移到外层无渲染的template标签上,和v-show拆分到不同层级,同时修正日期比较逻辑:
<template v-for="article in articles" :key="article.slug"> <div class="article" v-show="new Date(article.eventDate).getTime() > dateNow" > <!-- 文章内容 --> </div> </template>
注意这种写法会把所有过期文章的DOM节点都渲染到页面,只是通过CSS隐藏,性能差于计算属性过滤的方案,如果外层容器绑定了跳转事件,仍有可能出现误触问题,不推荐使用。
内容的提问来源于stack exchange,提问作者Andrew Mathieu
相关产品推荐
相关产品推荐

