如何在Nuxt2+@nuxtjs/composition-api中实现Vue3 readonly嵌套对象效果
实现Nuxt2中Composition API的深层readonly(Vue3风格)
@nuxtjs/composition-api提供的readonly()本质是浅层实现,仅阻止修改对象的第一层属性,嵌套对象/数组的属性仍可被修改。要实现和Vue3一致的深层只读效果,可以自己封装一个递归处理的deepReadonly()函数,具体实现如下:
1. 封装deepReadonly函数
import { readonly, isReactive, isObject, isArray } from '@nuxtjs/composition-api' export function deepReadonly(target) { // 非响应式对象/非直接对象类型,直接返回readonly包装结果 if (!isReactive(target) || !isObject(target)) { return readonly(target) } // 处理数组:递归处理每个元素后转成readonly数组 if (isArray(target)) { const processedArr = target.map(item => deepReadonly(item)) return readonly(processedArr) } // 处理普通对象:遍历所有属性,递归处理后生成新对象再转readonly const processedObj = {} for (const key in target) { if (Object.prototype.hasOwnProperty.call(target, key)) { processedObj[key] = deepReadonly(target[key]) } } return readonly(processedObj) }
2. 使用示例
在组件的setup函数中,用deepReadonly包裹响应式对象:
import { reactive } from '@nuxtjs/composition-api' import { deepReadonly } from '@/utils/readonly' export default { setup() { const mutableState = reactive({ user: { name: 'Alice', address: { city: 'Shanghai' } }, tags: ['frontend', 'nuxt'] }) // 生成深层只读的响应式对象 const readonlyState = deepReadonly(mutableState) // 以下操作在开发环境会触发警告,生产环境静默失败(符合Vue3 readonly行为) // readonlyState.user.name = 'Bob' // 不允许 // readonlyState.tags[0] = 'backend' // 不允许 return { readonlyState } } }
关键说明
- 该函数会递归遍历目标对象的所有嵌套属性,将每一层都用
readonly()包裹,确保整个对象树都处于只读状态。 - 保留了响应式特性:和Vue3的
readonly一致,只读对象仍会响应源对象的变更,但自身无法被修改。 - 开发环境下,尝试修改只读属性会触发Vue的警告,生产环境则会忽略修改操作。
内容的提问来源于stack exchange,提问作者harunaga
相关产品推荐
相关产品推荐

