Как использовать асинхронные функции для загрузки данных в Vue и Express? - PullRequest
0 голосов
/ 17 мая 2019

Я использую 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 я создаю папку services в проекте vue, созданном с помощью Vue-Cli, где я использую axios для получения данных из серверной части.

коды от сервисов / Api.js:

import axios from 'axios'

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

коды от сервисов / 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 можно загрузить данные. Однако странная вещь заключается в том, что после того, как я запустил экспресс и vue в терминале, на странице не отображается список фильмов, но ниже показан список кнопок.

в консоли сначала нет сообщений об ошибках, но через некоторое время появляется сообщение об ошибке:

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

Так как я могу получить данные фильма для рендеринга и почему кнопка отображается, а список фильмов не отображается?

Я все еще изучаю разработку интерфейса, поэтому любая помощь будет отличной! Извините за мой плохой английский.

...