【问题标题】:Vue3 - Table not updating after deleting an array item, need to refresh the page to see effectVue3 - 删除数组项后表格不更新,需要刷新页面才能看到效果
【发布时间】:2022-01-16 13:52:46
【问题描述】:

当我删除其中一个元素时,我的表格没有更新。

我的 Vue 页面:

<template>
    <div class="home">
        <div class="py-10">

            <header>
                <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <h1 class="text-3xl font-bold leading-tight text-gray-900">Items</h1>
                </div>
            </header>
            <main>
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
          <div class="flex flex-col">
            <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                <div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
                    <div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
                    <table class="min-w-full divide-y divide-gray-200">
                        <thead class="bg-gray-50">
                        <tr>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Name
                            </th>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Hostname
                            </th>
                            <th scope="col" class="relative px-6 py-3">
                                <span class="sr-only">Actions</span>
                            </th>
                        </tr>
                        </thead>
                        <tbody>
                            <tr v-for="(item, index) in items.value" :key="index" :class="index % 2 === 0 ? 'bg-white' : 'bg-gray-50'">
                                <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ item._source.name }}</td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ item._source.hostname }}</td>
                                <td class="px-6 py-4 whitespace-nowrap text-right text-sm">
                                    <div class="flex flex-row-reverse">
                                        <div @click="deleteItem(item._id)" class="px-1 text-red-600 hover:text-red-900">
                                            <TrashIcon class="h-5 w-5"/>
                                        </div>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                        
                </table>
                </div>
            </div>
            </div>
        </div>
        </div>
      </main>

        </div>
    </div>
</template>

<script>
import { ref } from '@vue/reactivity'
import { TrashIcon } from '@heroicons/vue/outline'
import ItemsService from '../../services/items.service'
export default {
    name: 'ReadItems',
    components: {
        TrashIcon,
    },
    data(){
        return {
            items: ref([]),
        }
    },

    async mounted(){
        this.items.value = await this.readItems()
    },

    methods: {
        async readItems(){
            let temp = null
            try {
                temp = await ItemsService.readItems()
                temp = temp.data.body.hits.hits
            } catch (error) {
                console.log('Error: could not retrieve all items.')
            }
            return temp
        },

        async deleteItem(itemId){
            await ItemsService.deleteItem({ _id: itemId })
            await this.readItems()
        }
    }
}
</script>

当我运行deleteItem 方法时,我需要重新加载页面才能看到该项目消失了。我想看到它而不必重新加载页面...

【问题讨论】:

    标签: javascript vuejs3 vue-reactivity


    【解决方案1】:

    不要在选项 API 的数据函数中使用组合 API 中的ref,这里的数据已经是响应式的:

    const app = Vue.createApp({
      data() {
        return {
          items: [],
        };
      },
      async mounted(){
        this.items = await this.readItems()
      },
      methods: {
        async readItems(){
          let temp = null
          try {
            // setTimeout emulates async call
            setTimeout(() => this.items = [{_id: '1', _source: {name: 'aaa', hostname: 'aaa'}}, {_id: '2', _source: {name: 'bbb', hostname: 'bbb'}}, {_id: '3', _source: {name: 'ccc', hostname: 'ccc'}}], 2000)
            //temp = await ItemsService.readItems()
            //temp = temp.data.body.hits.hits
          } catch (error) {
            console.log('Error: could not retrieve all items.')
          }
          return temp
        },
        async deleteItem(itemId){
          // setTimeout emulates async call
          setTimeout(() => this.items = this.items.filter(i => i._id !== itemId), 1000)
          //await ItemsService.deleteItem({ _id: itemId })
        }
      }
    })
    app.mount('#demo')
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" integrity="sha512-wnea99uKIC3TJF7v4eKk4Y+lMz2Mklv18+r4na2Gn1abDRPPOeef95xTzdwGD9e6zXJBteMIhZ1+68QC5byJZw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <script src="https://unpkg.com/vue@next"></script>
    <div id="demo">
      <div class="home">
        <div class="py-10">
          <header>
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
              <h1 class="text-3xl font-bold leading-tight text-gray-900">Items</h1>
            </div>
          </header>
          <main>
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
              <div class="flex flex-col">
                <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                  <div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
                    <div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
                      <table class="min-w-full divide-y divide-gray-200">
                        <thead class="bg-gray-50">
                          <tr>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                              Name
                            </th>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                              Hostname
                            </th>
                            <th scope="col" class="relative px-6 py-3">
                              <span class="sr-only">Actions</span>
                            </th>
                          </tr>
                        </thead>
                          <tbody>
                            <tr v-for="(item, index) in items" :key="index" :class="index % 2 === 0 ? 'bg-white' : 'bg-gray-50'">
                              <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ item._source.name }}</td>
                              <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ item._source.hostname }}</td>
                              <td class="px-6 py-4 whitespace-nowrap text-right text-sm">
                                <div class="flex flex-row-reverse">
                                  <div @click="deleteItem(item._id)" class="px-1 text-red-600 hover:text-red-900 cursor-pointer">
                                    <!--<TrashIcon class="h-5 w-5"/>-->
                                    delete
                                  </div>
                                </div>
                              </td>
                            </tr>
                         </tbody>
                      </table>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </main>
        </div>
      </div>
    </div>

    【讨论】:

    • 感谢您的解决方案。这是否意味着对于这种过程,我总是需要运行一个“并行”脚本过滤(在这种情况下)数组?
    • @Henri 嘿伙计,不,您可以跳过过滤本地项目,而是在删除后直接调用 this.readItems()
    猜你喜欢
    • 2014-07-16
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多