MattyRad
MattyRad

Reputation: 183

Dynamic vue.js components that aren't in the parent

I would like to use Vue's dynamic components (http://vuejs.org/guide/components.html#Dynamic_Components) for components that are defined in a child object instead of the parent object. For example:

new Vue({
  el: 'body',
  components: {
    'post': require('./post')
});

// post.js

module.exports = {
  inherit: true,

  data: function () {
      return {
          currentView: 'create-post'
      }
  },
  components: {
     'create-post': require('./create-post'),
     'update-post': require('./update-post')
  }
}

<component is="{{ post.currentView }}"></component>

or better yet

<post is="{{ currentView }}"></post>

Since, as far as I know, the parent is the only one with access to the <component> tag, using a 2nd level child with it isn't possible. Am I thinking about the structure incorrectly, or is there a way to accomplish the above?

Upvotes: 1

Views: 1020

Answers (1)

MattyRad
MattyRad

Reputation: 183

So, the intern helped me solve this one... ugh, embarrassing.

My problem above is just with scope, and these best practices describe bow to fix it: http://vuejs.org/guide/best-practices.html#Component_Scope

Essentially, I just need an extra view layer component for "post" to have the proper scope its children. Easier shown than described:

new Vue({
  el: 'body',
  components: {
    'post': require('./post')
});

// post.js
module.exports = {
  inherit: true,

  template: document.querySelector('#post'),

  data: function () {
      return {
          currentView: 'create-post'
      }
  },
  components: {
     'create-post': require('./create-post'),
     'update-post': require('./update-post')
  }
}

// create-post.js
module.exports = {
  inherit: true,
  template: document.querySelector('#create-post'),
}

// update-post.js
module.exports = {
  inherit: true,
  template: document.querySelector('#update-post'),
}

// main.html
<html>
  <body>
    <post></post>
  </body>
</html>

// post.html
<script id="post" type="x-template">
  <component is="%% currentView %%"></component>
</script>

// create-post.html
<script id="create-post" type="x-template">
  <h1>Create a post</h1>
</script>

// update-post.html
<script id="create-post" type="x-template">
  <h1>Update a post</h1>
</script>

Upvotes: 1

Related Questions