在加载的数据填充工作表之前,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-loader和v-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在应用程序启动时加载其他功能之前运行功能并等待数据
Delphi在提取数据填充到Grid上面总是一行行的闪烁加载、如何解决?