在加载的数据填充工作表之前,Vue 如何在 v-card 中将文本作为占位符?

Posted

技术标签:

【中文标题】在加载的数据填充工作表之前,Vue 如何在 v-card 中将文本作为占位符?【英文标题】:Vue how to have text as a placeholder in a v-card before loaded data populates the sheet? 【发布时间】:2021-10-06 04:53:31 【问题描述】:

我在 vue 中有这张表格,我希望在用户实际点击某些内容以加载数据之前有一些占位符文本,例如“点击加载”。

目前我有这个按钮,它将用数据填充工作表:

      <v-btn @click="fetchData()"> Apply Filters </v-btn>

这是将加载从 fetchData() 返回的数据的工作表:

      <v-card
           THE DATA
      </v-card>

如何在单击按钮之前使工作表有一些占位符文本?

【问题讨论】:

简单的 THE_DATA 怎么样? THE_DATA : '没有数据...' 【参考方案1】:

除了 Kellen 的建议,您还可以使用骨架加载器。

这是我在 codepen 上找到的示例:

模板:

   <div id="app">
      <v-app>
        <v-content>
          <v-container class="grey lighten-4">
            <div class="text-center d-flex justify-center align-center mb-12 flex-wrap">
              <v-btn class="mx-12 my-4" @click="loading = !loading">
                Toggle
              </v-btn>
            </div>
    
            <v-row justify="center">
              <v-col class="mb-12" cols="12" md="4">
                <v-skeleton-loader 
                                   :loading="loading" 
                                   transition="scale-transition" 
                                   type="table-heading, list-item-two-line, table-tfoot">
                  <v-card>
                    <v-card-title>Title</v-card-title>
                    <v-card-text>Card Text</v-card-text>
                  </v-card>
                </v-skeleton-loader>
              </v-col>
            </v-row>
          </v-container>
        </v-content>
      </v-app>
    </div>

脚本:

// Looking for the v1.5 template?
// https://codepen.io/johnjleider/pen/GVoaNe

new Vue(
  el: '#app',
  vuetify: new Vuetify(),
  data: () => (
      loading: true,
  ),
)

来源: https://codepen.io/piiner123/pen/abbBOgO?editors=1010

【讨论】:

【参考方案2】:

如果用户尚未加载任何数据,您可以使用计算值返回一些占位符文本。这可能看起来像这样:

data() 
     dataFetched: false,
     data: ,
,
computed: 
     theData() 
          if (!dataFetched) 
               return 'placeholder text goes here'
          
          return data
     
,
methods: 
     async fetchData() 
         let data = await axios.get('/data')
         this.data = data.data
         this.dataFetched = true
    

【讨论】:

【参考方案3】:

引入一个status 数据元素,它可以根据组件的实际状态取不同的值。 最初,status 可能已“准备就绪”。在这种情况下,复制 v-card 并使用自定义字符串生成占位符:

<v-card>
  Click to load
</v-card>

当用户点击加载数据时,当你正在处理它时,设置status = 'loading'。这使您可以非常轻松地显示预加载器:

<div v-if="status === 'loading'">
  Loading data...
</div>

加载数据后,status 将变为 'loaded',然后您会显示带有数据的正确 v-card:

<v-card v-if="status === 'loaded'">
 data 
</v-card>

请注意,使用这种方法,如果数据加载失败,您也可以很容易地显示错误。只需将状态设置为“错误”并显示正确的消息。

这样做会使 html 非常明确,因为每个部分都有自己的 html 元素:data 变量仅用于显示实际数据,占位符文本有自己的元素,等等。

【讨论】:

【参考方案4】:

我使用v-skeleton-loaderv-if,最后使用watch查看数据状态。

<div id="app">
  <v-app id="inspire">
    <div>
      options
      <v-skeleton-loader v-if="firstLoad" :loading="loading" type="table">. 
      </v-skeleton-loader>
      <v-data-table 
        :headers="headers"
        v-show="!firstLoad"
        :items="desserts"
        :options.sync="options"
        :server-items-length="totalDesserts"
        :loading="loading"
        class="elevation-1"
      ></v-data-table>
    </div>
  </v-app>
</div>

脚本:

    new Vue(
      el: '#app',
      vuetify: new Vuetify(),
      data() 
        return 
          totalDesserts: 0,
          desserts: [],
          loading: true,
          firstLoad: true,
          options: ,
          headers: [
            
              text: 'Dessert (100g serving)',
              align: 'left',
              sortable: false,
              value: 'name',
            ,
             text: 'Calories', value: 'calories' ,
             text: 'Fat (g)', value: 'fat' ,
             text: 'Carbs (g)', value: 'carbs' ,
             text: 'Protein (g)', value: 'protein' ,
             text: 'Iron (%)', value: 'iron' ,
          ],
        ;
      ,
      watch: 
        options: 
          handler() 
            console.log('options watcher called');
            this.getDataFromApi()
              .then(data => 
                this.desserts = data.items;
                this.totalDesserts = data.total;
              );
          ,
          deep: true,
        ,
      ,
      methods: 
        getDataFromApi() 
          this.loading = true;
          return new Promise((resolve, reject) => 
            const  sortBy, sortDesc, page, itemsPerPage  = this.options;
    
            let items = this.getDesserts();
            const total = items.length;
    
            if ((sortBy && sortBy.length === 1) && (sortDesc && sortDesc.length === 1)) 
              items = items.sort((a, b) => 
                const sortA = a[sortBy[0]];
                const sortB = b[sortBy[0]];
    
                if (sortDesc[0]) 
                  if (sortA < sortB) return 1;
                  if (sortA > sortB) return -1;
                  return 0;
                 else 
                  if (sortA < sortB) return -1;
                  if (sortA > sortB) return 1;
                  return 0;
                
              );
            
    
            if (itemsPerPage > 0) 
              items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage);
            

        setTimeout(() => 
          if (this.firstLoad) this.firstLoad = false
          console.log('data is loaded');
          this.loading = false;
          resolve(
            items,
            total,
          );
        , 1000);
      );
    ,
    getDesserts() 
      return [
        
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        ,
        
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        ,
        
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        ,
       

      ];
    ,
  ,
);

【讨论】:

以上是关于在加载的数据填充工作表之前,Vue 如何在 v-card 中将文本作为占位符?的主要内容,如果未能解决你的问题,请参考以下文章

vue 3在应用程序启动时加载其他功能之前运行功能并等待数据

用 sqlalchemy 查询敲除填充表

Delphi在提取数据填充到Grid上面总是一行行的闪烁加载、如何解决?

如何使用 vue 和 vuefire 加载 Firebase 数据?

在 viewDidLoad 之前延迟表视图加载或加载数组?

Vue.js 在渲染组件之前填充数据