Я использую шаблон для получения данных файла json, я использую "v-for" для печати всех данных, например:
template: /*html*/
`
<div class = "col-lg-8">
<template v-for = "item of actividades">
<ul>
<li>{{ item.date }}</li>
<ul>
</template>
</div>
`,
Но мне нужно использовать функции year() для изменения этой информации и возврата и результата, например:
template: /*html*/
`
<div class = "col-lg-8">
<template v-for = "item of actividades">
<ul>
<li>{{ year(item.date) }}</li>
<ul>
</template>
</div>
`,
Значение {{ item.date }} напечатает «2021-01-20», но я надеюсь напечатать «2021», используя функцию {{ year(item.date) }}
Код функции year() с использованием javascript:
year(date){
return String(date).substr(0, 4);
}
Я пытался использовать этот код, но он не работает, появляется эта ошибка:
Это мой код javascript:
//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');
}
});
Появляется ошибка петли.
Что за сообщение об ошибке?
Ваша первая часть вопроса о компоненте, который зацикливает данные и нуждается в функции year
, ваша вторая часть о хранилище vuex, но вы не показываете, как эти два взаимодействия взаимодействуют. Очень сложно понять вашу проблему.
Пожалуйста, извините, я обновил пост и загрузил изображение, на котором вы можете увидеть ошибку.
Я не уверен, что это позволяет использовать функцию в {{}}
. В любом случае, я думаю, вы могли бы иметь дело с данными в функции llamarJsonMutation до того, как они были назначены actividades.
Я вижу, вы пытаетесь работать с магазином Vuex. И используя мутацию внутри синтаксиса шаблона.
Не уверен, что мы можем вызвать мутацию напрямую через HTML, как это делаете вы. В прошлом, когда я пытался вызвать мутацию, я бы либо:
Vue.component('followers', {
template: '<div>Followers: {{ computedFollowers }} {{printSampleLog()}}</div>',
data() {
return { followers: 0 }
},
created () {
this.$store.dispatch('getFollowers').then(res => {
this.followers = res.data.followers
})
},
computed: {
computedFollowers: 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.com/users/octocat')
.then(response => resolve(response))
.catch(err => reject(error))
});
},
sampleAction(context){
context.commit('sampleMutation');
}
},
mutations: {
sampleMutation(){
console.info("sample mutation")
}
}
})
const app = new Vue({
store,
el: '#app'
})
<script src = "https://unpkg.com/vue"></script>
<script src = "https://unpkg.com/vuex"></script>
<script src = "https://unpkg.com/axios/dist/axios.min.js"></script>
<div id = "app">
<followers></followers>
</div>
PS: Я бы порекомендовал сначала создать действие вокруг мутации, так как это гораздо более чистый подход.
@luis, дайте мне знать, правильно ли я понял ваш вопрос.
Совершенно безопасно звонить mutation
s или action
s из любого места. Единственная разница в том, что action
s являются async
(и возвращают обещание — у них есть .then()
), а mutation
s синхронны.
Внутри шаблона вы можете использовать функции, определенные как methods
или computed
. Технически вы также можете использовать data
для передачи функции в шаблон, но я бы не рекомендовал этого делать. Не то чтобы это не сработало, но Vue делает все, что объявлено в data
, реактивным, и нет смысла делать функцию (которая по сути является константой) реактивной. Итак, в вашем случае:
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>
Если по какой-то причине вы хотите передать year
как computed
:
computed: {
year() { return date => date.substring(0, 4); }
}
Но это запутанная конструкция (геттер-функция, возвращающая внутреннюю стрелочную функцию), и эта сложность не служит никакой цели. Я бы порекомендовал вам использовать method
в вашем случае, так как это наиболее прямолинейно (легко читать/понимать).
Если вы импортируете функцию year
из другого файла:
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
}
Боковые примечания:
<template>
, которые содержат <ul>
. Вы можете поместить v-for непосредственно на <ul>
и потерять <template>
(вы должны использовать <template>
только тогда, когда хотите применить некоторую логику, то есть: v-if
- к группе элементов, фактически не оборачивая их в оболочку DOM; другое использование -case - это когда вы хотите, чтобы его дети были прямыми потомками его родителя: для отношений <ul>
/<li>
или <tbody>
/<tr>
, где между ними не может быть промежуточных оболочек). В вашем случае размещение v-for
на <ul>
дает тот же результат с меньшим количеством кода.key
ваши v-for
: <ul v-for = "(item, key) in actividades" :key = "key">
. Ключи помогают Vue поддерживать состояние элементов списка, отслеживать анимации и корректно обновлять их.Ваше объяснение прекрасно, большое спасибо.
Как это не "работает"? Каков ожидаемый результат? Что на самом деле произошло?