如何將非同步資料傳入 Prop ?

栏目: JavaScript · 发布时间: 6年前

内容简介:假如資料是從Vue 2.5.17Vue CLI 3.0.5

假如資料是從 App.vue 透過 API 抓取資料,然後透過 Prop 傳進 Component,最後再讀取 Prop 寫入 Component 的 Data,這看似平常的過程,若是同步資料則完全不是問題,但因為資料是從 API 來,為非同步 Promise,寫法則沒有想像中單純。

Version

Vue 2.5.17

Vue CLI 3.0.5

錯誤寫法

App.vue

<template>
  <div id="app">
    <todo-list :source="todos">
    </todo-list>
  </div>
</template>

<script>
import TodoList from './components/todo-list.vue';
import { fetchTodos } from './api/todos.api';

const mounted = function() {
  const response = res =>
    this.todos = res.data.slice(0, 5);

  fetchTodos()
    .then(response);
};

const components = {
  TodoList,
};

const data = function() {
  return {
    todos: [],
  };
};

export default {
  name: 'app',
  components,
  data,
  mounted,
};
</script>

<style>
</style>

12 行

const mounted = function() {
  const response = res =>
    this.todos = res.data.slice(0, 5);

  fetchTodos()
    .then(response);
};

mounted hook 透過 API 抓取資料。

第 3 行

<todo-list :source="todos">
</todo-list>

todos 傳進 todo-listsource prop。

todo-list.vue

<template>
  <div id="todo-list">
    <input type="text" v-model="input">
    <button @click="addItem">Add</button>
    <ul>
      <li v-for="(todo, index) in todos" @click="finishItem(index)" :key="index">
          {{ todo.title }}, {{ todo.completed }}
      </li>
    </ul>
  </div>
</template>

<script>
const finishItem = function(index) {
  this.todos[index].completed = !this.todos[index].completed;
};

const addItem = function() {
  const elem = {
    title: this.input,
    completed: false,
  };
  this.todos = [...this.todos, elem];
};

const props = [
  'source',
];

const data = function() {
  return {
    input: '',
    todos: this.source,
  };
};

const methods = {
  finishItem,
  addItem,
};

export default {
  name: 'todo-list',
  props,
  data,
  methods,
};
</script>

<style scoped>

</style>

30 行

const data = function() {
  return {
    input: '',
    todos: this.source,
  };
};

data()source prop 指定給 todos

這種寫法在若 prop 資料為同步,則為標準寫法;但若是非同步資料,則 todos 永遠為 []

因為 Promise 為非同步,會在同步執行完後才執行,也就是 todo-list component 的 data() 會先執行,最後才執行 Promise,因此 todos 永遠為 []

正確寫法

todo-list.vue

<template>
  <div id="todo-list">
    <input type="text" v-model="input">
    <button @click="addItem">Add</button>
    <ul>
      <li v-for="(todo, index) in todos" @click="finishItem(index)" :key="index">
          {{ todo.title }}, {{ todo.completed }}
      </li>
    </ul>
  </div>
</template>

<script>
const finishItem = function(index) {
  this.todos[index].completed = !this.todos[index].completed;
};

const addItem = function() {
  const elem = {
    title: this.input,
    completed: false,
  };
  this.todos = [...this.todos, elem];
};

const source = function(value) {
  this.todos = value;
};

const props = [
  'source',
];

const data = function() {
  return {
    input: '',
    todos: this.source,
  };
};

const watch = {
  source,
};

const methods = {
  finishItem,
  addItem,
};

export default {
  name: 'todo-list',
  props,
  data,
  watch,
  methods,
};
</script>

<style scoped>

</style>

41 行

const watch = {
  source,
};

由於 Promise 會最後執行,因此必須對 source prop 開 watch。

26 行

const source = function(value) {
  this.todos = value;
};

將 Promise 最後執行改變 source prop 時,會執行 watch 的 source() ,再由此 function 去改變 todos data。

如此 component 就能收到 prop 傳進來的非同步資料了。

Conclusion

  • 寫 ECMAScript 只要碰到非同步 Promise,就要考慮到其是最後執行,因此不能使用同步的方式思考

Sample Code

完整的範例可以在我的 GitHub 上找到


以上所述就是小编给大家介绍的《如何將非同步資料傳入 Prop ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大数据供应链

大数据供应链

娜达·R·桑德斯 (Nada R. Sanders) / 丁晓松 / 中国人民大学出版社 / 2015-7-1 / CNY 55.00

第一本大数据供应链落地之道的权威著作,全球顶级供应链管理专家娜达·桑德斯博士聚焦传统供应链模式向大数据转型,助力工业4.0时代智能供应链构建。 在靠大数据驱动供应链处于领先地位的企业中,45% 是零售商,如沃尔玛、亚马逊,而22%是快消企业,如戴尔电脑。他们都前所未有地掌控了自己的供应链。在库存管理、订单履行率、原材料和产品交付上具有更为广阔的视野。利用具有预见性的大数据分析结果,可以使供需......一起来看看 《大数据供应链》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具