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

查看所有标签

猜你喜欢:

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

数据驱动:从方法到实践

数据驱动:从方法到实践

桑文锋 / 电子工业出版社 / 2018-3 / 49

本书是从理论到实践的全面且细致的企业数据驱动指南,从作者的百度大数据工作说起,完整还原其从零到一构建百度用户行为大数据处理平台经历。详解大数据本质、理念与现状,围绕数据驱动四环节——采集、建模、分析、指标,深入浅出地讲述企业如何将数据驱动方案落地,并指出数据驱动的价值在于“数据驱动决策”、“数据驱动产品智能”。最后通过互联网金融、电子商务、企业服务、零售四大行业实践,从需求梳理、事件指标设计、数据......一起来看看 《数据驱动:从方法到实践》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

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

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码