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:
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: av-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 thev-for
on the<ul>
produces the exact same result with less code. - you should always
key
yourv-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