【问题标题】:How to use function that return value inside a template? Vuex, Vue如何在模板中使用返回值的函数? Vuex, Vue
【发布时间】:2020-12-19 19:09:09
【问题描述】:

我使用模板获取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”,但我希望使用函数 {{ year(item.date) }}

使用javascript编写函数year():

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 存储的第二部分,但您没有展示这两者如何交互。真的很难理解你的问题。
  • 我不确定是否允许使用{{}} 中的函数。无论如何,我认为您可以在分配给 actividades 之前处理函数 llamarJsonMutation 中的数据。

标签: javascript vue.js vuex


【解决方案1】:

在模板中,您可以使用定义为methodscomputed 的函数。从技术上讲,您也可以使用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); }
}

但它是一个复杂的构造(一个返回内部箭头函数的 getter 函数),这种复杂性没有任何用途。我建议您在您的情况下使用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
}

旁注:

  • 遍历包含&lt;ul&gt;&lt;template&gt; 标记是没有意义的。您可以将 v-for 直接放在 &lt;ul&gt; 上并丢失 &lt;template&gt; (当您想应用一些逻辑时,您应该只使用 &lt;template&gt; - 即:v-if - 到一堆元素而不实际包装将它们放入 DOM 包装器中;另一个用例是当您希望其子代是其父代的直接后代时:对于 &lt;ul&gt;/&lt;li&gt;&lt;tbody&gt;/&lt;tr&gt; 关系,您不能有中介它们之间的包装器)。在您的情况下,将 v-for 放在 &lt;ul&gt; 上会产生完全相同的结果,但代码更少。
  • 您应该始终key 您的v-for 的:&lt;ul v-for="(item, key) in actividades" :key="key"&gt;。键帮助列表元素的 Vue maintain the state,跟踪动画并正确更新它们

【讨论】:

  • 你的解释太棒了,非常感谢。
【解决方案2】:

我看到您正在尝试使用 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.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>
  • 使用 this.$store.commit() 直接在 Vue 组件中创建不带操作的方法来直接提交突变

PS:建议首先围绕突变创建操作,因为它是一种更简洁的方法。

【讨论】:

  • @luis,如果我理解你的问题,请告诉我。
  • 从任何地方拨打mutations 或actions 都非常安全。唯一的区别是 actions 是 async(并返回一个承诺 - 他们有一个 .then())和 mutations 是同步的。
猜你喜欢
  • 2011-08-31
  • 2021-10-11
  • 2021-08-20
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 2023-01-02
  • 1970-01-01
相关资源
最近更新 更多