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({ mit }){
const data = await fetch('calendario-2021-prueba.json');
const dataJson = await data.json();
mit('llamarJsonMutation', dataJson);
}
}
});
//Vue
new Vue({
el: '#caja-vue',
store: store,
created() {
this.$store.dispatch('llamarJson');
}
});
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({ mit }){
const data = await fetch('calendario-2021-prueba.json');
const dataJson = await data.json();
mit('llamarJsonMutation', dataJson);
}
}
});
//Vue
new Vue({
el: '#caja-vue',
store: store,
created() {
this.$store.dispatch('llamarJson');
}
});
Share
Improve this question
edited Dec 20, 2020 at 3:18
Felipe Moreno
asked Dec 19, 2020 at 19:09
Felipe MorenoFelipe Moreno
1332 silver badges7 bronze badges
6
- How is it not "working"? What's the expected oute? What actually happened? – tony19 Commented Dec 19, 2020 at 19:14
- Appear loop error. – Felipe Moreno Commented Dec 19, 2020 at 19:22
- What's the error message? – tony19 Commented Dec 19, 2020 at 19:36
-
Your first part of the question of about a ponent which is looping data and needs a
year
function, your second part of about a vuex store, but you don't show how these two interact. Really hard to understand your problem. – Maarten Veerman Commented Dec 19, 2020 at 21:47 -
1
I'm not sure it's allow to use a function in
{{}}
. Anyway I think you could deal with the data in function llamarJsonMutation before where it assigned to actividades. – ElapsedSoul Commented Dec 20, 2020 at 3:04
2 Answers
Reset to default 4Inside a template you can use functions defined as methods
or puted
. Technically, you can also use data
to pass a function to the template, but I wouldn't remend 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./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 puted
:
puted: {
year() { return date => date.substring(0, 4); }
}
But it's a convoluted construct (a getter function returning an inner arrow function) and this plexity doesn't serve any purpose. I'd remend 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 ponent'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
I see you are trying to work with the Vuex store. And using mutation inside the template syntax.
Not sure if we can call mutation directly via HTML as the way you are doing. In the past when I tried to call a mutation, I would either:
- Create an action which would mit that mutation and call that action wrapped inside a method through Vue, something like this:look for a method printSampleLog() that I defined here
Vue.ponent('followers', {
template: '<div>Followers: {{ putedFollowers }} {{printSampleLog()}}</div>',
data() {
return { followers: 0 }
},
created () {
this.$store.dispatch('getFollowers').then(res => {
this.followers = res.data.followers
})
},
puted: {
putedFollowers: function () {
return this.followers
}
},
methods:{
printSampleLog(){
this.$store.dispatch('sampleAction').then(res => {
this.followers = res.data.followers
})
}
}
});
const store = new Vuex.Store({
actions: {
getFollowers() {
return new Promise((resolve, reject) => {
axios.get('https://api.github./users/octocat')
.then(response => resolve(response))
.catch(err => reject(error))
});
},
sampleAction(context){
context.mit('sampleMutation');
}
},
mutations: {
sampleMutation(){
console.log("sample mutation")
}
}
})
const app = new Vue({
store,
el: '#app'
})
<script src="https://unpkg./vue"></script>
<script src="https://unpkg./vuex"></script>
<script src="https://unpkg./axios/dist/axios.min.js"></script>
<div id="app">
<followers></followers>
</div>
- Else create method w/o action in your Vue ponent mitting the mutation directly, using this.$store.mit()
PS: Would remend creating action around the mutation first, as it is a much cleaner approach.