显示每行项目 3 的列表并在点击时选择项目 - Vue.js

Posted

技术标签:

【中文标题】显示每行项目 3 的列表并在点击时选择项目 - Vue.js【英文标题】:Display list of items 3 per row and select items on click - Vue.js 【发布时间】:2021-12-27 16:49:11 【问题描述】:

我有两个任务:

    每行显示项目列表 3 个项目 添加一个input 字段,用于编辑当前选定元素中的title 字段(应通过单击进行选择)。

所以,我基于这个解决V-if inside v-for - display list of items in two columns 做了第一个任务,现在我的第二个任务选择方法有问题。它应该适用于每个项目,但单击时会从每个列表中选择一个项目,并且只能从第一个列表中进行编辑。我认为这个问题可能出在onItemClick(index) 方法中,但不知道为什么。 对此有何想法?

Vue.component('item-list', 
  template: '#item-list-template',
  data() 
    return 
      items: [
          title: 'item 1'
        ,
        
          title: 'item 2'
        ,
        
          title: 'item 3'
        ,
        
          title: 'item 4'
        ,
        
          title: 'item 5'
        ,
        
          title: 'item 6'
        
      ],
      activeIndex: -1,
      rowArray: []
    
  ,
  mounted()
      this.fakeFetchData();
  ,
  methods: 
    // new method from example solving
    fakeFetchData()
        var cloned = this.items.slice();
        while (cloned.length > 0) 
            let chunk = cloned.splice(0,3);
            this.rowArray.push(chunk);
          
    ,
    onItemClick(index) 
      this.activeIndex = this.activeIndex === index ? -1 : index;
    ,
    setActiveItemValue(event) 
      const foundItem = this.items[this.activeIndex];
      if (!foundItem) return;
      
      return this.items[this.activeIndex].title = event.currentTarget.value;
    
  ,
  computed: 
    activeItemValue() 
      return this.items[this.activeIndex]?.title ?? '';
    
  
);

Vue.component('item', 
  template: '#item-template',
  props: 
    isActive: Boolean,
    title: String
  
);

new Vue(
  el: '#app'
);
li.active 
  background-color: yellow;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <item-list></item-list>
</div>

<script type="text/x-template" id="item-list-template">
  <div>
    <input type="text" placeholder="Edit selected items" :value="activeItemValue" @input="setActiveItemValue" />
    <div class="items-col">
      <ul class="items-list" v-for="(row, rowIndex) in rowArray" :key="rowIndex">
        <item v-for="(item, i) in row" :key="i" :title="item.title" :isActive="activeIndex === i" @click.native="onItemClick(i)" />
      </ul>
    </div>
  </div>
</script>

<script type="text/x-template" id="item-template">
  <li class="item" :class=" active: isActive "> title </li>
</script>
<style>
    .items-list 
        display: flex;
    
</style>

【问题讨论】:

【参考方案1】:

我已经修改并将fakeFetchData()mounted 移动到内部computed 并修改了模板内部的v-for。看看吧

Vue.component('item-list', 
  template: '#item-list-template',
  data() 
    return 
      items: [
          title: 'item 1'
        ,
        
          title: 'item 2'
        ,
        
          title: 'item 3'
        ,
        
          title: 'item 4'
        ,
        
          title: 'item 5'
        ,
        
          title: 'item 6'
        
      ],
      activeIndex: -1,
      rowArray: []
    
  ,
  methods: 
    // new method from example solving
    onItemClick(index) 
      this.activeIndex = this.activeIndex === index ? -1 : index;
    ,
    setActiveItemValue(event) 
      const foundItem = this.items[this.activeIndex];
      if (!foundItem) return;
      
      return this.items[this.activeIndex].title = event.currentTarget.value;
    
  ,
  computed: 
    activeItemValue() 
      return this.items[this.activeIndex]?.title ?? '';
    ,
    fakeFetchData()

        // ********* Changes done below ************

        var cloned = this.items.map((item, index) =>  
           return title: item.title, id: index
        );
        this.rowArray = [];
        while (cloned.length > 0) 
            let chunk = cloned.splice(0,3);
            this.rowArray.push(chunk);
          
        return this.rowArray;

        // ******* End of changes ********
    ,
  
);

Vue.component('item', 
  template: '#item-template',
  props: 
    isActive: Boolean,
    title: String
  
);

new Vue(
  el: '#app'
);
li.active 
  background-color: yellow;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <item-list></item-list>
</div>

<script type="text/x-template" id="item-list-template">
  <div>
    <input type="text" placeholder="Edit selected items" :value="activeItemValue" @input="setActiveItemValue" />
    <div class="items-col">
      <ul class="items-list" v-for="(row, rowIndex) in fakeFetchData" :key="rowIndex">
        <!-- Changes done --><item v-for="item in row" :key="item.id" :title="item.title" :isActive="activeIndex === item.id" @click.native="onItemClick(item.id)" />
      </ul>
    </div>
  </div>
</script>

<script type="text/x-template" id="item-template">
  <li class="item" :class=" active: isActive "> title </li>
</script>
<style>
    .items-list 
        display: flex;
    
</style>

【讨论】:

非常感谢,完美运行! @IoannSulyma 太好了!如果它对您有用并且您很高兴-那么通常您会接受答案。这不仅会帮助其他人解决同样的问题,而且还意味着人们将来更有可能帮助您解决您遇到的任何其他问题。您可以在此处阅读有关接受的信息:***.com/help/accepted-answer

以上是关于显示每行项目 3 的列表并在点击时选择项目 - Vue.js的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 不显示下拉选择

离子项目行中具有不同宽度的多列

IDEA 创建Web项目并在Tomcat中部署运行

识别不同文本区域中的光标位置并在列表框中选择项目时插入文本

vue v-for循环每行显示三个盒子,每行最后一个盒子的竖线不显示

Vue.js v-for 循环绑定数组中的项目对象并在更改时更新