13

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.

Angelin Calu
  • 1,905
  • 8
  • 24
  • 44
  • 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 https://vuejs.org/v2/api/#data see Restriction. So do it everywhere to not be surprise one day ) : `data: function() { return { foo: '', bar: ''   } }` – Happyriri Apr 05 '17 at 17:21
  • Remove `props: [ 'foo', 'bar' ],` in app.js should do the job. – Happyriri Apr 05 '17 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` – Angelin Calu Apr 05 '17 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...) – Happyriri Apr 05 '17 at 19:13
  • I do have a Huge understanding problem concerning VueJS and Jquery, playing nice together. VueJS is always one step behind Jquery. – Angelin Calu Apr 05 '17 at 19:49

3 Answers3

32

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.

thanksd
  • 54,176
  • 22
  • 157
  • 150
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".

user1920580
  • 101
  • 1
  • 2
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

Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164