You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:10:29