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

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

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

查看所有标签

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

谁排第一

谁排第一

Amy N. Langville、Carl D. Meyer / 郭斯羽 / 机械工业出版社 / 2014-6 / 49

《谁排第一?关于评价和排序的科学》是首个关于评分和排名科学的著作。它是搜索排序姊妹篇的第二本。本书主要内容有:排名概述、梅西法、科利法、基纳法、埃洛体系、马尔可夫法、攻防评分法、基于重新排序的排名方法、分差、用户偏好评分、处理平局、加入权重、“假如……会怎样”的问题与敏感性、排名聚合、比较排名的方法、数据等。 《谁排第一?关于评价和排序的科学》可作为数学、计算机、网络技术、管理学和数据科学等......一起来看看 《谁排第一》 这本书的介绍吧!

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

在线压缩/解压 CSS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具