使用 Promise 渲染一个 Vue 应用程序,并等待用户输入
Posted
技术标签:
【中文标题】使用 Promise 渲染一个 Vue 应用程序,并等待用户输入【英文标题】:Render a Vue app using a promise, and await user input 【发布时间】:2018-10-22 16:36:51 【问题描述】:我有一个设计问题,我目前有一个逻辑繁重的 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
,然后再对逻辑繁重的脚本进行函数调用 - 但这感觉不那么干净。
有什么想法吗?
提前致谢。
【问题讨论】:
为什么要将数据传回 promise 链,除非loadVueApp
仅在做出选择并销毁 Vue 组件后才解析? (是这样吗?否则你为什么要像这样串联承诺?)
是的,这就是我想做的——在用户做出选择并关闭应用程序之前保持承诺未解决。
【参考方案1】:
这是一个简单的示例,它执行以下操作:
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>
如果您使用单个文件组件,您的代码结构应该类似于:
InputUI.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));
【讨论】:
感谢这个解决方案,它看起来不错 - 但这需要手动编译或使用渲染功能。我正在使用单个文件组件。 我没有使用渲染函数,我的示例中没有任何内容不能转换为单个文件组件。 来自文档:However, if you are relying on mounting to an element with existing content as template (using the el option), you will still be subject to those limitations.
我想尽可能避免添加编译器,还是我遗漏了什么?
我的答案以这种方式编写的唯一原因是让它可以在线运行。要使其成为单个文件组件,您所要做的就是将<template>
和组件定义代码照常放入.vue 文件中(并删除template: '#input-ui'
)。其他一切都保持不变。
嗯,对不起@Decade Moon,不确定我做错了什么:- Component template requires a root element, rather than just text.
但如果我删除对template
的引用,那么对new Vue()
的调用将如何知道从哪里得到html 来自?以上是关于使用 Promise 渲染一个 Vue 应用程序,并等待用户输入的主要内容,如果未能解决你的问题,请参考以下文章
React 帮助:在映射数组中使用 Promise 进行条件渲染 [关闭]
vue开发的网页打包后在IE浏览器下显示promise未定义怎么解决?