0

The site I'm currently working on is built in Drupal 7. I have one form that requires user input so I'm attempting to build it with VueJS. The form is contained all within one template file (.tpl.php) and all the content is provided in this template file or via the VueJS Javascript (nothing is coming from the CMS).

The issue I have is that the Vue components are not rendering on the front-end, but when I copy the code into a JSFiddle they do, so I'm guessing it is an issue with the interaction between VueJS and Drupal. Here is a screenshot of my markup when inspecting...

enter image description here

Here is the code from the .tpl.php file...

<div id="app">
        <form>
          <div>
            <label for="year">Per Year</label>
            <input type="radio" name="frequency" id="year" value="year" v-model="frequency" checked>
            <label for="month">Per Month</label>
            <input type="radio" name="frequency" id="month" value="month" v-model="frequency">
          </div>
        </form>

        <ul class="plans">
          <template id="plan-component">
            <h2 class="plan-name">{{ name }}</h2>
                  <h2 class="plan-cost">{{ price }}</h2>

                  <h2 class="plan-tagline">{{ tagline }}</h2>
                <a href="#" v-on:click="makeActivePlan($event)" class="select-plan button">Choose this plan</a>
          </template>
          <li>
            <plan-component :frequency="frequency"
                            name="Basic"
                            tagline="Basic tagline"
                            price-yearly="Free"
                            price-monthly="Free"
            ></plan-component>
          </li>
          <li>
            <plan-component :frequency="frequency"
                            name="Rec"
                              tagline="Rec tagline"

                            price-yearly="3"
                            price-monthly="4"
            ></plan-component>
          </li>
          <li>
            <plan-component :frequency="frequency"
                            name="Team"
                              tagline="Team tagline"

                            price-yearly="4"
                            price-monthly="5"
            ></plan-component>
          </li>
          <li>
            <plan-component :frequency="frequency"
                            name="Club"
                              tagline="Club tagline"

                            price-yearly="5"
                            price-monthly="6"
            ></plan-component>
          </li>
        </ul>
      </div>

..and the code from my JS file...

Vue.component('plan-component', {
    template: '#plan-component',

  props: ['frequency', 'name', 'tagline', 'priceYearly', 'priceMonthly'],

  computed: {
    'price': function() {
        if (this.frequency === 'year') {
        return this.priceYearly;
      } else {
        return this.priceMonthly;
      }
    }
  },

  methods: {
    makeActivePlan() {
        // We dispatch an event setting this to become the active plan
        this.$dispatch('set-active-plan', this);
    }
  }

});

new Vue({
  el: '#app',
  data: {
    frequency: 'year',
    activePlan: {name: 'no', price: 'You must select a plan!' }
  },

  events: {
    'set-active-plan': function(plan) {
        this.activePlan = plan;
    }
  },
});

And here is the JSFiddle which outputs the components correctly - https://jsfiddle.net/2xgrpLm6/

GuerillaRadio
  • 1,267
  • 5
  • 29
  • 59

3 Answers3

2

What browser are you using? <template> tags are not supported in IE.

Another idea is to make sure you are never using fragment components (meaning wrap everything inside your template with a div like so:

<template id="foobar">
  <div>
    CONTENT HERE
  </div>
</template>

Lastly, have you turned on Vue debug mode? Before you instantiate your Vue instance, set Vue.config.debug = true and see if you get console errors then.

Jeff
  • 24,623
  • 4
  • 69
  • 78
  • Using Vue debug mode I was able to identify the problem. My script was firing before the page content was rendered, as such #app was not yet defined. Thanks for the help. – GuerillaRadio Jun 28 '16 at 09:45
1

Try moving the <template id="plan-component">...</template> code outside of the Vue instance. I.e., such that it is not contained within <div id="app">...</div>.

This has solved a similar problem for me in the past, though I'm not sure if it applies here.

asemahle
  • 20,235
  • 4
  • 40
  • 38
0

For anyone having a similar issue, the solution was simple. After Jeff suggested turning on Vue debug mode (and downloading the Dev version of Vue JS instead of minified - https://vuejs.org/guide/installation.html) the console gave the error [Vue warn]: Cannot find element: #app.

The issue was that Drupal was loading my scripts in the <head>, before <div id="app"> was loaded in the DOM. As such #app couldn't be found. After outputting the scripts before the closing <body> tag all was sorted. See here for more information [Vue warn]: Cannot find element

Community
  • 1
  • 1
GuerillaRadio
  • 1,267
  • 5
  • 29
  • 59