Vuejs将类绑定到行然后隐藏/显示行?

Posted

技术标签:

【中文标题】Vuejs将类绑定到行然后隐藏/显示行?【英文标题】:Vuejs bind class to row then later hide/show the row? 【发布时间】:2018-05-31 23:19:32 【问题描述】:

我正在尝试创建一个表,用户可以在其中隐藏行,并在删除其他行时保持隐藏。

在我的html中,我在渲染表格时使用vuejs绑定一个类:

<tr v-for="item in mylist" :class="'noFruits': (item.fruits.length == 0)">

有一个用户复选框可以隐藏该类的行:

<label><input type="checkbox" v-model="showBlankFruits" @change="setBlankDisplay">Show Blank Fruits</label>

在我的 Vue 实例中,复选框执行一个方法来通过 jquery 隐藏/显示该类的行以附加 css 显示属性:

methods: 
  setBlankDisplay: function() 
    if (this.showBlankFruits) 
     $('.noFruits').css('display', '');
   else 
     $('.noFruits').css('display', 'none');
  
,

在我的jsfiddle 中,当用户删除一行时,隐藏的行会重新出现。我看到在这种情况下使用 jquery 附加样式并不好......有人对更好的方法有建议吗?

【问题讨论】:

vuejs 中有用于类/样式绑定的组件。 vuejs.org/v2/guide/class-and-style.html 【参考方案1】:

这是一个很好的例子,展示了声明式渲染的强大功能,而不是在组件中使用 DOM 操作。您遇到的问题是当 Vue 引擎重新呈现您的列表时,它不知道您在 setBlankDisplay 方法中对元素进行的手动操作。解决这个问题的方法是在视图本身的定义中使用组件逻辑,有点像您首先设置 noFruits 类。

所以,我建议你把setBlankDisplay去掉,换成方法:

itemDisplay(item) 
    if (item.fruits.length === 0 && !this.showBlankFruits) 
    return 'none';
  
  return '';
,

然后您可以在链接到 css display 属性的 tr 元素的定义中引用它,如下所示:

<tr v-for="item in mylist" :class="'noFruits': (item.fruits.length == 0)" :style="display: itemDisplay(item)">

我已经用这个修改更新了jsfiddle,显示当其他项目被删除时隐藏水果的状态仍然存在。

以此作为使用 jquery 更改视图状态的危险的一般示例。应尽一切努力根据组件逻辑定义整个视图。

【讨论】:

【参考方案2】:

不建议混合使用 Vue 和 jQuery,因为您几乎可以使用 Vue 完成所有事情,而且您不会遇到任何不知道其他库/框架在做什么的冲突操作。

如果 fruits 数组长度为真,即不为 ​​0,或者 showBlankFruits 为真,则以下将显示该行:

<tr v-for="item in mylist" v-show="item.fruits.length || showBlankFruits">

单击复选框时,以下内容将切换 showBlankFruits:

<label><input type="checkbox" v-model="showBlankFruits">Show Blank Fruits</label>

完整代码示例:

JSFiddle

【讨论】:

【参考方案3】:

你也可以这样写。 我已经完全使用了计算并删除了 jQuery 部分。 您必须将数据声明为函数而不是数据对象 (https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function)

您不需要调用 mounted 方法来设置初始状态。它已经用你的数据对象设置好了。 在您的代码中,您必须调用mounted,因为jQuery 只能在加载DOM 时隐藏结果。

new Vue(
  el: '#app',
  data() 
    return 
      showBlankFruits: true,
      mylist: [
        'user': 'Alice', 'fruits': ['name': 'apple'],
        'user': 'Bob', 'fruits': ['name': 'orange'],
        'user': 'Charlie', 'fruits': [],
        'user': 'Denise', 'fruits': ['name': 'apple', 'name': 'orange'],
      ]
    
  ,
  computed: 
    list() 
      return this.mylist.filter(item => (item.fruits.length > 0 && !this.showBlankFruits) || (item.fruits.length === 0 && this.showBlankFruits))
    ,
  ,
  methods: 
    delItem(item) 
      let index = this.mylist.indexOf(item);
      if (index > -1) 
        this.mylist.splice(index, 1);
      
    
  
)
<script src="https://unpkg.com/vue"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<div id="app">
  <label><input type="checkbox" v-model="showBlankFruits">Show Blank Fruits</label>
  <br> <br>
  <table>
    <tr> <th class="col">User</th> <th class="col">Fruits</th> <th class="col"></th> </tr>
    <tr v-for="item in list">
      <td> item.user </td>
      <td> <span v-for="f in item.fruits">  f.name  </span> </td>
      <td> <button @click="delItem(item)">Delete</button> </td>
    </tr>
  </table>
</div>

【讨论】:

比起@cstricklan 解决方案中的样式绑定,我更喜欢这样做。使用计算过滤数据使组件更具可测试性。 数据必须成为组件的函数。据我所知,对于根 Vue 实例,不“推荐”它是任何地方的函数。事实上,文档会引导您使用来自 very beginning 的对象。 我写了“推荐”,因为在这个例子中他使用的是单个实例,它不会破坏应用程序。但你是对的!我会更新我的答案。 过滤条件可以简化,item.fruits.length || this.showBlankFruits @LeeComstock 是的,你是对的,如果你想每次都显示完整的列表,无论是否有空水果。我坚持认为 Andrew 不能同时想要两者,因为复选框标签上写着“显示空白水果”而不是“显示空白水果”

以上是关于Vuejs将类绑定到行然后隐藏/显示行?的主要内容,如果未能解决你的问题,请参考以下文章

将类绑定到 TextField

VueJS 将类切换到表中的特定元素

Xamarin 如何将类属性(来自另一个项目)绑定到 Picker.ItemDisplayBinding 属性

将类绑定到 Vue.js 2 中的插槽

Dagger 和 Kotlin - 将类绑定到其泛型超类型的问题

html Vue将类绑定到v-for循环中的元素