14

I am really struggling with the following scenario:

Some index page:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <div id="app">

      <ul>
        <li>some existing option</li>
        <example-component :foo="foo" :bar="bar"/>
      </ul>

      <a @click.prevent="showDetail(1, 'abc')" href="#" >Click ME!</a>

    </div>


    <script src="app.js"></script>


  </body>
</html>

Some single file component:

<template>
    <li><a v-show="checkBool" data-toggle="tab" class="some-class" href="#container-div" data-tab-url="{{ this.foo }}">{{ this.bar }}</a></li>
</template>



<script>
export default {

  props: ['foo', 'bar'],


  computed: {
    checkBool: function() {
      return (this.foo != undefined && this.bar != undefined )
    }

  }

}
</script>

And the app.js looks something like this:

import Vue from 'vue'

Vue.component('example-component', require('ExampleComponent.vue'));

const app = new Vue({
    el: '#app',

    props: [
      'foo',
      'bar'
    ],

    data: {
      foo: '',
      bar: ''
    },

     methods: {
      showDetail: function (foo, bar) {
        this.foo = foo,
        this.bar = bar
      }
  }
});

I am using babel with webpack under a laravel instalation.

The scenario is like this:

  • When I click the Click ME! link, foo and bar are updated and passed to the component (This part is working)
  • The computed property, named checkBool for this example becomes true, so I will then see the new list item (This part is working)
  • New list item, has a link, with the text correctly set to bar (This part is also working)

At this point I know that the values setting and communication between component and parent is working properly, however data-tab-url="{{ this.foo }}" part is driving me crazy.

Instead of parsing the moustache syntax as expected and return data-tab-url="1", I get a parsed/escaped value of everything between quotes.

Something like data-tab-url="%7B%7B+this.foo+%7D%7D".

Now, how do I prevent the encode from happening? From what I've read, there used to be a way in vuejs 1.*. Using three brackets: {{{ this.foo }}} but it's now deprecated in favor of v-html which I cannot use for my example.

5
  • If you use Vue in development mode you should see some warnings in your browser console. You should'nt use props in Vue instance - so in new Vue({...}). Here you declare foo and bar in props and data so there is a conflict. You should use data in a Vue instance and use data as a function (because you must declare function for data in component vuejs.org/v2/api/#data see Restriction. So do it everywhere to not be surprise one day ) : data: function() { return { foo: '', bar: ''   } } Commented Apr 5, 2017 at 17:21
  • Remove props: [ 'foo', 'bar' ], in app.js should do the job. Commented Apr 5, 2017 at 17:55
  • Thank you for your hint. Actually, I only have the props and don't have the data at all in the main Vue Commented Apr 5, 2017 at 18:00
  • Ok and all is fine now ? Everything works as expected ? ( I thought you have an other problem... so sorry if it not the case...) Commented Apr 5, 2017 at 19:13
  • I do have a Huge understanding problem concerning VueJS and Jquery, playing nice together. VueJS is always one step behind Jquery. Commented Apr 5, 2017 at 19:49

3 Answers 3

35

Bind the attribute like this :data-tab-url="foo".

This will give the affected element a data-tab-url attribute with a value equal to the foo property of your component.

Sign up to request clarification or add additional context in comments.

1 Comment

a sidenote: If foo is not defined, the tag will be displayed without the attribute.
10

thanksd's answer is right but;

for further understanding:

You can't use mustache syntax for attribute binding. Use mustache {{}} only content of a dom element, ie.

 <div>{{someValue}}</div> (THIS IS WRONG)

To bind any attribute, including template props any other attribute, such as "src" or "data-tab-url" like in question, you can use "v-bind:attr" or ":attr" shorthand, ie.

 <div v-bind:src="someDataVariable"></div>

or

<div v-bind:some-prop="someMethod()"></div>

You can use any member(data, method, computed etc.) of your component or Vue app, without "this".

Comments

1

To render any component instance property (prop, data, computed ...) inside html you've to :

  • Bind it to an attribute using v-bind: or the shorthand : like :foo="someFoo"

  • Use it inside mustache syntax {{someFoo}}

  • Use it as directive value v-show="isShown" or v-model="username", directives are always prefixed by v-

For the events, they are written like v-on:eventName or @eventName which could run an inline statement @click="count++" or a method @click="increment" knowing that increment is a function defined inside the methods options

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.