Vue.js Dynamic Values in Component












1















I'm building a decoupled application with Vue.js, consuming data from WordPress' Rest API. The application includes a sort by category feature. I can't use vanilla form inputs to accomplish this and still match the design, to I need to use a Vue component to list the categories. The issue I have is that I can't populate the name of the category in the component's template.



The component code:



Vue.component( 'sort-button', {
props: ['value'],
template: `
<button class="button button-accent"
v-bind:value="value"
v-on:input="$emit( 'input', $event.target.value )"
>
<a href="#">{{ cat.name }}</a>
`
}
);


I'm displaying this as in-DOM template, like so:



<sort-button v-for="cat in portfolioCats"></sort-button>


This loops through each category and gives me a corresponding button if I leave the a tag contents of the template static or blank. However, if I use the {{ cat.name }} mustache, it errors because cat is not defined.



My question: How can I make the template aware of cat in the context of the for loop? Note that I would like for this to be a re-usable component that I can plugin into other Vue instances within the site.



Thanks!










share|improve this question



























    1















    I'm building a decoupled application with Vue.js, consuming data from WordPress' Rest API. The application includes a sort by category feature. I can't use vanilla form inputs to accomplish this and still match the design, to I need to use a Vue component to list the categories. The issue I have is that I can't populate the name of the category in the component's template.



    The component code:



    Vue.component( 'sort-button', {
    props: ['value'],
    template: `
    <button class="button button-accent"
    v-bind:value="value"
    v-on:input="$emit( 'input', $event.target.value )"
    >
    <a href="#">{{ cat.name }}</a>
    `
    }
    );


    I'm displaying this as in-DOM template, like so:



    <sort-button v-for="cat in portfolioCats"></sort-button>


    This loops through each category and gives me a corresponding button if I leave the a tag contents of the template static or blank. However, if I use the {{ cat.name }} mustache, it errors because cat is not defined.



    My question: How can I make the template aware of cat in the context of the for loop? Note that I would like for this to be a re-usable component that I can plugin into other Vue instances within the site.



    Thanks!










    share|improve this question

























      1












      1








      1








      I'm building a decoupled application with Vue.js, consuming data from WordPress' Rest API. The application includes a sort by category feature. I can't use vanilla form inputs to accomplish this and still match the design, to I need to use a Vue component to list the categories. The issue I have is that I can't populate the name of the category in the component's template.



      The component code:



      Vue.component( 'sort-button', {
      props: ['value'],
      template: `
      <button class="button button-accent"
      v-bind:value="value"
      v-on:input="$emit( 'input', $event.target.value )"
      >
      <a href="#">{{ cat.name }}</a>
      `
      }
      );


      I'm displaying this as in-DOM template, like so:



      <sort-button v-for="cat in portfolioCats"></sort-button>


      This loops through each category and gives me a corresponding button if I leave the a tag contents of the template static or blank. However, if I use the {{ cat.name }} mustache, it errors because cat is not defined.



      My question: How can I make the template aware of cat in the context of the for loop? Note that I would like for this to be a re-usable component that I can plugin into other Vue instances within the site.



      Thanks!










      share|improve this question














      I'm building a decoupled application with Vue.js, consuming data from WordPress' Rest API. The application includes a sort by category feature. I can't use vanilla form inputs to accomplish this and still match the design, to I need to use a Vue component to list the categories. The issue I have is that I can't populate the name of the category in the component's template.



      The component code:



      Vue.component( 'sort-button', {
      props: ['value'],
      template: `
      <button class="button button-accent"
      v-bind:value="value"
      v-on:input="$emit( 'input', $event.target.value )"
      >
      <a href="#">{{ cat.name }}</a>
      `
      }
      );


      I'm displaying this as in-DOM template, like so:



      <sort-button v-for="cat in portfolioCats"></sort-button>


      This loops through each category and gives me a corresponding button if I leave the a tag contents of the template static or blank. However, if I use the {{ cat.name }} mustache, it errors because cat is not defined.



      My question: How can I make the template aware of cat in the context of the for loop? Note that I would like for this to be a re-usable component that I can plugin into other Vue instances within the site.



      Thanks!







      javascript vue.js






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 18 '18 at 22:02









      DavidBrownDavidBrown

      9310




      9310
























          3 Answers
          3






          active

          oldest

          votes


















          3














          You need to pass the variable cat as a prop.



          <sort-button v-for="cat in portfolioCats" :cat="cat"></sort-button>


          And add it to the props array.



          props: ['value', 'cat']





          share|improve this answer



















          • 2





            +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

            – Sheng Slogar
            Nov 18 '18 at 22:10













          • Works perfectly. Thanks for the response!

            – DavidBrown
            Nov 18 '18 at 23:02



















          2














          cat is not defined in the component. You need a prop for it, and you also need to supply the value for value.



          <sort-button v-for="cat in portfolioCats" :name="cat.name" :value="cat.value"></sort-button>


          So your template should be



          Vue.component( 'sort-button', {
          props: ['value', 'name'],
          template: `
          <button class="button button-accent"
          v-bind:value="value"
          v-on:input="$emit( 'input', $event.target.value )"
          >
          <a href="#">{{ name }}</a>
          `
          });


          Also, buttons don't typically have input events, so it's not clear what you're expecting to happen there. Possibly you want a click event.



          Just noticed you aren't closing your <button> tag, too. It's odd to put an anchor inside a button; maybe you want the button to close before the anchor.






          share|improve this answer


























          • That's an excellent point about the input event

            – Phil
            Nov 18 '18 at 22:14











          • button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

            – DavidBrown
            Nov 18 '18 at 23:42



















          0














          One option would be to use a slot so you can define the content from the parent context. For example



          <button class="button button-accent"
          :value="value"
          @input="$emit( 'input', $event.target.value )">
          <slot></slot>
          </button>


          and in the parent...



          <sort-button v-for="cat in portfolioCats" v-model="something" :key="cat.id">
          <a href="#">{{ cat.name }}</a>
          </sort-button>





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53365907%2fvue-js-dynamic-values-in-component%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            3














            You need to pass the variable cat as a prop.



            <sort-button v-for="cat in portfolioCats" :cat="cat"></sort-button>


            And add it to the props array.



            props: ['value', 'cat']





            share|improve this answer



















            • 2





              +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

              – Sheng Slogar
              Nov 18 '18 at 22:10













            • Works perfectly. Thanks for the response!

              – DavidBrown
              Nov 18 '18 at 23:02
















            3














            You need to pass the variable cat as a prop.



            <sort-button v-for="cat in portfolioCats" :cat="cat"></sort-button>


            And add it to the props array.



            props: ['value', 'cat']





            share|improve this answer



















            • 2





              +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

              – Sheng Slogar
              Nov 18 '18 at 22:10













            • Works perfectly. Thanks for the response!

              – DavidBrown
              Nov 18 '18 at 23:02














            3












            3








            3







            You need to pass the variable cat as a prop.



            <sort-button v-for="cat in portfolioCats" :cat="cat"></sort-button>


            And add it to the props array.



            props: ['value', 'cat']





            share|improve this answer













            You need to pass the variable cat as a prop.



            <sort-button v-for="cat in portfolioCats" :cat="cat"></sort-button>


            And add it to the props array.



            props: ['value', 'cat']






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 18 '18 at 22:09









            Rodrigo Martín de LamoRodrigo Martín de Lamo

            1167




            1167








            • 2





              +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

              – Sheng Slogar
              Nov 18 '18 at 22:10













            • Works perfectly. Thanks for the response!

              – DavidBrown
              Nov 18 '18 at 23:02














            • 2





              +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

              – Sheng Slogar
              Nov 18 '18 at 22:10













            • Works perfectly. Thanks for the response!

              – DavidBrown
              Nov 18 '18 at 23:02








            2




            2





            +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

            – Sheng Slogar
            Nov 18 '18 at 22:10







            +1. Another approach would also be slots, if you want to manage data at the parent instead of passing it down.

            – Sheng Slogar
            Nov 18 '18 at 22:10















            Works perfectly. Thanks for the response!

            – DavidBrown
            Nov 18 '18 at 23:02





            Works perfectly. Thanks for the response!

            – DavidBrown
            Nov 18 '18 at 23:02













            2














            cat is not defined in the component. You need a prop for it, and you also need to supply the value for value.



            <sort-button v-for="cat in portfolioCats" :name="cat.name" :value="cat.value"></sort-button>


            So your template should be



            Vue.component( 'sort-button', {
            props: ['value', 'name'],
            template: `
            <button class="button button-accent"
            v-bind:value="value"
            v-on:input="$emit( 'input', $event.target.value )"
            >
            <a href="#">{{ name }}</a>
            `
            });


            Also, buttons don't typically have input events, so it's not clear what you're expecting to happen there. Possibly you want a click event.



            Just noticed you aren't closing your <button> tag, too. It's odd to put an anchor inside a button; maybe you want the button to close before the anchor.






            share|improve this answer


























            • That's an excellent point about the input event

              – Phil
              Nov 18 '18 at 22:14











            • button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

              – DavidBrown
              Nov 18 '18 at 23:42
















            2














            cat is not defined in the component. You need a prop for it, and you also need to supply the value for value.



            <sort-button v-for="cat in portfolioCats" :name="cat.name" :value="cat.value"></sort-button>


            So your template should be



            Vue.component( 'sort-button', {
            props: ['value', 'name'],
            template: `
            <button class="button button-accent"
            v-bind:value="value"
            v-on:input="$emit( 'input', $event.target.value )"
            >
            <a href="#">{{ name }}</a>
            `
            });


            Also, buttons don't typically have input events, so it's not clear what you're expecting to happen there. Possibly you want a click event.



            Just noticed you aren't closing your <button> tag, too. It's odd to put an anchor inside a button; maybe you want the button to close before the anchor.






            share|improve this answer


























            • That's an excellent point about the input event

              – Phil
              Nov 18 '18 at 22:14











            • button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

              – DavidBrown
              Nov 18 '18 at 23:42














            2












            2








            2







            cat is not defined in the component. You need a prop for it, and you also need to supply the value for value.



            <sort-button v-for="cat in portfolioCats" :name="cat.name" :value="cat.value"></sort-button>


            So your template should be



            Vue.component( 'sort-button', {
            props: ['value', 'name'],
            template: `
            <button class="button button-accent"
            v-bind:value="value"
            v-on:input="$emit( 'input', $event.target.value )"
            >
            <a href="#">{{ name }}</a>
            `
            });


            Also, buttons don't typically have input events, so it's not clear what you're expecting to happen there. Possibly you want a click event.



            Just noticed you aren't closing your <button> tag, too. It's odd to put an anchor inside a button; maybe you want the button to close before the anchor.






            share|improve this answer















            cat is not defined in the component. You need a prop for it, and you also need to supply the value for value.



            <sort-button v-for="cat in portfolioCats" :name="cat.name" :value="cat.value"></sort-button>


            So your template should be



            Vue.component( 'sort-button', {
            props: ['value', 'name'],
            template: `
            <button class="button button-accent"
            v-bind:value="value"
            v-on:input="$emit( 'input', $event.target.value )"
            >
            <a href="#">{{ name }}</a>
            `
            });


            Also, buttons don't typically have input events, so it's not clear what you're expecting to happen there. Possibly you want a click event.



            Just noticed you aren't closing your <button> tag, too. It's odd to put an anchor inside a button; maybe you want the button to close before the anchor.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 18 '18 at 22:15

























            answered Nov 18 '18 at 22:11









            Roy JRoy J

            26.4k33158




            26.4k33158













            • That's an excellent point about the input event

              – Phil
              Nov 18 '18 at 22:14











            • button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

              – DavidBrown
              Nov 18 '18 at 23:42



















            • That's an excellent point about the input event

              – Phil
              Nov 18 '18 at 22:14











            • button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

              – DavidBrown
              Nov 18 '18 at 23:42

















            That's an excellent point about the input event

            – Phil
            Nov 18 '18 at 22:14





            That's an excellent point about the input event

            – Phil
            Nov 18 '18 at 22:14













            button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

            – DavidBrown
            Nov 18 '18 at 23:42





            button elements can contain a tags as phrasing content: developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

            – DavidBrown
            Nov 18 '18 at 23:42











            0














            One option would be to use a slot so you can define the content from the parent context. For example



            <button class="button button-accent"
            :value="value"
            @input="$emit( 'input', $event.target.value )">
            <slot></slot>
            </button>


            and in the parent...



            <sort-button v-for="cat in portfolioCats" v-model="something" :key="cat.id">
            <a href="#">{{ cat.name }}</a>
            </sort-button>





            share|improve this answer




























              0














              One option would be to use a slot so you can define the content from the parent context. For example



              <button class="button button-accent"
              :value="value"
              @input="$emit( 'input', $event.target.value )">
              <slot></slot>
              </button>


              and in the parent...



              <sort-button v-for="cat in portfolioCats" v-model="something" :key="cat.id">
              <a href="#">{{ cat.name }}</a>
              </sort-button>





              share|improve this answer


























                0












                0








                0







                One option would be to use a slot so you can define the content from the parent context. For example



                <button class="button button-accent"
                :value="value"
                @input="$emit( 'input', $event.target.value )">
                <slot></slot>
                </button>


                and in the parent...



                <sort-button v-for="cat in portfolioCats" v-model="something" :key="cat.id">
                <a href="#">{{ cat.name }}</a>
                </sort-button>





                share|improve this answer













                One option would be to use a slot so you can define the content from the parent context. For example



                <button class="button button-accent"
                :value="value"
                @input="$emit( 'input', $event.target.value )">
                <slot></slot>
                </button>


                and in the parent...



                <sort-button v-for="cat in portfolioCats" v-model="something" :key="cat.id">
                <a href="#">{{ cat.name }}</a>
                </sort-button>






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 18 '18 at 22:12









                PhilPhil

                96.7k11138157




                96.7k11138157






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53365907%2fvue-js-dynamic-values-in-component%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Guess what letter conforming each word

                    Port of Spain

                    Run scheduled task as local user group (not BUILTIN)