#javascript #vue.js #vuex
#javascript #vue.js #vuex
Вопрос:
Я использую шаблон для получения данных из файла 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');
}
});
Комментарии:
1. Как это не «работает»? Каков ожидаемый результат? Что на самом деле произошло?
2. Появляется ошибка цикла.
3. Какое сообщение об ошибке?
4. Ваша первая часть вопроса о компоненте, который зацикливает данные и нуждается в
year
функции, ваша вторая часть о хранилище vuex, но вы не показываете, как эти два взаимодействуют. Действительно сложно понять вашу проблему.5. Я не уверен, что это позволяет использовать функцию внутри
{{}}
. В любом случае, я думаю, вы могли бы иметь дело с данными в функции llamarJsonMutation до того, как она была назначена actividades .
Ответ №1:
Внутри шаблона вы можете использовать функции, определенные как methods
или computed
. Технически вы также можете использовать data
для передачи функции в шаблон, но я бы не рекомендовал это. Не то чтобы это не сработало, но Vue делает все, что объявлено в data
reactive, и нет смысла делать функцию (которая в основном является константой) реактивной. Итак, в вашем случае:
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); }
}
Но это запутанная конструкция (функция получения, возвращающая функцию внутренней стрелки), и эта сложность не служит никакой цели. Я бы рекомендовал вам использовать a 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>
‘s. Вы можете поместить v-for непосредственно в<ul>
и потерять<template>
(вы должны использовать только тогда, когда<template>
хотите применить некоторую логику, то есть: av-if
— к куче элементов, фактически не оборачивая их в оболочку DOM; другой вариант использования — когда вы хотите, чтобы его дочерние элементы были прямыми потомкамиего родительского элемента: для<ul>
/<li>
или<tbody>
/<tr>
отношений, где у вас не может быть промежуточных оболочек между ними). В вашем случае размещениеv-for
на<ul>
дает точно такой же результат с меньшим количеством кода. - вы всегда должны
key
использовать своиv-for
:<ul v-for="(item, key) in actividades" :key="key">
. Ключи помогают Vue поддерживать состояние элементов списка, отслеживать анимации и корректно обновлять их
Комментарии:
1. ваше объяснение потрясающее, большое вам спасибо.
Ответ №2:
Я вижу, вы пытаетесь работать с хранилищем Vuex. И использование мутации внутри синтаксиса шаблона.
Не уверен, можем ли мы вызвать мутацию напрямую через HTML, как вы делаете. В прошлом, когда я пытался вызвать мутацию, я бы либо:
- Создайте действие, которое зафиксировало бы эту мутацию, и вызовите это действие, заключенное в метод через Vue, что-то вроде этого: найдите метод printSampleLog(), который я определил здесь
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.log("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>
- Иначе создайте метод без действия в вашем компоненте Vue, непосредственно фиксирующий мутацию, используя this.$store.commit()
PS: Рекомендовал бы сначала создать действие вокруг мутации, поскольку это гораздо более чистый подход.
Комментарии:
1. @luis, дайте мне знать, правильно ли я понял ваш вопрос.
2. Совершенно безопасно вызывать
mutation
s илиaction
s из любого места. Единственная разница в том, чтоaction
s являютсяasync
(и возвращают обещание — у них есть.then()
) иmutation
s синхронны.