最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use function that return value inside a template? Vuex, Vue - Stack Overflow

programmeradmin6浏览0评论

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
 |  Show 1 more ment

2 Answers 2

Reset to default 4

Inside 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: 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.
  • you should always 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

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.

发布评论

评论列表(0)

  1. 暂无评论