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');
}
});
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:
<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.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