Subscribe on changes!

组件的属性不能包含 $

avatar
Feb 14th 2023

Vue version

3

Link to minimal reproduction

https://github.com/leivii/leivii.github.io

Steps to reproduce

// error occurs
<my-component $type="input" />
// my-component.vue
<script setup>
import { ref } from 'vue'

defineProps({
  $type: String,
})
</script>

<template>
  <component :is="$type"></component>
</template>

What is expected?

像vue2一样支持包含 $ 的属性。

我在维护一个低代码项目,通过 json schema 来描述组件的功能,其中包括 $id$type 等通用 prop,升级vue3之后,没有找到相应的解决方案,如果有的话请告知,不胜感激!

What is actually happening?

错误信息如下: DOMException: Failed to execute 'setAttribute' on 'Element': '$type' is not a valid attribute name. at patchAttr (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:6829:10) at patchProp (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:6960:5) at mountElement (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4512:11) at processElement (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4490:7) at patch (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4424:11) at patchKeyedChildren (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:5053:11) at patchChildren (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4991:11) at processFragment (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4727:9) at patch (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4420:9) at ReactiveEffect.componentUpdateFn [as fn] (http://127.0.0.1:5173/node_modules/.vite/deps/vue.js?v=a498f009:4908:9)

System Info

可以在任何系统浏览器重现。

Any additional comments?

No response

avatar
Feb 14th 2023

v3在设计上就是会判断是否以$开头,当不是以$开头才会去props当中获取数据

 if (key[0] !== '$') {
      const n = accessCache![key]
      if (n !== undefined) {
        switch (n) {
          case AccessTypes.SETUP:
            return setupState[key] 
          case AccessTypes.DATA:
            return data[key] 
          case AccessTypes.CONTEXT: 
            return ctx[key]  
          case AccessTypes.PROPS:
            return props![key]  // 这里获取props当中的数据
          // default: just fallthrough
        }
      }
avatar
Feb 14th 2023

这是 el.setAttribute('$type', val) 报错的。 可能vue2中是:el['$type'] = val

avatar
Feb 14th 2023

I think this is the same problem with https://github.com/vuejs/core/issues/7710 should not start with "$" or "_" which are reserved prefixes for Vue internals.

avatar
Feb 15th 2023

@code-ManL @edison1105 确实是 el.setAttribute 报错的,属性的任何位置包含 $ 符号都会导致报错,这对于我们之前的 v2 版本升级来说,真是个灾难啊 ):

avatar
Feb 15th 2023

@AlexVagrant 是的,谢谢! 对于低代码平台来说,我们需要把通用属性和用户自定义组件的属性做隔离,否则可能导致冲突,有没有备选方案? 我们做低代码的初衷是让业务和技术分离,我们在升级技术(如vue3)时,业务配置可以保持不变。 所以我暂能想到的是,在低代码组件中将 $type 等通用属性做转换,比如 LC_type,尽管这看起来有点丑。

Yes, thank you!

For low-code platforms, we need to separate the common props from the props of user-defined components, otherwise it may cause conflicts. Is there any alternative?

The original intention of making low code is to separate business and technology. When we upgrade technology (such as vue3), the business configuration can remain unchanged.

So what I can think of for the moment is that in the low code components, the common props such as' $type 'are converted, such as' LC_ Type `, although it looks a little ugly.