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
.
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
}
}
})
}