如何將非同步資料傳入 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 ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

智能主义

智能主义

周鸿祎 / 中信出版集团股份有限公司 / 2016-11-1 / CNY 49.00

大数据和人工智能迅猛发展,对社会和商业的影响日益深刻,从学术界到企业界,智能化时代必将来临,已经成为共识。而此次变革,将会开启新一轮的发展浪潮。企业家、互联网以及传统企业、个人,应当如何理解这一轮的发展,如何行动以抓住智能化所带来的众多机遇,成为所有人持之以恒的关注热点。 周鸿祎作为最具洞察力的互联网老兵、人工智能领域成功的先行者,通过总结360公司的战略布局、产品规划、方法论实践,从思想到......一起来看看 《智能主义》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器