v-for和v-if在vue.js中无法一起使用

Sha*_*e G 7 radio-button vue.js v-for

表单用于提交文本,两个选项告诉vue在其中显示文本。选中col2单选按钮时,提交的文本应显示在第2列中。这没有发生,而是在第1列上显示了文本。

我有两个单选按钮,应将值“ one”或“ two”传递给newInfo.option。在子方法上,一个方法将表单数据推入数组“ info”。

<input type="radio" id="col1" value="one" v-model="newInfo.col">
<input type="radio" id="col2" value="two" v-model="newInfo.col">
Run Code Online (Sandbox Code Playgroud)

此数据被正确地推送到数组“ info”,我可以对其进行迭代。我知道这是行得通的,因为我可以遍历一个数组,一个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>
Run Code Online (Sandbox Code Playgroud)

全vue.js代码是在github 这里

而且它在GH-网页运行这里

pxe*_*eba 44

来自Vue 文档

当它们存在于同一节点时,v-if 的优先级高于 v-for。这意味着 v-if 条件将无法访问 v-for 范围内的变量:


<!--
This will throw an error because property "todo"
is not defined on instance.
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo.name }}
</li>

Run Code Online (Sandbox Code Playgroud)

这可以通过将 v-for 移动到包装标签来解决(这也更明确):

<template v-for="todo in todos">   
  <li v-if="!todo.isComplete">
     {{ todo.name }}   
  </li> 
</template> 

Run Code Online (Sandbox Code Playgroud)

如果您不介意元素在 html 中保留为“display:none”,您可以将 v-show 与 v-for 结合起来

  • `&lt;template v-for="todo in todos"&gt;` 帮助了我!祝您度过愉快的一天! (3认同)
  • 带有 &lt;template v-for... 的选项是最好的! (2认同)

Dob*_*leL 9

为什么不使用计算属性的功能

computed: {
  infoOne: function () {
    return this.info.filter(i => i.col === 'one')
  },
  infoTwo: function () {
    return this.info.filter(i => i.col === 'two')
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,在每个列表上只需遍历其各自的属性即可,而无需检查。例

<ol>
   <li v-for="item in infoOne">{{item}}</li>
</ol>
Run Code Online (Sandbox Code Playgroud)

这里工作的小提琴

  • 这是官方 Vue 风格指南的 [advice](https://vuejs.org/v2/style-guide/#Avoid-v-if-with-v-for-essential),归类为“必备” (与“强烈推荐”、“推荐”或“谨慎使用”相反)。 (3认同)

inT*_*low 9

您还可以在模板中使用 JavaScript 来过滤 v-for 的数组元素。相反,v-for="item in infos"您可以将信息数组缩小到v-for="item in infos.filter(info => info.col === 'one')".

由于在回调中使用了 info,因此我将您的信息数组重命名为 infos 以提高我的建议的可读性。

<div class="row">
    <div class="col-md-6">
        <ol>
            <li v-for="item in infos.filter(info => info.col === 'one')">
                text: {{ item.text }}, col: {{ item.col }}
            </li>
        </ol>
    </div>
    <div class="col-md-6">
        <ol>
            <li v-for="item in infos.filter(({ col }) => col === 'two')">
                text: {{ item.text }}, col: {{ item.col }}
            </li>
        </ol>
    </div>
</div>

Run Code Online (Sandbox Code Playgroud)


vpa*_*ade 5

!从第二个 if 中删除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>
Run Code Online (Sandbox Code Playgroud)


Agu*_*hew 5

<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>
Run Code Online (Sandbox Code Playgroud)

  • 更好的解决方案是将模板与 li 交换。这样就可以避免空 li 元素。 (3认同)

小智 5

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

原始示例

原始循环

<li v-for="item in info" v-if="item.col==='one'">
  text: {{ item.text }}, col: {{ item.col }}
</li>
Run Code Online (Sandbox Code Playgroud)

建议重构

重构循环

<custom-li v-for="item in info" :visible="item.col==='one'">
  text: {{ item.text }}, col: {{ item.col }}
</custom-li>
Run Code Online (Sandbox Code Playgroud)

新组件

Vue.component('custom-li', {
  props: ['visible'],
  template: '<li v-if="visible"><slot/></li>'
})
Run Code Online (Sandbox Code Playgroud)