Using Vue-cli to create web component, how to pass objects?

problem description

web component created with Vue-cli, I need to pass the object into it

the environmental background of the problems and what methods you have tried

tried to pass the object directly, but the attribute value defaults to toString, causing web components to only get [Obejct Obejct]
because I believe there must be a good solution or other way to achieve the goal, so I don"t think too much time on string and attribute transformation.
also found a lot of information on the Internet, and there is really little information about it. No, no, no. _ (: bilateral "angular) _

related codes

/ / Please paste the code text below (do not replace the code with pictures)
< foo-my-name id= "id1" > < / foo-my-name >

< script >

document.querySelector("-sharpid1").setAttribute("my-object", {
    name1: "name1_123123213123",
    name2: "name2_456456546456",
});

< / script >

what result do you expect? What is the error message actually seen?

I expect to pass the object in. Web components always uses the default parameters, which is very uncomfortable

.
May.01,2022

foo-my-name components

export default {
    props: {
        params: {
            type: Object//Object,
            default: () => {}//
        }
    },
    created(){
        console.log(this.params)
    }
}

use

<template>
    <!-- myParamsfoo-my-name -->
    <foo-my-name :params="myParams"></foo-my-name>
</template>
<script>
    import FooMyName from './foo-my-name'
    export default {
        components: {
            FooMyName 
        },
        data(){
            return {
                myParams: {
                    name1: 'name1_123123213123',
                    name2: 'name2_456456546456'
                }
            }
        }
    }
</script>

web components should focus on the reuse of UI. If you want to deal with complex content, it is more appropriate for vue-cli to export to lib


document.querySelector('-sharpid1').setAttribute('params', '{
    "name1": "name1_123123213123",
    "name2": "name2_456456546456",
}');

just pass the json string in and convert it to use after receiving it

<script>
export default {
  name: 'app',
  props: {
    params: {
      type: String,
      default: ''
    },
  },
  data () {
    return {
      paramsObj:{}
    }
  },
  mounted(){
      this.paramsObj = JSON.parse(this.params)  
  },
  methods: {
    test(){
      console.log('',this.paramsObj)
    }
    }
}
</script>

it just happened to be messing with this today, and it took me a long time to come up with this method. Maybe you can't use it now, so leave it to future generations

.

provide bridge layer

export function createBeseComponent(vueInstance: VueConstructor, opts: BeseComponent) {
  const { name, coreTag: _coreTag, modelEvent = 'puiChange', valueProperty = 'value' } = opts;
  const coreTag = _coreTag ?? name;
  return vueInstance.component(name, {
    model: {
      event: modelEvent,
      prop: valueProperty,
    },
    // created() {
    //   console.log(this);
    // },
    mounted() {
      this.updateAttrs();
    },
    render(h) {
      const cmp: any = this;

      this.updateAttrs();
      // return this._element
      const vnode =  h(coreTag, {
        // attrs: this.webAttrs.baseAttrs,
        on:cmp.webListeners
      }, cmp.webSlots);

      console.log(vueVNodeToWebVNode(vnode))
      return vnode
    },
    computed: {
      // {baseAttrs:{}, objectAttrs: {}}
      // webAttrs() {
      //   const baseAttrs = {}
      //   const objectAttrs = {}
      //   Object.keys(this.$attrs).forEach(i => {
      //     const typeofStr = typeof this.$attrs[i]
      //     if (typeofStr === 'object' || typeofStr === 'function') {
      //       objectAttrs[i] = this.$attrs[i]
      //     } else {
      //       baseAttrs[i] = this.$attrs[i]
      //     }
      //   })
      //   return {
      //     baseAttrs,
      //     objectAttrs
      //   }
      // },
      webListeners() {
        const $listeners: any = {}
        const $this = this
        Object.keys(this.$listeners).forEach(i => {
          $listeners[i] = function ($event: CustomEvent) {
            // args.unshift(i)
            $this.proxyEmitMethod(i, $event)
          }
        })
        $listeners[modelEvent] = function ($event: CustomEvent) {
          // const args = Array.prototype.slice.call(arguments)
          // args.unshift(modelEvent)
          // $this.proxyEmitMethod.apply(null, args)
          $this.proxyEmitMethod(modelEvent, $event)
        }
        return $listeners
      },
      webSlots() {
        // let slots = this.$slots.default
        // Object.keys(this.$slots).forEach(i => {
        //   if (i !== 'default') {
        //     this.$slots[i].forEach(item => {
        //       item.data.attrs.slot = i
        //     delete item.data.slot
        //     slots.push(item)
        //     })
        //   }
        // })
        const slots = Object.keys(this.$slots)
        // @ts-ignore
        .reduce((arr, key) => arr.concat(this.$slots[key]), [])
        //  context
        .map(vnode => {
          // @ts-ignore
          vnode.context = this._self
          return vnode
        })
        return slots
      },
      webScopedSlots() {
        return this.$scopedSlots
      },
    },
    watch: {
      value(val) {
        console.log(val)
      }
    },
    methods: {
      updateAttrs() {
        if(this.$el) {
          Object.keys(this.$attrs).forEach(i => {
            // @ts-ignore
            this.$el[i] = this.$attrs[i]
          })
          // @ts-ignore
          this.$el.getScopedSlotsVNode = this.getScopedSlotsVNode
        }
      },
      proxyEmitMethod(eventName: string, $event: CustomEvent) {
        if (modelEvent === eventName) {
          // Vue expects the value to be sent as the argument for v-model, not the
          // actual event object
          // @ts-ignore
          this.$emit(eventName, $event.target[valueProperty]);
        } else {
          this.$emit(eventName, $event.detail);
        }
      },
      getScopedSlotsVNode(slotName: string, props: any) {
        if (this.webScopedSlots[slotName]) {
          const VueNode: any = this.webScopedSlots[slotName](props)
          return vueVNodeToWebVNode(VueNode)
        }
        return null
      }
    }
  })
}
Menu