Vue 3中每个v-for元素的单独转换

unhi4e5o  于 12个月前  发布在  Vue.js
关注(0)|答案(1)|浏览(97)

我有两个独立的(假设是因为它们有不同的键)v-for元素的div,在它们里面,有一个刷新按钮来更新相对div的健康状况。这就是为什么我用Tailwind CSS => 'animate-spin'在我的按钮上放了一个旋转动画。
问题是每当我点击其中一个div的刷新按钮时,尽管我为列表中的每个元素都有一个键值,但它会旋转两个刷新图标。我的预期行为是只旋转点击按钮的图标。

const list: Ref<Array<SomeType>> = ref([
    {
        name: 'Item 1',
        title: 'XXXXXX',
        healthCheck: true
    },
    {
        name: 'Item 2',
        title: 'XXXXXX',
        healthCheck: false
    }
])

字符串
我的refreshStatus函数:

const isStatusRefreshed: Ref<boolean> = ref(false)

const refreshStatus = async (name: string): Promise<void> => {
    isStatusRefreshed.value = true

    // Some request and according to response, I manipulate healthCheck field of relative object. 
    // Ex. item.healthCheck = response.status === 200
    
    isStatusRefreshed.value = false
}


HTML部分:

<li v-for="listItem in list" :key="listItem.name" :data-index="listItem.name" 
  class="col-span-1 flex flex-col divide-y divide-gray-200 rounded-lg bg-white text-center shadow-xl">
  <!-- Some other components.. --> 
        <button @click="refreshStatus(listItem.name)"
          :class="[!isStatusRefreshed ? '' : 'animate-spin', 'hover:cursor-pointer']">
                 <i class="bi bi-arrow-clockwise" style="line-height: 16px; font-size: 16px; color: rgb(112, 112, 112);"></i>
        </button>
  <!-- Some other components.. --> 
</li>


我也试着用Transition Group.来 Package 我的li,我错过了什么?

fnvucqvd

fnvucqvd1#

你没有理解isStatusRefreshed ref的行为。它的值对于迭代列表中的每个项目都是相同的。它的值独立于键控项目列表迭代,并且在v-for循环的所有迭代中都是相同的。
要只显示相关的按钮旋转,请考虑将isStatusRefreshed作为每个项目本身的变量:

const { ref, createApp } = Vue;

createApp({
  setup() {
    const list = ref([
      {
        name: 'Item 1',
        title: 'XXXXXX',
        healthCheck: true,
        isStatusRefreshed: false,
      },
      {
        name: 'Item 2',
        title: 'XXXXXX',
        healthCheck: false,
        isStatusRefreshed: false,
      }
    ]);

    const refreshStatus = async (listItem) => {
      listItem.isStatusRefreshed = true
      
      // Some request and according to response, I manipulate healthCheck field of relative object. 
      // Ex. item.healthCheck = response.status === 200
      await new Promise(resolve => {
        setTimeout(resolve, 1000);
      });
    
      listItem.isStatusRefreshed = false
    };

    return {
      refreshStatus,
      list,
    };
  }
}).mount('#app')

个字符
或者将isStatusRefreshed作为数组,每个元素对应一个元素:

const { ref, createApp } = Vue;

createApp({
  setup() {
    const list = ref([
      {
        name: 'Item 1',
        title: 'XXXXXX',
        healthCheck: true,
      },
      {
        name: 'Item 2',
        title: 'XXXXXX',
        healthCheck: false,
      }
    ]);
    
    const isStatusRefreshed = ref([]);

    const refreshStatus = async (name) => {
      isStatusRefreshed.value = isStatusRefreshed.value.concat(name);
      
      // Some request and according to response, I manipulate healthCheck field of relative object. 
      // Ex. item.healthCheck = response.status === 200
      await new Promise(resolve => {
        setTimeout(resolve, 1000);
      });
    
      isStatusRefreshed.value = isStatusRefreshed.value.filter(v => v !== name);
    };

    return {
      isStatusRefreshed,
      refreshStatus,
      list,
    };
  }
}).mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.8/vue.global.prod.min.js" integrity="sha512-4ahMvsCQ/SdOCggIPH0vNgGVaeOB4qlXgQkdYyXBtb420bCJ9TR1wE4+0mOOYEFxId4d3tLRj98j2a5dgspR4g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.3.5"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.1/font/bootstrap-icons.min.css" integrity="sha512-oAvZuuYVzkcTc2dH5z1ZJup5OmSQ000qlfRvuoTTiyTBjwX1faoyearj8KdMq0LgsBTHMrRuMek7s+CxF8yE+w==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app">
  <ul>
    <li
      v-for="listItem in list"
      :key="listItem.name"
      :data-index="listItem.name" 
      class="col-span-1 flex flex-col divide-y divide-gray-200 rounded-lg bg-white text-center shadow-xl"
    >
      <!-- Some other components.. --> 
      <button
        @click="refreshStatus(listItem.name)"
        :class="[!isStatusRefreshed.includes(listItem.name) ? '' : 'animate-spin', 'hover:cursor-pointer']"
      >
        <i class="bi bi-arrow-clockwise" style="line-height: 16px; font-size: 16px; color: rgb(112, 112, 112);"></i>
      </button>
      <!-- Some other components.. --> 
    </li>
  </ul>
</div>

的字符串

相关问题