vue wrap another component, passing props and events vue wrap another component, passing props and events vue.js vue.js

vue wrap another component, passing props and events


Place the component you wish to wrap into the template of the wrapper component, add v-bind="$attrs" v-on="$listeners" to that component tag, then add the inner component (and, optionally, inheritAttrs: false) to the wrapper component's config object.

Vue's documentation doesn't seem to cover this in a guide or anything, but docs for $attrs, $listeners, and inheritAttrs can be found in Vue's API documentation. Also, a term that may help you when searching for this topic in the future is "Higher-Order Component" (HOC) - which is basically the same as your use of "wrapper component". (This term is how I originally found $attrs)

For example...

<!-- WrapperComponent.vue --><template>    <div class="wrapper-component">        <v-table v-bind="$attrs" v-on="$listeners"></v-table>    </div></template><script>    import Table from './BaseTable'    export default {        components: { 'v-table': Table },        inheritAttrs: false // optional    }</script>

Edit: Alternatively, you may want to use dynamic components via the is attribute so you can pass in the component to be wrapped as a prop (closer to the higher-order component idea) instead of it always being the same inner component. For example:

<!-- WrapperComponent.vue --><template>    <div class="wrapper-component">        <component :is="wraps" v-bind="$attrs" v-on="$listeners"></component>    </div></template><script>    export default {        inheritAttrs: false, // optional        props: ['wraps']    }</script>

Edit 2: The part of OP's original question that I missed was passing all props EXCEPT one or two. This is handled by explicitly defining the prop on the wrapper. To quote the documentation for $attrs:

Contains parent-scope attribute bindings (except for class and style) that are not recognized (and extracted) as props

For example, example1 is recognized and extracted as a prop in the snippet below, so it doesn't get included as part of the $attrs being passed down.

Vue.component('wrapper-component', {   template: `    <div class="wrapper-component">        <component :is="wraps" v-bind="$attrs" v-on="$listeners"></component>    </div>  `,  // NOTE: "example1" is explicitly defined on wrapper, not passed down to nested component via $attrs  props: ['wraps', 'example1']})Vue.component('posts', {  template: `    <div>      <div>Posts component</div>      <div v-text="example1"></div>      <div v-text="example2"></div>      <div v-text="example3"></div>    </div>  `,  props: ['example1', 'example2', 'example3'],})new Vue({  el: '#app',  template: `    <wrapper-component wraps="posts"      example1="example1"      example2="example2"      example3="example3"    ></wrapper-component>  `,})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script><div id="app"></div>