[Vuejs]-VuesJS components template

0👍

There are at least three options I can think of:


1. Example with ref

Vue.component('NavBar', {
  template: `
    <nav>
      <slot></slot>
    </nav>
  `,

  methods: {
    run() {
      console.log('Parent\'s method invoked.');
    }
  }
});

new Vue().$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>

<div id="app">
  <nav-bar ref="navbar">
    <button @click="$refs.navbar.run()">Run with refs</button>
  </nav-bar>
</div>

2. With Scoped <slot>

Vue.component('NavBar', {
  template: `
    <nav>
      <slot v-bind="$options.methods"></slot>
    </nav>
  `,

  methods: {
    run() {
      console.log('Parent\'s method invoked.');
    }
  }
});

new Vue().$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>

<div id="app">
  <nav-bar>
    <template #default="methods">
      <button @click="methods.run">Run with slot props</button>
    </template>
  </nav-bar>
</div>

3. With provide and inject

Vue.component('NavBar', {
  template: `
    <nav>
      <slot></slot>
    </nav>
  `,
  
  provide() {
    const props = {
      ...this.$options.methods,

      // The rest of props you'd like passed down to the child components.
    };

    return props;
  },

  methods: {
    run() {
      console.log('Parent\'s method invoked.');
    }
  }
});

// In order to "receive" or `inject` the parent props,
// the child(ren) needs to be a component itself.
Vue.component('Child', {
  template: `
    <button @click="run">
      <slot></slot>
    </button>
  `,

  // Inject anything `provided` by the direct parent
  // This could also be `data` or `props`, etc.
  inject: ['run']
});

new Vue().$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>

<div id="app">
  <nav-bar>
    <template>
      <child>Run with injected method</child>
    </template>
  </nav-bar>
</div>

Leave a comment