Subscribe on changes!

Allow exposing variables with a private prefix (_)

avatar
Feb 14th 2023

What problem does this feature solve?

In a component library I want to expose some refs for use by other internal components, but mark it as private for consumers of the library. The JS convention is to prefix properties like this with _:

setup () {
  const somePrivateProperty = ref()
  return {
    _somePrivateProperty: somePrivateProperty
  }
}

This works, but vue logs

setup() return property "_somePrivateProperty" should not start with "$" or "_" which are reserved prefixes for Vue internals. 

Related: #4532, #5038

What does the proposed API look like?

Rename vue's internal properties to __ instead, which is already used in a few places (__hmrId, __asyncLoader, __v_isVNode, __isBuiltIn, __isScriptSetup)

avatar
Feb 16th 2023

Have you considered using expose()?

avatar
Feb 20th 2023

expose() isn't type safe. I wasn't aware expose allowed prefixed keys, is there a reason setup return is treated differently?

avatar
Feb 20th 2023

simplified: setup returns are exposed as part of "this", where also Vue's _internal properties live. the objects returned by ?expose() doesn't expose internals (its whole point is only to expose what you told it to).

expose() isn't type safe.

True, would be a better way to fix your issue though if we fix that?

avatar
Feb 20th 2023

Fair enough, I don't use this anymore so I forgot that was a thing. It doesn't actually appear to use _ though apart from this._ for ComponentInternalInstance, and #4570 only mentions this._ not any value starting with _.
Would changing the check from key[0] === '_' || key[0] === '$' to key === '_' || key[0] === '$' actually break anything?

I don't know if it's possible to make expose() type safe unless you run vue-tsc on every .ts(x) file and convert it into return internally like is done for defineExpose in script setup.