Vuex-class绑定v-model时searchPhrase无Setter赋值报错问题解决
Vuex接入搜索栏时报错「计算属性无setter」的问题与修复
初始实现与报错现象
我们开发的是支持用户输入内容实时筛选角色列表的搜索栏功能,初始实现代码如下:
<!-- 组件模板部分 --> <input class="form-control" type="text" placeholder="Search" v-model="searchPhrase" /> <Character v-for="character in resultSearching" :key="character.id" :photo="character.image" :characterID="character.id" :name="character.name" :gender="character.gender" :species="character.species" :lastEpisode="character.episode[character.episode.length - 1].episode" :character="character" /> <!-- 组件脚本部分 --> <script lang="ts"> import { Vue, Component } from "vue-property-decorator"; import Character from "./Character.vue"; import { CharactersApiI } from "@/models/models"; import { Getter } from "vuex-class"; @Component({ components: { Character }, }) export default class Characters extends Vue { @Getter("characters/getCharacters") characters!: CharactersApiI[]; @Getter("characters/getLoading") loading!: boolean; @Getter("characters/getError") error!: boolean; @Getter("characters/getSearchPhrase") searchPhrase!: string; @Getter("characters/getHeaders") headers!: string[]; get resultSearching(): any { return this.characters.filter((character) => { return character.name .toLowerCase() .match(this.searchPhrase.toLowerCase()); }); } set resultSearching(newValue: any) { this.searchPhrase = newValue.target.value.toLowerCase(); } } </script>
实际运行时,只要在输入框中输入内容,就会立刻触发报错:Computed property "searchPhrase" was assigned to but it has no setter,搜索筛选功能完全失效。
报错根因
- 通过
vuex-class的@Getter装饰器映射的Vuex状态,本质是仅带getter逻辑的只读计算属性,没有内置的setter方法,直接对这类属性赋值会直接触发运行时错误 - Vuex的核心规则要求:所有对全局状态的修改,都必须通过触发对应模块的Mutation完成,禁止在组件内直接修改映射的只读状态
- 原代码中存在两处不符合规则的赋值:
- 给输入框直接绑定
v-model="searchPhrase",输入内容时Vue会自动尝试给searchPhrase赋值,触发只读报错 - 在
resultSearching计算属性的setter中直接修改searchPhrase,本质还是在组件内直接改Vuex状态,违反单向数据流规则
- 给输入框直接绑定
最终可运行的修复方案
1. 在Vuex的characters模块新增更新搜索词的Mutation
所有对searchPhrase状态的修改,统一在Mutation中完成:
// characters.ts 模块代码 @Mutation updateMessage(e: { target: { value: string } }) { this.searchPhrase = e.target.value; }
2. 调整组件内的绑定逻辑
去掉原代码中对只读searchPhrase的v-model绑定,改用单向值绑定+事件触发的模式,通过调用Mutation的方式更新全局状态:
// characters.vue 组件脚本代码 export default class Characters extends Vue { // 原有只读的Getter映射保持不变 @Getter("characters/getCharacters") characters!: CharactersApiI[]; @Getter("characters/getSearchPhrase") searchPhrase!: string; // 新增映射模块内的Mutation方法 @Mutation("characters/updateMessage") updateMessage!: (e: { target: { value: string }; }) => void; // 筛选逻辑仅保留getter即可 get resultSearching(): CharactersApiI[] { return this.characters.filter((character) => { return character.name .toLowerCase() .match(this.searchPhrase.toLowerCase()); }); } // 新增输入事件处理函数,通过触发Mutation更新状态 handleInput(e: { target: { value: string } }) { this.updateMessage(e); } }
对应的模板部分输入框调整为:value="searchPhrase" @input="handleInput",保证整个数据流单向流转,不再出现只读赋值的报错。
内容的提问来源于stack exchange,提问作者Goteii
相关产品推荐
相关产品推荐

