v-for 和 v-if 在 vue.js 中不能一起工作

Posted

技术标签:

【中文标题】v-for 和 v-if 在 vue.js 中不能一起工作【英文标题】:v-for and v-if not working together in vue.js 【发布时间】:2018-08-02 16:03:18 【问题描述】:

一个表单用于提交文本和两个选项告诉 vue 在哪一列显示文本。当 col2 单选按钮被选中时,提交的文本应该显示在第 2 列。这不会发生,第 1 列的文本是显示。

我有两个单选按钮,它们应该将值“一”或“二”传递给 newInfo.option 在 submnit 上,一个方法将表单数据推送到数组“信息”。

<input type="radio" id="col1" value="one" v-model="newInfo.col">
<input type="radio" id="col2" value="two" v-model="newInfo.col">

这些数据被正确地推送到数组“信息”中,我可以遍历它。我知道这是有效的,因为我可以遍历数组,console.log 中的所有数据。所有提交的表单数据都在那里。

接下来我在模板中遍历这个数组两次。一次用于 info.col==="one",其他迭代仅应在 info.col==="two" 时显示。我正在同时使用 v-for 和 v-if,vue.js 文档说可以这样做,

https://vuejs.org/v2/guide/conditional.html#v-if-with-v-for

<div class="row">
            <div class="col-md-6">
                <ol>
                    <li v-for="item in info" v-if="item.col==='one'">
                        text:  item.text , col:  item.col 
                    </li>
                </ol>
            </div>
            <div class="col-md-6">
                <ol>
                    <li v-for="item in info" v-if="!item.col==='two'">
                        text:  item.text , col:  item.col 
                    </li>
                </ol>
            </div>
        </div>

完整的 vue.js 代码在 github here

它在 gh-pages here 上运行

【问题讨论】:

我遇到了同样的问题。这个link 解释了为什么它不起作用,你应该对数组和对象做什么 用 v-show 代替 v-if 怎么样?我知道该元素仍然存在,但它会被隐藏。 您可以在 v-for 指令中使用 javascript。例如,item in myFilter(info) 您提供的 Guid 链接还指出 v-if 的优先级高于 v-for。这意味着它会在 item 甚至有值之前尝试评估 item.col 【参考方案1】:

如果由于某种原因无法过滤列表,您可以将具有v-forv-if 的元素转换为组件,并将v-if 移动到组件中。

原始示例

原始循环

<li v-for="item in info" v-if="item.col==='one'">
  text:  item.text , col:  item.col 
</li>

建议重构

重构循环

<custom-li v-for="item in info" :visible="item.col==='one'">
  text:  item.text , col:  item.col 
</custom-li>

新组件

Vue.component('custom-li', 
  props: ['visible'],
  template: '<li v-if="visible"><slot/></li>'
)

【讨论】:

【参考方案2】:
<div class="row">
    <div class="col-md-6">
        <ol>
            <li v-for="item in info">
                <template v-if="item.col==='one'">
                    text:  item.text , col:  item.col 
                <template>
            </li>
        </ol>
    </div>
    <div class="col-md-6">
        <ol>
            <li v-for="item in info">
                <template v-if="!item.col==='two'">
                    text:  item.text , col:  item.col 
                <template>
            </li>
        </ol>
    </div>
</div>

【讨论】:

您应该对您的解决方案发表评论,以提供更多见解伴侣 :) “纯代码”答案不是很有趣 :) 更好的解决方案是用 li 交换模板。这样可以避免空的 li 元素。【参考方案3】:
<div v-for="item in items">

   <div v-if="checkThis(item.computeThisProperty)" />
   <div v-else />

</div>

methods: 
   checkThis(i) 
      return this[i];
   
,

computed: 
   myComputedProperty() 
      return this.$store.state.something ? true : false;
   

【讨论】:

【参考方案4】:

为什么不用Computed Properties 的力量呢?

computed: 
  infoOne: function () 
    return this.info.filter(i => i.col === 'one')
  ,
  infoTwo: function () 
    return this.info.filter(i => i.col === 'two')
  

然后在每个列表上迭代其各自的属性而无需检查。示例

<ol>
   <li v-for="item in infoOne">item</li>
</ol>

这里是工作fiddle

【讨论】:

很好的答案,并回答你的问题,因为我对 vue 很陌生,仍然有很多工作要做。但是谢谢,你的回答很有趣 很高兴我能帮上忙 这是官方 Vue 风格指南的 advice,被归类为“必需”(与“强烈推荐”、“推荐”或“谨慎使用”相对)。跨度> @DobleL 嘿,我绝对喜欢你的回答,我已经修改了它。我在每个列表项旁边添加了“删除”按钮,因此单击按钮时我从列表中删除了该索引。问题是我们从计算属性中迭代两个列表,基本上我们有重复的索引(查看列表项的打印,你会明白),所以它从错误的类别中删除了项目。我正在考虑解决这个问题的方法,但我必须同时使用 v-for 和 v-if ,这是不推荐的。您有什么建议或解决方案吗?提前致谢!这是我的fiddle【参考方案5】:

如果v-if="item.col==='two'",则从第二个删除!

最好你可以这样做(只迭代一次):

<div class="row" v-for="item in info">
            <div class="col-md-6">
                <ol>
                    <li v-if="item.col==='one'">
                        text:  item.text , col:  item.col 
                    </li>
                </ol>
            </div>
            <div class="col-md-6">
                <ol>
                    <li v-if="item.col==='two'">
                        text:  item.text , col:  item.col 
                    </li>
                </ol>
            </div>
        </div>

【讨论】:

啊!我现在看到了,谢谢,是的,你的方式意味着只迭代一次。非常感谢 实际上你的代码会错开行。不完全是我想要的。不过谢谢【参考方案6】:

您的第二次检查是!item.col==='two',并且只有当它等于“二”时才会显示。

编辑:! not 运算符可能比 === 绑定得更紧密,所以它总是返回 false。添加括号以控制应用程序的顺序。我说可能是因为它可能是我不熟悉的 Vue 魔法,而不是纯粹的 JavaScript 表达式。

我想你想删除那个感叹号。或者让它 !(item.col==='one') 显示除“一”以外的任何值。

【讨论】:

以上是关于v-for 和 v-if 在 vue.js 中不能一起工作的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js v-for中能不能嵌套使用v-if

Vue.js v-for中能不能嵌套使用v-if

在 Vue.js 中使用 V-for 和 V-if 在条件下显示 JSON 数据

Vue.js 从源码理解v-for和v-if的优先级的高低

Vue.js 从源码理解v-for和v-if的优先级的高低

在没有 v-if 和 v-for 的 Vue.js 中显示(添加、编辑)和删除多个列中的列表项