首页 > 解决方案 > 使用 Promise 渲染一个 Vue 应用程序,并等待用户输入

问题描述

我有一个设计问题,我目前有一个逻辑繁重的 JS 脚本,我将其编写为各种 Promise 并创建了如下结构:

init()
    .then(result => doSomethingA(result)) 
    .then(result => doSomethingB(result))
    .then(result => loadVueApp(result))

现在loadVueApp()函数调用执行以下操作:

new Vue({
  el : '#app',
  render : h => h(App)
});

它呈现了我的 Vue 应用程序,然后用户可以与应用程序交互,进入各种屏幕,进行选择,我将其存储在全局EventBus类型组件中。

现在我的问题是,我应该如何将用户的选择传递回我的承诺塔?我应该这样做吗?

我可以loadVueApp仅根据出现的应用程序立即解决问题,然后稍后将函数调用回逻辑繁重的脚本 - 但这感觉不那么干净。

有任何想法吗?

提前致谢。

标签: javascriptvue.jsvuejs2frontend

解决方案


这是一个简单的示例,它执行以下操作:

  • Vue 组件从模板实例化并附加到<body>元素,而不是从现有的 DOM 元素(如果您不希望 UI 最初可见)。
  • 只有在单击提交按钮时,才会使用输入的文本来解决承诺。组件实例被销毁并从 DOM 中移除。

const InputUI = {
  template: '#input-ui',
  data() {
    return {
      value: '',
    };
  },
};

function getInput() {
  return new Promise(resolve => {
    const inputUI = new Vue(InputUI);
    
    inputUI.$once('submit', value => {
      inputUI.$destroy();
      inputUI.$el.remove();
      resolve(value);
    });
    
    inputUI.$mount();
    document.body.appendChild(inputUI.$el);
  });
}

getInput().then(value => alert(value));
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>

<template id="input-ui">
  <div>
    <input v-model="value">
    <button @click="$emit('submit', value)">Submit</button>
  </div>
</template>

如果您使用的是单个文件组件,您的代码结构类似于:

输入UI.vue

<template>
  <div>
    <input v-model="value">
    <button @click="$emit('submit', value)">Submit</button>
  </div>
</template>

<script>

export default {
  data() {
    return {
      value: '',
    };
  },
};

</script>

main.js

import Vue from 'vue';
import InputUI from './InputUI.vue';

function getInput() {
  return new Promise(resolve => {
    const InputUIVue = Vue.extend(InputUI);
    const inputUI = new InputUIVue();

    inputUI.$once('submit', value => {
      inputUI.$destroy();
      inputUI.$el.remove();
      resolve(value);
    });

    inputUI.$mount();
    document.body.appendChild(inputUI.$el);
  });
}

getInput().then(value => alert(value));

推荐阅读