Search code examples
phpvuejs2laravel-mix

Passing props when rendering using h() with children on php laravel-mix


I have case for vuejs component that need to be rendered using php with laravel-mix. Its accepting role props

export default {
  name: 'ComponentOne',
  props: {
    role: [Number],
  },
  methods: {
    render(h) {
      return h(
        'div',
        {
          attrs: {
            id: 'component-one',
          }
        },
         this.$slots.default
      )
    },
  },
};
<?php
  $role = 1;
?>

<div id="app">
  <component-one :role="<?php echo $role ?>" />
</div>

Due to some package usage, the components render need to be define as follow:

import Vue from 'vue'
import ComponentOne from './ComponentOne.vue'
import SomePackage, { Wrapper, Reset } from '@somepackages'

Vue.use(SomePackage)

new Vue({
  render: (h) => h(Wrapper, [h(Reset), h(ComponentOne)]),
}).$mount('#app')

so the role props instead passed to the Wrapper and the props on ComponentOne are undefined.

Is there a way to pass the props from Wrapper to ComponentOne without literally declaring it on Wrapper?

I've been trying using provide and inject, and it somewhat working. But I want to know if there is another way that I not know.

export default {
  name: 'ComponentOne',
  provide() {
    return { role: this.role };
  },
  inject: ['role'],
  props: {
    role: [Number],
  },
  methods: {
    render(h) {
      return h(
        'div',
        {
          attrs: {
            id: 'component-one',
          }
        },
         this.$slots.default
      )
    },
  },
};

Solution

  • I am able to find a way to get props value from template.

    import Vue from 'vue'
    import ComponentOne from './ComponentOne.vue'
    import SomePackage, { Wrapper, Reset } from '@somepackages'
    
    Vue.use(SomePackage)
    
    new Vue({
      render: function (h) {
        const allProps = Object.keys(ComponentOne.props).reduce((carry, key) => {
          carry[key] = this.$vnode?.componentOptions?.propsData?.[key]
          return carry;
        }, {});
        return h(Wrapper, [h(reset), h(ComponentOne, { props: { ...allProps } })]
      },
    }).$mount('#app')
    

    this.$vnode is object from virtual node in which already rendered on php. So I can get props value initiated on the element.

    I need to change render from arrow function to function to be able to get this context.