代码之家  ›  专栏  ›  技术社区  ›  ofey

v-for和v-if在vue中不协同工作。js公司

  •  31
  • ofey  · 技术社区  · 8 年前

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

    我有两个单选按钮,可以将值“one”或“two”传递给newInfo。方法将表单数据推送到数组“info”中。

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

    此数据正被正确地推送到数组“info”,我可以对其进行迭代。我知道这是可行的,因为我可以遍历数组,一个控制台。记录其中的所有数据。所有提交的表单数据都在那里。

    接下来,我在模板中迭代该数组两次。一次获取信息。col==“one”和其他迭代应仅在信息显示时显示。列==“两”。我将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页面上运行 here

    8 回复  |  直到 8 年前
        1
  •  64
  •   DobleL    8 年前

    为什么不使用 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

        2
  •  7
  •   Agus Mathew    6 年前
    <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>
    
        3
  •  5
  •   vpalade    8 年前

    去除 ! 从第二个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>
    
        4
  •  4
  •   Rory Callaghan Cullen    5 年前

    如果出于某种原因,筛选列表不是一个选项,则可以同时使用这两个选项转换元素 v-for v-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>'
    })
    
        5
  •  3
  •   Mithsew    4 年前

    从…起 Vue docs :

    当它们存在于同一节点上时,v-if的优先级高于 v-用于。这意味着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>
    
    

    可以通过将v-for移动到包装标签(其中 也更加明确):

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

    如果您不介意在html中继续查看“显示:无” 您可以将v-show与v-for一起使用 没有任何问题。

        6
  •  2
  •   Raith    8 年前

    你的第二张支票是 !item.col==='two' 只有当它显示时才会显示 等于“2”。

    编辑:The!not运算符的绑定可能比===更紧密,因此将始终返回false。添加括号以控制应用程序的顺序。我说可能是因为这可能是我不熟悉的一点Vue魔术,而不是一个纯JavaScript表达式。

    我想你想去掉那个感叹号。还是为了成功 !(item.col==='one') 显示除“一”以外的任何值。

        7
  •  2
  •   Dazzle    6 年前
    <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;
       }
    }
    
        8
  •  1
  •   inTheFlow    4 年前

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

    由于回调中使用了信息,我将您的信息数组重命名为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 info.filter(info => info.col === 'two')">
                    text: {{ item.text }}, col: {{ item.col }}
                </li>
            </ol>
        </div>
    </div>