Skip to content
Advertisement

How to use function that return value inside a template? Vuex, Vue

I’m using a template to get data of a json file, I use “v-for” to print all data, for example:

template: /*html*/
    ` 
    <div class="col-lg-8">
        <template v-for="item of actividades">
            <ul>
                <li>{{ item.date }}</li>
            <ul>
        </template>
    </div>
    `,

But I need use functions, year() to modificate this information and return and result, for example:

   template: /*html*/
    ` 
    <div class="col-lg-8">
        <template v-for="item of actividades">
            <ul>
                <li>{{ year(item.date) }}</li>
            <ul>
        </template>
    </div>
    `,

The value {{ item.date }} print “2021-01-20” but I hope print “2021” using the function {{ year(item.date) }}

Code function year() using javascript:

year(date){
            return String(date).substr(0, 4);
        }

I tried use that code but is not working, appear this error: this image show error

That’s my javascript code:

//VueEx
const store = new Vuex.Store({
    state: {
        actividades: [],
        programas: [],
        year: ""
    },
    mutations: {
        llamarJsonMutation(state, llamarJsonAction){
            state.actividades = llamarJsonAction.Nueva_estructura_proveedor;
            state.programas = llamarJsonAction.BD_programas;
        },
        yearFunction(state, date){
            state.year = String(date).substr(8, 2);
            return state.year;
        }
    },
    actions: {
        llamarJson: async function({ commit }){
            const data = await fetch('calendario-2021-prueba.json');
            const dataJson = await data.json();
            commit('llamarJsonMutation', dataJson);
        }
    }
});

//Vue
new Vue({
    el: '#caja-vue',
    store: store,
    created() {
        this.$store.dispatch('llamarJson');
      }
});

Advertisement

Answer

Inside a template you can use functions defined as methods or computed. Technically, you can also use data to pass a function to the template, but I wouldn’t recommend it. Not that it wouldn’t work, but Vue makes anything declared in data reactive and there’s no point in making a function (which is basically a constant) reactive. So, in your case:

new Vue({
  el: '#app',
  data: () => ({
    actividades: [
      { date: '2021-01-20' },
      { date: '2020-01-20' },
      { date: '2019-01-20' },
      { date: '2018-01-20' },
      { date: '2017-01-20' }
    ]
  }),
  methods: {
    year(date) { return date.substring(0, 4); }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <ul>
      <li v-for="(item, key) in actividades" :key="key">
        {{ year(item.date) }}
      </li>
  </ul>
</div>

If, for some reason, you want to pass year as computed:

computed: {
  year() { return date => date.substring(0, 4); }
}

But it’s a convoluted construct (a getter function returning an inner arrow function) and this complexity doesn’t serve any purpose. I’d recommend you use a method in your case, since it’s the most straight-forward (easy to read/understand).


If you’re importing the year function from another file:

import { year } from '../helpers'; // random example, replace with your import

// inside component's methods:

methods: {
  year, // this provides `year` imported function to the template, as `year`
        // it is equivalent to `year: year,`
  // other methods here
}

Side notes:

  • there is no point in iterating through <template> tags which contain <ul>‘s. You can place the v-for directly on the <ul> and lose the <template> (You should only use <template> when you want to apply some logic – i.e: a v-if – to a bunch of elements without actually wrapping them into a DOM wrapper; another use-case is when you want its children to be direct descendants of the its parent: for <ul>/<li> or <tbody>/<tr> relations, where you can’t have intermediary wrappers between them). In your case, placing the v-for on the <ul> produces the exact same result with less code.
  • you should always key your v-for‘s: <ul v-for="(item, key) in actividades" :key="key">. Keys help Vue maintain the state of list elements, keep track of animations and update them correctly
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement