Vue如何在Vuex中使用JavaScript类?正确实现方案是什么
问题解答
核心结论
- 不推荐在Vuex的state中直接存储JavaScript类实例:Vuex state设计为存储可序列化的纯数据对象,类实例的方法、访问器属性无法被Vue响应式系统正确处理,还会导致状态序列化(如本地持久化)、devtool状态回溯功能失效。
现有代码的错误点
- 变量名冲突:getter中
const ChatMessage = new ChatMessage(message, index, messages)写法覆盖了导入的ChatMessage类,直接导致实例化失败 - 调用逻辑错误:类中定义的是
isNewDay访问器属性,你调用了不存在的idNewDay()方法,自然无法返回正确结果 - 违规修改原state:在getter中直接修改state中的
message对象添加isNewDay属性,Vue2环境下新增属性不会触发响应式更新,也违反了Vuex「state仅能通过mutation修改」的规范
正确实现方案
getter的作用是派生状态,不需要修改原state,直接返回处理后的新数据即可,示例代码如下:
修正后的Getter代码
import { ChatMessage } from '~/classes/ChatMessage' import _ from 'lodash' export default { getChatMessages: (state) => { const sortedMessages = _.orderBy(state.messages, 'created_at', 'asc') // 映射生成新数组,不修改原state内容 return sortedMessages.map((message, index) => { // 实例名不要和类名重复,避免变量覆盖 const chatMessageIns = new ChatMessage(message, index, sortedMessages) // 合并原消息属性和计算出的isNewDay,返回普通对象保证响应式正常 return { ...message, isNewDay: chatMessageIns.isNewDay // 访问类的getter属性,不需要加括号调用 } }) }, }
可选优化
如果你需要复用ChatMessage类的多个方法,也可以直接返回类实例给组件使用,只要不把实例存回state就不会有问题:
return sortedMessages.map((message, index) => new ChatMessage(message, index, sortedMessages))
补充规范
Vuex state请始终只存纯JSON格式的数据,所有衍生逻辑、类逻辑都放到getter、组件或者单独的工具层处理,可避免绝大多数响应式异常问题。
内容的提问来源于stack exchange,提问作者Krosilo
相关产品推荐
相关产品推荐

