如何将Vuetify的v-rating评分值写入Firestore现有文档
Nuxt+Firestore 实现Vuetify表格行内评分功能修复方案
错误原因与修复点
1. 页面刷新报错原因(已翻译)
[Vue 警告]:属性校验失败:属性 "value" 类型错误,预期为 Number 类型,实际得到 Array 类型 组件位置: ---> <VRating> <VSimpleTable> <VData> <VDataTable> <Pages/subcontractorperformance.vue> 位于 pages/subcontractorperformance.vue <Nuxt> <VMain> <VApp> <Layouts/dashboard.vue> 位于 layouts/dashboard.vue <Root>
问题根因:所有行的v-rating组件都绑定了同一个全局rating变量,没有和当前行的文档数据绑定,初始值类型不符合v-rating的要求(需要数字类型)。
修复点:将v-model绑定为当前行item的rating属性,初始加载数据时给无评分的文档设置默认值0。
2. 提交评分报错原因(已翻译)
prebuilt-306f43d8-45d6f0b9.js?a6a6:188 未捕获(在 Promise 中)FirebaseError:无对应文档可更新:projects/bumiputera-contractor/databases/(default)/documents/registersubwork/vBxSMJvQtOc5x6s7mRc7 at new n (prebuilt-306f43d8-45d6f0b9.js?a6a6:188) ...后续堆栈省略
问题根因:updateInput方法参数接收逻辑错误,且文档id从不存在的this.editedItem变量中获取,导致拿到无效id,Firestore找不到对应文档。
修复点:修改@input事件传参逻辑,直接将当前评分值和行item传入更新方法,使用item自带的id作为文档更新的标识。
完整修复后代码
模板代码
<template> <div> <v-data-table dense :headers="headers" :items="subcontractorperformance" :options.sync="options" :loading="loading" class="elevation-1" > <template v-slot:[`item.rating`]="{ item }"> <div class="d-flex align-center justify-center"> <v-rating v-model="item.rating" color="yellow darken-3" background-color="grey darken-1" empty-icon="$ratingFull" half-increments hover @input="(val) => updateInput(val, item)" > </v-rating> </div> </template> <template v-slot:no-data> <v-btn color="primary" @click="initialize"> 重置 </v-btn> </template> </v-data-table> </div> </template>
JS代码
methods: { // 加载表格文档数据 initialize() { this.loading = true this.subcontractorperformance = [] firestore .collection('registersubwork') .get() .then((querySnapshot) => { querySnapshot.forEach((doc) => { const docData = doc.data() // 无评分时默认赋值0,避免v-rating类型错误 this.subcontractorperformance.push({ ...docData, id: doc.id, rating: docData.rating || 0 }) }) // 全部数据加载完成后再关闭loading this.loading = false console.log(this.subcontractorperformance) }) }, // 更新文档评分 updateInput(value, item) { const itemId = item.id console.log(itemId, value) firestore .collection('registersubwork') .doc(itemId) // 用set+merge兼容文档不存在的场景,也可以保留update按需选择 .set({ rating: value }, { merge: true }) .then(() => { console.log('评分更新成功', value, item); }) .catch(err => { console.error('评分更新失败', err) }) }, }
效果参考


内容的提问来源于stack exchange,提问作者user16136444
相关产品推荐
相关产品推荐

