通过下拉列表调整数组实现Firestore帖子排序,解决const只读报错
报错原因
- 你使用
const关键字声明了constraints变量,JavaScript中const声明的为常量,仅允许首次赋值时写入,后续整体重新赋值会触发只读属性的类型错误,这是你收到报错的直接原因。 - 逻辑设计存在核心问题:
selectPosts是单次执行的异步查询方法,执行完成后就已经返回了首次查询的结果,就算你修改了constraints和queryRef变量,也不会触发页面列表数据的重新加载,根本达不到切换排序刷新列表的效果。 - 额外缺陷:在数据层直接通过ID获取Vue组件内的DOM元素,会存在组件未渲染获取不到节点、多实例场景ID冲突、多次调用方法重复绑定监听事件等问题,不符合Vue的单向数据流规范。
修复方案
1. 修改下拉组件,通过事件传递选中的排序值
修改dropDonwList.vue,用Vue的双向绑定和事件机制传递排序参数,避免原生DOM操作:
<template> <div> <select v-model="sortType" @change="handleSortChange"> <option value="1" selected>按最新排序</option> <option value="2">按点赞数排序</option> </select> </div> </template> <script> export default { data() { return { sortType: '1' } }, methods: { handleSortChange() { // 将选中的排序类型抛出给父组件 this.$emit('sort-change', this.sortType) } } } </script>
2. 重构查询方法,将排序类型作为入参
修改firestore.dao.js中的selectPosts方法,移除内部的DOM监听逻辑,将排序类型作为参数传入,动态拼接查询条件:
async selectPosts (sortType = '1', {country, city, state, street} = {}) { const goodOrderByDir = 'desc' const dateOrderByDir = 'desc' const db = getFirestore() // 抽离公共过滤条件 const baseConstraints = [ where('visibility', '==', 'public'), where('country', '==', country), where('city', '==', city), where('state', '==', state), where('street', '==', street) ] // 根据传入的排序类型动态生成排序规则 const orderConstraints = sortType === '1' ? [orderBy('date', dateOrderByDir), orderBy('good', goodOrderByDir)] : [orderBy('good', goodOrderByDir), orderBy('date', dateOrderByDir)] const allConstraints = [...orderConstraints, ...baseConstraints] const queryRef = query(collection(db, 'posts'), ...allConstraints) const snapshot = await getDocs(queryRef) // 无需多余的Promise.all包裹,map直接返回结果即可 return snapshot.docs.map(item => { this._lastSelectPostsDoc = item return { ...item.data() } }) }
3. 父组件监听排序变化,重新触发查询
在引入下拉组件的父组件中,监听排序变化事件,调用重构后的selectPosts方法重新拉取数据更新列表:
<template> <div> <DropDonwList @sort-change="handleSortChange" /> <!-- 帖子列表渲染逻辑 --> <div v-for="post in postList" :key="post.id">{{ post.content }}</div> </div> </template> <script> import DropDonwList from './dropDonwList.vue' import postDao from './firestore.dao.js' export default { components: { DropDonwList }, data() { return { postList: [], // 你的地址查询参数,根据实际场景赋值 queryParams: { country: '中国', city: '上海', state: '上海市', street: '某某路' } } }, mounted() { // 初始化加载默认排序的帖子 this.loadPosts('1') }, methods: { async loadPosts(sortType) { this.postList = await postDao.selectPosts(sortType, this.queryParams) }, handleSortChange(sortType) { // 排序切换时重新拉取数据 this.loadPosts(sortType) } } } </script>
内容的提问来源于stack exchange,提问作者dkskfktldi
相关产品推荐
相关产品推荐

