如何使用异步功能在Vue和Express中加载数据?

时间:2019-05-17 12:10:03

标签: express vue.js async-await axios

我正在使用Vue 3.6.3 + Express 4.x + MongoDB构建电影列表页面。主页显示了电影列表,并且仅包含每部电影的简要信息,页面底部有指向下一页的按钮。

影片存储在mongodb中,我使用Express.js处理与mongodb的连接并发送数据。

mongodb.js中的重要代码:

var mongo = require('mongodb');

var MongoClient = mongo.MongoClient;
let database = null;


let get_films = function(page_index) {
    let start_index = (page_index - 1) * 20;
    return MongoClient.connect('mongodb://' + user_name + ':' + pwd + '@' + url + ':' + port + '/' + 'films').then(function(db) {
        database = db;
        let cursor = database.db('films').collection('films').find().skip(start_index).limit(10);
        // let cursor = database.db('films').collection('films').find();
        return cursor.toArray();
    }).then(function(items) {
        console.log('Already got items...');
        database.close();
        result = items;
        return items;
    });
};

设置mongodb处理程序后,我设置了一个快速应用程序来发送数据:

来自router.js的代码:

const db = require('./mongodb');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')

const router = express.Router();
const app = express();

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());
app.use(cors);

app.get('/get_films', (req, res) => {
    let page_index = req.query['film_index'];
    db.get_films(page_index).then((items) => {
        res.json(items);
    }).catch((err) => {
        res.send(err);
        return;
    })
})
app.listen(process.env.PORT || 9000);

那些是后端的东西。在前端Vue应用程序中,我在使用Vue-Cli生成的vue项目中创建一个 services 文件夹,在其中使用 axios 从后端获取数据。

来自services / Api.js的代码:

import axios from 'axios'

export default() => {
  return axios.create({
    baseURL: `http://localhost:9000`
  })
}

来自services / GetService.js的代码:

import Api from './Api';

export default {
    get_films: async (index) => {
        console.log('getting films...');
        try {
            const res = await Api().get('/get_films?film_index=' + index);
            console.log(res.data);
            return res.data;
        } catch (err) {
            console.log(err);
        }
    }
}

在Vue页面中,最重要的组件是FilmList.vue,其中显示了简要信息以及按钮。

来自FilmList.vue的

代码:

<template>
  <div id="filmlist">
    <div id="search-box" v-if="searchedFilm != -1">
      <input v-model="filmToSearch" placeholder="请输入想搜索的电影">
      <button @click="seachFilm">搜索</button>
    </div>
    <div id="searchError" v-if="searchedFilm == -1">
      <p>抱歉,未找到您搜索的电影</p>
      <button @click="returnToPage">返回</button>
    </div>
    <div v-else>
      <film-brief
        v-for="film in films"
        v-bind:key="film._id"
        v-bind:index="film._id"
        v-bind:film="film"
      ></film-brief>
      <div class="buttons">
        <jump-button
          class="button"
          v-for="index in buttonIndexList"
          :key="index.id"
          v-bind:index="index"
          v-on:jump-page="pageIndex = index.id"
        ></jump-button>
      </div>
    </div>
  </div>
</template>

<script>
import FilmBrief from "../components/FilmBrief.vue";
import JumpButton from "../components/JumpButton.vue";

import service from "../services/GetService.js";

const GroupCount = 10;

export default {
  name: "FilmList",
  data: function() {
    return {
      films: [],
      pageIndex: 1,
      filmToSearch: "",
      searchedFilm: 0,
      pageCount: 0,
      groupCount: GroupCount
    };
  },
  components: {
    FilmBrief,
    JumpButton
  },
  computed: {
    buttonIndexList: function() {
      let indexes = [];
      for (let i = 1; i <= this.pageCount; i++) {
        let temp = { id: i };
        indexes.push(temp);
      }
      return indexes;
    }
  },
  created: function() {
    service.get_films(this.pageIndex).then(items => {
      this.films = items;
    });
    console.log(this.films);
    this.pageCount = Math.ceil(10000 / GroupCount);
  },
  methods: {
    seachFilm: async function() {
      let _id = await service.search_film(this.filmToSearch);
      if (_id != null) {
        this.$router.push({ name: "detail", params: { id: _id } });
      } else {
        this.searchedFilm = -1;
      }
    },
    returnToPage: function() {
      this.searchedFilm = 0;
    }
  }
};
</script>

<style>
#filmlist {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
#search-box {
  margin-bottom: 50px;
}
.buttons {
  width: 300px;
  margin: 50px auto;
  padding-bottom: 100px;
}
.button {
  float: left;
}
</style>

我想使用Promise.then可以加载数据。但是,很奇怪的是,在终端中同时运行express和vue之后,页面没有显示电影列表,但是在下面显示了按钮列表。

在控制台中,最初没有错误消息,但是过一会儿会出现错误消息:

Error: Network Error
    at createError (createError.js?2d83:16)
    at XMLHttpRequest.handleError (xhr.js?b50d:87)

那么我如何获得要渲染的电影数据以及为什么在无法显示电影列表的情况下显示按钮?

我仍在学习前端开发,因此任何帮助都会很棒!对不起,我的英语不好。

0 个答案:

没有答案