用Vue-cli创建web component,怎么传递对象呢?

问题描述

用Vue-cli创建的web component,我需要把对象传递到里面去

问题出现的环境背景及自己尝试过哪些方法

试过直接传对象,但是属性值默认会去toString,导致web components只会拿到[Obejct Obejct]
因为我相信肯定有好的解决办法或者别的方法去实现目标,所以我没有在字符串、属性转变上思考太多时间,
在网上也找了不少资料,跟这方面的资料还真的少。。。。_(:з」∠)_

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
<foo-my-name id="id1"></foo-my-name>

<script>

document.querySelector('#id1').setAttribute('my-object', {
    name1: 'name1_123123213123',
    name2: 'name2_456456546456',
});

</script>

你期待的结果是什么?实际看到的错误信息又是什么?

我期望能把对象传进去,web components一直用的是默认参数,很难受

阅读 7.4k
4 个回答

web components的侧重点应该是UI的复用,如果要弄一下复杂的内容,vue-cli导出成lib更合适

foo-my-name组件

export default {
    props: {
        params: {
            type: Object//定义传递的类型为Object,
            default: () => {}//默认空对象
        }
    },
    created(){
        console.log(this.params)
    }
}

使用

<template>
    <!-- 将定义的myParams对象传给foo-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>
新手上路,请多包涵
document.querySelector('#id1').setAttribute('params', '{
    "name1": "name1_123123213123",
    "name2": "name2_456456546456",
}');

传json字符串进去然后在接收后转换来用就行

<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>

今天正好捣鼓这个,也捣鼓了挺久才灵机一动想到这个方法,或许你现在用不上了,留给后人看吧

新手上路,请多包涵

提供桥接层

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
      }
    }
  })
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题